diff options
| -rw-r--r-- | unprotbas.1 | 6 | ||||
| -rw-r--r-- | unprotbas.c | 40 | ||||
| -rw-r--r-- | 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  | 
