diff options
author | B. Watson <urchlay@slackware.uk> | 2024-05-17 05:09:45 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2024-05-17 05:09:45 -0400 |
commit | 96af9bc891987f6fcc560a6e403c5ada541d8699 (patch) | |
tree | 6bdd20a1fdd7f31316d14fb5e233718b48713522 /unprotbas.1 | |
parent | d4064b55a7ddbb002ef80dbc0db60cd0d95cb1cd (diff) | |
download | bw-atari8-tools-96af9bc891987f6fcc560a6e403c5ada541d8699.tar.gz |
unprotbas: added; blob2xex: tweak docs.
Diffstat (limited to 'unprotbas.1')
-rw-r--r-- | unprotbas.1 | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/unprotbas.1 b/unprotbas.1 new file mode 100644 index 0000000..92e6b66 --- /dev/null +++ b/unprotbas.1 @@ -0,0 +1,213 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "UNPROTBAS" 1 "2024-05-17" "0.2.1" "Urchlay's Atari 8-bit Tools" +.SH NAME +unprotbas \- Unprotect LIST-protected Atari 8-bit BASIC programs +.SH SYNOPSIS +.sp +unprotbas [\fB\-v\fP] [\fB\-f\fP] [\fB\-n\fP] [\fB\-g\fP] \fBinput\-file\fP \fBoutput\-file\fP +.SH DESCRIPTION +.sp +\fBunprotbas\fP modifies LIST\-protected Atari 8\-bit BASIC programs, +creating a new non\-protected copy. See \fBDETAILS\fP, below, to +understand how the protection and unprotection works. +.sp +\fBinput\-file\fP must be a tokenized Atari BASIC program. Use \fI\-\fP to +read from standard input. +.sp +\fBoutput\-file\fP will be the unprotected tokenized BASIC program. If it +already exists, it will be overwritten. Use \fI\-\fP to write to standard +output, but \fB[TODO]\fP \fBunprotbas\fP will refuse to write to standard +output if it\(aqs a terminal (since tokenized BASIC is binary data and +may confuse the terminal). +.SH OPTIONS +.INDENT 0.0 +.TP +.B \fB\-v\fP +Verbose operation. +.TP +.B \fB\-f\fP +Force the variable name table to be rebuilt, even if it looks OK. +.TP +.B \fB\-n\fP +Don\(aqt rebuild the variable table (only fix the line pointers, if +needed). +.TP +.B \fB\-g\fP +Remove any "garbage" data from the end of the file. By default, +it\(aqs left as\-is, in case it\(aqs actually data used by the program. +.UNINDENT +.SH EXIT STATUS +.sp +Exit status is zero for success, non\-zero for failure. +.SH DETAILS +.sp +In the Atari BASIC world, it\(aqs possible to create a SAVEd (tokenized) +program that can be RUN from disk (\fBRUN "D:FILE.BAS"\fP) but if +it\(aqs LOADed, it will either crash the BASIC interpreter, or LIST +as gibberish. This is known as LIST\-protection. Such programs are +generally released to the world in protected form; the author +privately keeps an unprotected copy so he can modify it. In +later days, collections such as the Holmes Archive contain many +LIST\-protected programs, for which the unprotected version was never +released. +.sp +One example of LIST\-protection, taken from \fIMapping the Atari\fP (the +\fBSTMCUR\fP entry in the memory map) looks like: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +32000 FOR VARI=PEEK(130)+PEEK(131)*256 TO PEEK(132)+PEEK(133)*256:POKE VARI,155:NEXT VARI +32100 POKE PEEK(138)+PEEK(139)*256+2,0:SAVE "D:filename":NEW +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +To use, add the 2 lines of code to your program, then execute them +with \fBGOTO 32000\fP in immediate mode. +.sp +This illustrates both types of protection, which can be (and usually +are) applied to the same program: +.INDENT 0.0 +.TP +.B Variable name table scrambling +BASIC has specific rules on what are and aren\(aqt considered legal +variable names, which are enforced by the tokenization process, +at program entry time. However, it doesn\(aqt use the variable names +at runtime, when the tokenized file is interpreted. +.sp +Replacing the variable names with binary gibberish will render the +program LIST\-proof, either replacing every variable name with the +same control character, or causing LIST to display a long string of +binary garbage for each variable name... but the program will still +RUN correctly. Note that the original variable names are \fIgone\fP, +and cannot be recovered. +.sp +Line 32000 in the example above does this job, replacing every +variable name with the EOL character (155). +.sp +\fBunprotbas\fP detects a scrambled variable name table, and builds +a new one that\(aqs valid. However, since there are no real variable +names in the program, the recovery process just invents new ones, +named A through Z, A1 through A9, B1 through B9, etc, etc. It\(aqll +require human intelligence to figure out what each variable is for, +since the names are meaningless. +.sp +The \fBoutput\-file\fP may be larger than the \fBinput\-file\fP was, since +some types of variable\-name scrambling shrink the variable name +table to the minimum size (one byte per name); the rebuilt table +will be larger. +.TP +.B Bad next\-line pointer +Generally, this is done with line number 32768. Yes, this line +number is outside the range BASIC accepts... but BASIC uses it +internally for immediate\-mode commands. And when SAVE or CSAVE are +executed, this line gets saved, too. +.sp +Every line of tokenized BASIC contains a line length byte, which +BASIC uses as a pointer to the next line of code. Before printing +the READY prompt, BASIC iterates over every line of code in the +program, using the next\-line pointers, in order to delete any +existing line 32768 (the previous immediate mode command). If any +line\(aqs pointer is set to zero, that means it points to itself. +.sp +When BASIC tries to traverse a line of code that points to itself as +"next" line, it will get stuck in an infinite loop. This not only +prevents LIST, it actually prevents any immediate mode command: +after LOADing such a file, \fInothing\fP will work (even pressing RESET +won\(aqt get you out of it). The only way to use such a program is to +use the RUN command with a filename, and if the program ever exits +(due to END, STOP, an error, or the Break key), BASIC will get stuck +again. +.sp +This doesn\(aqt \fIhave\fP to be done with line 32768. Any line of code +that doesn\(aqt have to be traversed at runtime would work (in other +words, a regular line whose line number is higher than any code that +ever gets executed, usually the last line in the file). +.sp +Line 32100 in the example above does this job, taking advantage of +the STMCUR pointer used by BASIC, which holds the address of the +line of tokenized code currently being executed. +.sp +\fBunprotbas\fP fixes this simply by calculating what the pointer +should be (based on the tokens in the line) and changing it. No +information is lost by doing this. +.UNINDENT +.sp +One more thing \fBunprotbas\fP can do is remove extra data from the end +of the file. It\(aqs possible for BASIC files to contain extra data that +occurs after the end of the program. Some programs use this as a way +to load arbitrary binary data into memory along with the program; for +other programs, the extra data is truly garbage (e.g. an EOF character +if the file came from a CP/M system, or padding to a block size if a +dumb implementation of XMODEM was used to transfer the file). +.sp +Normally, such "garbage" doesn\(aqt hurt anything. BASIC ignores it. Or +it normally does... if you suspect it\(aqs causing a problem, you can +remove it with the \fB\-g\fP option. If removing the "garbage" causes the +program to fail to run, it wasn\(aqt garbage! \fBunprotbas\fP doesn\(aqt +remove extra data by default, to be on the safe side. +.SH COPYRIGHT +.sp +WTFPL. See \fI\%http://www.wtfpl.net/txt/copying/\fP for details. +.SH AUTHOR +.INDENT 0.0 +.IP B. 3 +Watson <\fI\%urchlay@slackware.uk\fP>; Urchlay on irc.libera.chat \fI##atari\fP\&. +.UNINDENT +.SH SEE ALSO +.sp +\fBa8eol\fP(1), +\fBa8utf8\fP(1), +\fBatr2xfd\fP(1), +\fBatrsize\fP(1), +\fBaxe\fP(1), +\fBblob2c\fP(1), +\fBblob2xex\fP(1), +\fBcart2xex\fP(1), +\fBdasm2atasm\fP(1), +\fBf2toxex\fP(1), +\fBfenders\fP(1), +\fBrom2cart\fP(1), +\fBunmac65\fP(1), +\fBxexamine\fP(1), +\fBxexcat\fP(1), +\fBxexsplit\fP(1), +\fBxfd2atr\fP(1), +\fBxex\fP(5), +\fBatascii\fP(7). +.sp +Any good Atari 8\-bit book: \fIDe Re Atari\fP, \fIThe Atari BASIC Reference +Manual\fP, the \fIOS Users\(aq Guide\fP, \fIMapping the Atari\fP, etc. +.\" Generated by docutils manpage writer. +. |