Classic Computer Magazine Archive COMPUTE! ISSUE 61 / JUNE 1985 / PAGE 88

Unlocking IBM BASIC Programs

Peter F. Nicholson

This short utility unlocks BASIC programs which have been saved in protected format with the P option. It works on any IBM PC or PCjr.

IBM BASIC lets you save a program in three formats: in tokenized (compressed binary) form, as an ASCII file, or as a protected (encoded binary) program. The commands for these options are:

SAVE "filename"   (tokenized)
SAVE "filename",A (ASCII)
SAVE "filename",P (protected)

In each case, DOS automatically appends the extender .BAS and does not indicate the format on disk directories. You can load a program saved in any format with LOAD "filename.BAS", omitting the .BAS extender if you wish.

Although a protected program loads and runs normally, it cannot be listed or edited, and neither BASIC nor DOS provides a way to "unlock" it. So when you save a program in protected format, you should also save an unprotected copy in case you decide to make some changes later. If you find yourself without a backup, however, the following utility can remove the protection.

Type in and save UNPROT. UTL. Note that you must save it with the filename UNPROT.UTL. When you run it, you'll be prompted to enter the active drive (enter A if you have one drive) and the name of the protected program. The drive runs briefly as the protection is removed, and then your program is listed on the screen, ready for you to edit or resave.

Invisible Fingers

To mimic the effect of entering direct keyboard commands, UNPROT. UTL assigns strings to the ten special function keys. It then manipulates the keyboard buffer to enter each string automatically, as if the function keys were being pressed in sequence by invisible fingers. If you use DOS 2.1, the subroutine at line 2000 automatically enters the function keystrokes for you. If you have another version of DOS, you'll have to delete the GOSUB 2000 statement from line 290 and press F1 through F10 in sequence yourself, after entering the filename.

Mimicking keystrokes is an efficient technique, but it makes a program somewhat difficult to follow. If you're interested in how this utility works, here's a brief explanation of how protected programs can be unlocked.

The Key Addresses

The first thing you need to learn is where the program starts and ends in memory. As explained in Appendix I of the IBM BASIC Manual, these addresses can be found with the following PEEKs:

PEEK(&H30)+256*PEEK(&H31)
	       Program starting address
PEEK(&H358)+256*PEEK(&H359) -1
	       Program ending address

The starting address is the same in every case; you can find it simply by entering NEW followed by the first PEEK statement above. Finding the ending address is more difficult, as you'll find if you load a protected program and enter the second statement. All you'll get for your trouble is an illegal function call error.

However, there's another way to get the same information. Scalar variables are stored immediately after the end of a BASIC program, and the VARPTR function can find the address of any variable. All you need to do is define an arbitrary scalar variable, CHAIN the protected program into memory, and use VARPTR to find the address of the dummy variable.

Breaking The Chains

Unlike the LOAD command, which clears variables, CHAIN brings a program into memory and begins execution at a specified line number without destroying preexisting variables. This is the method used in UNPROT.UTL. We don't want to run the chained program after it's in memory, so the CHAIN command uses a nonexistent line number (65529). This simply halts execution with an illegal function call error.

Subtracting a few bytes to account for the variable descriptor gives us the exact address where the program ends. To determine its length, we subtract the starting address from the ending address.

Now that we know the program's starting address and length, we BSAVE it back to disk as a binary file. After performing a second NEW, it's necessary to set the pointers for the start of scalar variables, arrays, and strings at the spot where the program ends. Finally, the program is BLOADed back into memory at the correct starting address, and the unlocking process is complete.

If you would rather not type in this program, send a formatted disk with a self-addressed, postage-paid mailer and a $3.00 check to:

Peter F. Nicholson
1701 South Princeton Road
Ottawa, Kansas 66067

UNPROT.UTL

Please refer to "COMPUTE!'s Guide to Typing In Programs" before entering this listing.

ID 80 REM 'UNLOCK' PROGRAMS SAVED IN PROTECTED FORMAT.
MA 90 REM LOADS A PREVIOUSLY PROTECTED PROGRAM INTO MEMORY
MB 95 REM WITHOUT PROTECTION, SO PROGRAM CAN BE LISTED AND SAVED.
KD 96 REM IBM BASIC VERSIONS 1.1 AND 2.0
JL 100 DEF SEG:CLEAR:KEY OFF:CLS :ON ERROR GOTO 300
HJ 110 B% = 0 : A = 0
NM 120 GOSUB 1000
KD 130 A=PEEK(&H30)+256*PEEK(&H3 1)
IL 140 LINE INPUT "PROTECTED FILE DRIVE ";G$:
          IF LEN(G$)>0 THEN IF INSTR(G$,":")=0 THEN G$=G$+":"
HO 150 LINE INPUT "PROTECTED FILE NAME ";F$:IF INSTR(F$," .")=0 THEN F$=F$+".BAS"
HP 160 G$=G$+F$
DI 170 F$="PROT.SCR"
HG 180 H$=ldquo;PROT.DAT":I$="UNPROT. UTL"
HK 190 KEY 1,"B=VARPTR(B)"+CHR$( 13)
IF 200 KEY 2,"BSAVE F$,A,B-A"
QL 210 KEY 3,"-4:BSAVE H$,B,"
ML 220 KEY 4,"4s CHAIN I$,500"+CHR$(13)
ON 230 KEY 5,"BLOAD"+CHR$(34)
HE 240 KEY 6,H$+CHR$(34)+",856"+ CHR$(13)
EI 250 KEY 7,"BLOAD"+CHR$(34)+F$
IH 260 KEY 8,CHR$(34)+","+STR$(A)+CHR$(13)+"LIST"+CHR$(13 )
AC 270 KEY 9,"FOR I=1 TO 10:KE"
HN 280 KEY 10,"Y I,"+CHR$(34)+CH R$(34)+"NEXT"+CHR$(13)
LJ 290 GOSUB 2000:COLOR 0,0:CHAI N G$,65529!,ALL
EE 300 FOR I=1 TO 10:KEY I,"":NEXT I
DH 310 COLOR 7,0:IF ERL=290 AND ERR=53 THEN CLS:BEEP:PRINT G$+" DOES NOT EXIST":RESUME 140
NE 320 ON ERROR GOTO 0:END
GB 500 B=0:DIM B1%(2):COLOR 7,0
DD 510 BLOAD "PROT.DAT",VARPTR(B)
DB 520 FOR I=0 TO 2:IF B<2^15 TH EN B1%(I)=B ELSE B1%(I)=B -2^16
MC 530 NEXT I:B SAVE "PROT.DAT",V ARPTR(B1%(0)),6
DC 540 NEW
HH 1000 PRINT "UNPROTECTING BASIC PROGRAMS"
OJ 1010 LOCATE 4,10:PRINT "1. YOU WILL BE PROMPTED FOR THE FILE DRIVE AND NAME"
PC 1040 LOCATE 7,10:PRINT "2. THE FINAL STEP IS THE LISTING OF YOUR PROGRAM"
GF 1050 LOCATE 16,1:PRINT "NOTE: FUNCTION KEYS ARE CLEARED BY THE PROGRAM AND TWO SCRATCH"
KM 1060 LOCATE 18,1:PRINT "FILES, PROT.SCR AND PROT.DAT ARE LEFT ON YOUR DEFAULT DRIVE"
DH 1070 LOCATE 25,1:PRINT "PRESS ANY KEY TO START";
CB 1080 KB$=INKEY$:IF KB$="" GOTO 1090: 'CLEAR KEYBOARD
EN 1090 KB$=INKEY$:IF KB$="" GOTO 1090
EF 1100 CLS:RETURN
GF 2000 REM ** SET KEYBOARD BUFFER TO ENTER F1 THROUGH F10 AUTOMATICALLY***
DM 2010 REM **             IBM PC DOS VERSION 2.1 ***
JG 2020 DEF SEG=&H40:FOR I=1 TO 10:POKE 2*I+2B,0:POKE 2*I+29,5B+I;NEXT I
CO 2030 POKE 2*I+28,13:POKE 2*I+29,28:POKE 26,30:POKE 28,50:DEF SEG:RETURN