c60c-4au@web-4f.berkeley.edu (10/16/88)
A while ago, someone posted a message asking about a way to deprotect
BASIC programs which were saved with the ",p" option. (Actually, he
probably did not know that they were saved this way, but by his description
of being able to RUN a program, but not LIST it, I assume this is his
problem). I tried E-Mailing him, but I can't seem to reach him, so I decided
to post this message, since it is short.
This program, UNPRO, is a short memory-resident program which will
unprotect BASIC programs. To run the program, just run UNPRO from the
DOS prompt, and it will be installed. Now, load BASIC (I have only
tried it with GW-BASIC, but it should run with BASICA too), and load the
protected program. Now, enter a control-D. You should hear a beep. Now,
LIST the program and the program will be there. It may now be saved
normally.
The UUencoded program follows (since it is only 128 bytes long, I figured
I would put it here):
section 1 of uuencode 2.13 of file unpro.com by R.E.M.
begin 644 unpro.com
MZSV`_`!U+E.<#KL0`5/K)3T$('4>45:^``.Y``B[``/\K#S^=0?&1/\`NP<B9
MXO)>68O#6\\N_RXZ`0``````'C/`CMB^6`#$//K'!`(!C$P"'XD^.@&,!CP!,
F^[H_`<TG&@``````````````````````````````````````````]
``
end
size 128
--
Erik Talvola | "It's just what we need... a colossal negative
c60c-4au@web.berkeley.edu | space wedgie of great power coming right at us
| at warp speed." -- Star Drek
mattp@oakhill.UUCP (Matt Pressly) (03/15/89)
How can one go about making protected BASIC programs listable again? I thought I saw something in comp.sys.ibm.pc or comp...binaries about this several days ago, but I can't find it now. -- address: mattp@oakhill
mattp@oakhill.UUCP (Matt Pressly) (03/16/89)
Could the person who sent me the unprotect for GWBASIC programs using debug please re-email that to me. I inadvertently lost the mail. Thanks. -- address: mattp@oakhill
riley@ihuxv.ATT.COM (d. riley) (03/17/89)
Could the person (or anyone who may have such information) who sent Matt Pressly (mattp@oakhill) the unprotect for GWBASIC programs using degug either post that procedure here or at least email it to me (att!ihuxv!riley) also? Thanks in advance.
maa@nbires.nbi.com (Mark Armbrust) (03/17/89)
In article <3251@ihuxv.ATT.COM> riley@ihuxv.ATT.COM (d. riley) writes: >Could the person (or anyone who may have such information) who sent Matt >Pressly (mattp@oakhill) the unprotect for GWBASIC programs using degug either >post that procedure here or at least email it to me (att!ihuxv!riley) also? > > Thanks in advance. Think that was me, so... There is a feature (bug) of the GWBASIC interpreter that causes it to work a bit strangely when it reads a null program (as opposed to an empty file). This null program is the two-byte sequence FF, 1A. Create this file with the debugger and call it U.BAS: >debug -e 100 ff 1a -n u.bas -r cx CX 0000 :2 -w -q > Now start basic and load the protected program and then load U.BAS. The protected program should now be unprotected: LOAD "prot-prg LIST Illegal function call LOAD "u LIST 10 rem I used to be protected 20 rem but now I am not (As a side note, it you make a file containing FE 1A, it will act as a protector!) There is an algorithmic way to do this, and I have source to a .ASM program to do it. If there is enough interest, I'll post it. Enjoy, Mark maa@nbires.nbi.com maa@nbires.UUCP
wew@naucse.UUCP (Bill Wilson) (03/17/89)
I would like the information too, please. -- Bill Wilson (Bitnet: ucc2wew@nauvm) Northern AZ Univ Flagstaff, AZ 86011 {These views are mine and do not necessarily reflect those of my employer}
jz0t+@andrew.cmu.edu (James Zurlo) (03/18/89)
This ought to do the trick for you. 10000 'LISTING 2, BUFFUNPR.BAS 10050 ' 10100 'This program unprotects protected BASIC programs 10150 ' 10200 'Copyright, 1985 VERSION 1.30 10250 ' 10300 'By: Jim Pottkotter 10350 ' 3015 Kirby M'Liss Cove 10400 ' Memphis, TN 38115 10450 ' 10500 ' (901) 795-2238 10550 ' 10600 '=====> Initialize environment 10650 ' 10700 SCREEN 0,1,0,0 'Text mode 10750 WIDTH 80 '80 columns 10800 COLOR 10,0,0 'Bright green on black background 10850 CLS 'Clear the screen 10900 DEF SEG 'Set default segment 10950 ON ERROR GOTO 17750 'General error handling 11000 ' 11050 '=====> Initialize variables and constants 11100 ' 11150 PROTECTED.FILE$ = "" 'Drive and name of protected file 11200 PROTECTED% = 0 'Boolean - initially false 11250 THIS.PROGRAM$ = "BUFFUNPR.BAS" 'The name of this program 11300 UNPROTECT.FILE$ = "UNPRBYTE.IMG" 'File containing unprotected status 11350 FIRST.LINE$ = "" 'First line from protected file 11400 IK$ = "" 'INKEY$ value 11450 LOOP% = 0 'Loop counter 11500 MESG$ = "" 'Error message 11550 EXTENSION% = 0 'Boolean - true means user entered 11600 'an extension on input file name 11650 ' 11700 '=====> If this program is protected, save an unprotected version 11750 ' 11800 WHILE PEEK(1124) <> 0 11850 POKE 1124,0 11900 PRINT 11950 PRINT "Saving unprotected version of "; THIS.PROGRAM$;" "; 12000 PRINT "on default drive." 12050 SAVE THIS.PROGRAM$ 12100 WEND 12150 ' 12200 PROTECTED.FILE$ = "" 12250 WHILE PROTECTED.FILE$ = "" 12300 COLOR 10,0,0 12350 PRINT "BASIC files on current drive and path: "; 12400 COLOR 7,0,0 12450 FILES "*.BAS" 12500 COLOR 10,0,0 12550 PRINT "Enter drive and name of protected file." 12600 PRINT 12650 PRINT "Example: B:PROTECTD.BAS " 12700 PRINT 12750 PRINT "The default file extension is .BAS " 12800 PRINT 12850 PRINT "Enter END to end program." 12900 PRINT 12950 PRINT 13000 WHILE PROTECTED.FILE$ = "" 13050 LOCATE CSRLIN - 1, 1 13100 GOSUB 20550 'Get file name 13150 IF PROTECTED.FILE$ = "" THEN GOSUB 17350 'Buzz 13200 WHILE PROTECTED.FILE$ = "END" 13250 COLOR 15,0 13300 PRINT 13350 PRINT "Bye!" 13400 PRINT 13450 END 13500 WEND 13550 WEND 13600 EXTENSION% = 0 13650 FOR LOOP% = 1 TO LEN(PROTECTED.FILE$) 13700 IF MID$(PROTECTED.FILE$,LOOP%,1) = "." THEN EXTENSION% = -1 13750 NEXT 13800 IF NOT EXTENSION% THEN PROTECTED.FILE$ = PROTECTED.FILE$ + ".BAS" 13850 WEND 13900 ' 13950 PRINT 14000 PRINT "Opening "; PROTECTED.FILE$ 14050 PRINT 14100 OPEN "I", 1, PROTECTED.FILE$ 14150 INPUT #1, FIRST.LINE$ 14200 CLOSE #1 14250 PROTECTED% = (ASC(LEFT$(FIRST.LINE$,1)) = 254) 14300 WHILE NOT PROTECTED% 'If first byte = 254, then file 14350 'is a protected BASIC program 14400 GOSUB 17350 'Low warning buzz 14450 COLOR 15,0 'Bright white on black background 14500 PRINT PROTECTED.FILE$; " is not a protected BASIC program." 14550 GOSUB 16800 'Press any key 14600 WEND 14650 ' 14700 PRINT "Creating "; UNPROTECT.FILE$; " on default drive." 14750 BSAVE UNPROTECT.FILE$, 1124, 1 14800 ' 14850 ' 14900 ON ERROR GOTO 0 14950 CLS 'Clear the screen 15000 BUFF.1$ = STRING$(5,13) '5 carriage returns 15050 GOSUB 19150 'Load the keyboard buffer 15100 LOCATE 2,1 'Put cursor at row 2, col 1 15150 '----- The following print statements display statements that are 15200 '----- executable in direct mode. When the program ends, we will 15250 '----- be in direct mode, and the five carriage returns we save in 15300 '----- the keyboard buffer will execute the statements. 15350 '----- 15400 '----- The statements do the following: 15450 '----- 15500 '----- 1. LOAD the protected program 15550 '----- 15600 '----- 2. BLOAD a byte of data that identifies the currently 15650 '----- loaded program as unprotected. 15700 '----- 15750 '----- 3. KILL the file used in step 2. 15800 '----- 15850 '----- 4. SAVE the previously protected program in unprotected 15900 '----- format. 15950 '----- 16000 '----- 5. LIST the now unprotected program. 16050 '----- 16100 PRINT "LOAD"; CHR$(34); PROTECTED.FILE$ 16150 PRINT 16200 PRINT "BLOAD"; CHR$(34); UNPROTECT.FILE$ 16250 PRINT 16300 PRINT "KILL"; CHR$(34); UNPROTECT.FILE$ 16350 PRINT 16400 PRINT "SAVE"; CHR$(34); PROTECTED.FILE$ 16450 PRINT 16500 PRINT "CLS:LIST" 16550 LOCATE 1,1 'Put cursor at col 1, row 1 16600 END 'Cursor drops to col 1, row 2 after Ok prompt 16650 ' 16700 '=====> Wait for user to press a key 16750 ' 16800 PRINT 16850 PRINT "Press any key to start over." 16900 IK$ = "" 16950 WHILE IK$ = "" 17000 IK$ = INKEY$ 17050 WEND 17100 RUN 17150 RETURN 'You will never get here 17200 ' 17250 '=====> Low warning buzz 17300 ' 17350 FOR LOOP% = 1 TO 4 17400 SOUND 40, .5 17450 SOUND 200, .5 17500 NEXT 17550 RETURN 17600 ' 17650 '=====> Error handling 17700 ' 17750 COLOR 15,0 'Bright white on black 17800 MESG$ = "" 17850 IF ERR = 52 THEN MESG$ = "Invalid file specification. " 17900 IF ERR = 53 THEN MESG$ = "File not found. " 17950 IF ERR = 61 THEN MESG$ = "Disk full. " 18000 IF ERR = 62 THEN MESG$ = "File is empty. " 18050 IF ERR = 64 THEN MESG$ = "Bad file name. " 18100 IF ERR = 67 THEN MESG$ = "Too many files. " 18150 IF ERR = 70 THEN MESG$ = "Disk write protected. " 18200 IF ERR = 71 THEN MESG$ = "Disk not ready. " 18250 IF ERR = 72 THEN MESG$ = "Disk media error. " 18300 IF ERR = 75 THEN MESG$ = "Path/file access error. " 18350 IF ERR = 76 THEN MESG$ = "Path not found. " 18400 GOSUB 17350 'Low warning buzz 18450 IF MESG$ = "" THEN ON ERROR GOTO 0 'Unexpected error 18500 PRINT MESG$ 18550 PRINT 18600 PRINT "Please correct the problem." 18650 GOSUB 16800 'Press any key to continue 18700 'LISTING 2 18750 ' 18800 'BUFFLOAD.SUB clears and optionally loads the keyboard buffer 18850 ' 18900 '=====> Load Keyboard Buffer 18950 ' 19000 '---- If BUFF.1$ and BUFF.2$ both contain a string, 19050 '---- BUFF.1$ overrides BUFF.2$. 19100 ' 19150 POKE 1050, PEEK(1052) 'Clear the buffer 19200 DEF SEG = 0 'Set segment to 0 19250 WHILE BUFF.1$ <> "" 'Case 1 - normal codes 19300 POKE 1050, 30 'Address of 1st byte in buffer 19350 BUFF.LEN% = LEN(LEFT$(BUFF.1$,15)) 'Get truncated string size 19400 POKE 1052, 30 + 2 * BUFF.LEN% 'Addr of 1st byte after buffer 19450 FOR BUFF.LOOP% = 1 TO BUFF.LEN% 'Loop BUFF.LEN% times 19500 POKE 1052 + 2 * BUFF.LOOP%, ASC(MID$(BUFF.1$,BUFF.LOOP%,1)) 'ASCII 19550 NEXT 'End loop 19600 BUFF.2$ = "" 'Prevent case 2 19650 BUFF.1$ = "" 'Set exit condition 19700 WEND 'End case 1 19750 ' 19800 WHILE BUFF.2$ <> "" 'Case 2 - extended codes 19850 POKE 1050, 30 'Address of 1st byte in buffer 19900 BUFF.LEN% = LEN(LEFT$(BUFF.2$,30)) 'Limit is 30 characters 19950 BUFF.LEN% = (BUFF.LEN% \ 2) * 2 'Force even # of bytes 20000 POKE 1052, 30 + BUFF.LEN% 'Addr of 1st byte after buffer 20050 FOR BUFF.LOOP% = 1 TO BUFF.LEN% 'Loop BUFF.LEN% times 20100 POKE 1053 + BUFF.LOOP%, ASC(MID$(BUFF.2$,BUFF.LOOP%,1)) 'ASCII 20150 NEXT 'End loop 20200 BUFF.2$ = "" 'Set exit condition 20250 WEND 'End case 2 20300 ' 20350 RETURN 20400 ' 20450 '=====> Get protected file name and shift string to upper case 20500 ' 20550 INPUT "", PROTECTED.FILE$ 20600 FOR LOOP% = 1 TO LEN(PROTECTED.FILE$) 20650 A.LETTER$ = MID$(PROTECTED.FILE$,LOOP%,1) 20700 LOWERCASE% = 0 20750 IF A.LETTER$ >= "a" AND A.LETTER$ <= "z" THEN LOWERCASE% = -1 20800 IF LOWERCASE% THEN A.LETTER$ = CHR$(ASC(A.LETTER$) - 32) 20850 MID$(PROTECTED.FILE$,LOOP%,1) = A.LETTER$ 20900 NEXT 20950 RETURN