From bcb4f66286476d6697c1f363a41eb167c958b40a Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 28 May 2024 15:38:08 -0400 Subject: unprotbas: -p/-pc now actually inserts a new line of code with the bad offset. --- unprotbas.1 | 6 +++--- unprotbas.c | 40 +++++++++++++++++++++++++++++++--------- unprotbas.rst | 6 +++--- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/unprotbas.1 b/unprotbas.1 index 1e1b919..b8123f1 100644 --- a/unprotbas.1 +++ b/unprotbas.1 @@ -228,9 +228,9 @@ The program \fBUNPROTEC\fP, from the \fIPirate\(aqs Treasure Chest\fP, can fix bad pointers in protected programs, though it doesn\(aqt do anything about variable name scrambling. .sp -\fBunprotbas \-pc\fP also does this type of protection. Beware: the -last line of code must never actually be executed by the program, -or BASIC will freeze when it tries to execute it. +\fBunprotbas \-pc\fP also does this type of protection. It works by +adding a line 32767 to the program, with a bad next\-line pointer. +This will fail if there\(aqs already a line 32767. .UNINDENT .sp One more thing \fBunprotbas\fP can do is remove extra data from the end diff --git a/unprotbas.c b/unprotbas.c index efc1b2f..6edb38f 100644 --- a/unprotbas.c +++ b/unprotbas.c @@ -40,6 +40,15 @@ /* entire file gets read into memory (for now) */ unsigned char data[BUFSIZE]; +/* for the -p/-pc options: 32767 END */ +unsigned char badcode[] = { + 0xff, 0x7f, /* line number 32767 */ + 0x00, /* *bad* next-line offset */ + 0x06, /* next-statement offset */ + 0x15, /* END token */ + 0x16, /* end-of-line token */ +}; + /* for the -r option */ #define MAP_FILE "varnames.txt" unsigned char varnames[BUFSIZE]; @@ -200,7 +209,7 @@ int fixcode(void) { offset = data[pos + 2]; /* fprintf(stderr, "pos %d, line #%d, offset %d\n", pos, lineno, offset); */ if(offset < 6) { - if(verbose) fprintf(stderr, "Found invalid offset %d (<6) at line %d, file offset %04x\n", offset, lineno, pos + 2); + if(verbose) fprintf(stderr, "Found invalid offset %d (<6) at line %d, file offset %04x\n", offset, lineno, pos); offset += fixline(pos); result++; } @@ -222,7 +231,7 @@ int fixcode(void) { return result; } -/* iterate over all the lines, zero out the offset of the last one +/* iterate over all the lines, insert a poisoned line 32767 just before line 32768 */ void breakcode(void) { int pos = codestart, oldpos = 0; @@ -244,13 +253,26 @@ void breakcode(void) { } } - if(!oldpos) { - die("can't protect code because there are no lines of code"); - } else { - data[oldpos + 2] = 0; - if(verbose) - fprintf(stderr, "set invalid line length 0 at line %d, file offset %04x\n", lineno, oldpos + 2); - } + if(!oldpos) die("can't protect code because there are no lines of code"); + if(lineno == 32767) die("can't protect code because there is already a line 32767"); + + /* pos is now the start of line 32768, move it up to make room for + the new line */ + offset = sizeof(badcode); + memmove(data + pos + offset, data + pos, filelen); + + /* insert new line */ + memmove(data + pos, badcode, offset); + + if(verbose) + fprintf(stderr, "Inserted line 32767 with invalid offset at file offset %04x\n", pos); + + /* update pointers that would be affected by the code move */ + stmcur += offset; + starp += offset; + set_header_vars(); + read_header(); + filelen += offset; } /* sometimes the variable name table isn't large enough to hold diff --git a/unprotbas.rst b/unprotbas.rst index cf7ca84..1df865f 100644 --- a/unprotbas.rst +++ b/unprotbas.rst @@ -202,9 +202,9 @@ Bad next-line pointer fix bad pointers in protected programs, though it doesn't do anything about variable name scrambling. - **unprotbas -pc** also does this type of protection. Beware: the - last line of code must never actually be executed by the program, - or BASIC will freeze when it tries to execute it. + **unprotbas -pc** also does this type of protection. It works by + adding a line 32767 to the program, with a bad next-line pointer. + This will fail if there's already a line 32767. One more thing **unprotbas** can do is remove extra data from the end of the file. It's possible for BASIC files to contain extra data that -- cgit v1.2.3