-----------Alge-Blaster Plus----------- A 4am crack 2014-11-17 --------------------------------------- "Alge-Blaster Plus" is a 1989 educational program designed by Julie Baumgartner and Anne Hertz, programmed by David Ely and Louis X. Savain, and distributed by Davidson and Associates. It is distributed on two double-sided disks, labeled "Program Disk" and "Data Disk". COPYA can read the Program Disk side 2, and both sides of the Data Disk, but it fails on the very last pass of side 1 of the Program Disk (which, perhaps not coincidentally, is the only bootable side). Locksmith Fast Disk Backup shows the problem: it reads tracks $00-$21, then sectors $00-$0E of track $22. But the last sector of the last track is unreadable. Needless to say, the copy that Locksmith FDB creates does not work. It boots to ProDOS, then it immediately quits via the ProDOS quit handler. It's a very ProDOS-y way of saying f--- you. Booting into BASIC.SYSTEM from my ProDOS hard drive, I can see a catalog and start investigating. [S6,D1=Program Disk side 1] ]CAT,S6,D1 /ABP1.0 NAME TYPE BLOCKS MODIFIED PRODOS SYS 32 13-JUN-88 ABP.SYSTEM SYS 4 7-APR-88 MFORTH BIN 60 20-NOV-89 TK.ABS BIN 28 4-APR-89 NEW.FONT BIN 7 16-OCT-89 ATXT.DAT BIN 9 17-NOV-89 ETXT.DAT BIN 5 17-NOV-89 MENU.DAT BIN 3 19-OCT-89 EDMENU.DAT BIN 1 29-SEP-89 SETUP.DAT BIN 1 17-NOV-89 ED.IMG BIN 10 30-AUG-89 ED.OBJ BIN 8 6-OCT-89 TOOLS.OBJ BIN 1 16-OCT-89 BLOCKS FREE: 43 BLOCKS USED: 237 ]PREFIX /ABP1.0 ProDOS always loads the first .SYSTEM file at $2000 and jumps to it. ]BLOAD ABP.SYSTEM,A$2000,TSYS ]CALL -151 *2000L 2000- 20 D2 25 JSR $25D2 2003- 4C 74 08 JMP $0874 There's nothing loaded at $0874 yet, so the subroutine at $25D2 must load something from disk or copy something from memory. *25D2L ; straightforward memory relocation 25D2- A2 00 LDX #$00 25D4- BD 03 20 LDA $2003,X 25D7- 9D 01 08 STA $0801,X 25DA- BD 03 21 LDA $2103,X 25DD- 9D 01 09 STA $0901,X 25E0- BD 03 22 LDA $2203,X 25E3- 9D 01 0A STA $0A01,X 25E6- BD 03 23 LDA $2303,X 25E9- 9D 01 0B STA $0B01,X 25EC- BD 03 24 LDA $2403,X 25EF- 9D 01 0C STA $0C01,X 25F2- BD 03 25 LDA $2503,X 25F5- E8 INX 25F6- D0 DC BNE $25D4 25F8- 60 RTS That's harmless enough. Let's run it. *25D2G *874L 0874- 20 C8 0A JSR $0AC8 0877- F0 D9 BEQ $0852 Down the rabbit hole we go. *AC8L ; $BF30 is the last used slot and drive ; in "DSSS0000" format ("Beneath Apple ; ProDOS", p. 8-6) 0AC8- AD 30 BF LDA $BF30 0ACB- 4A LSR 0ACC- 4A LSR 0ACD- 4A LSR 0ACE- 4A LSR 0ACF- 29 07 AND #$07 0AD1- 09 C0 ORA #$C0 ; slot number munged into the high byte ; of the drive slot ROM, e.g. $C6 0AD3- 85 61 STA $61 0AD5- A9 00 LDA #$00 0AD7- 85 60 STA $60 ; standard fingerprinting to identify ; the drive ROM 0AD9- A0 01 LDY #$01 0ADB- B1 60 LDA ($60),Y 0ADD- C9 20 CMP #$20 0ADF- D0 22 BNE $0B03 0AE1- A0 03 LDY #$03 0AE3- B1 60 LDA ($60),Y 0AE5- D0 1C BNE $0B03 0AE7- A0 05 LDY #$05 0AE9- B1 60 LDA ($60),Y 0AEB- C9 03 CMP #$03 0AED- D0 14 BNE $0B03 0AEF- A0 FF LDY #$FF 0AF1- B1 60 LDA ($60),Y 0AF3- D0 0E BNE $0B03 ; 5.25-inch floppy drive, so check ; block $110 (includes T22,S0F) 0AF5- A9 10 LDA #$10 0AF7- 8D CE 0D STA $0DCE 0AFA- A9 01 LDA #$01 0AFC- 8D CF 0D STA $0DCF 0AFF- D0 0C BNE $0B0D 0B01- F0 0A BEQ $0B0D ; 3.5-inch floppy drive, so check ; block $308 0B03- A9 08 LDA #$08 0B05- 8D CE 0D STA $0DCE 0B08- A9 03 LDA #$03 0B0A- 8D CF 0D STA $0DCF ; set up other MLI parameters 0B0D- AD 30 BF LDA $BF30 0B10- 8D CB 0D STA $0DCB 0B13- A9 03 LDA #$03 0B15- 8D CA 0D STA $0DCA 0B18- A9 CA LDA #$CA 0B1A- 8D CC 0D STA $0DCC 0B1D- A9 0B LDA #$0B 0B1F- 8D CD 0D STA $0DCD ; call MLI to read the specified block ; from disk (the $80 byte following the ; JSR is the READ_BLOCK command, and ; following that is the address of the ; MLI parameter table, $0DCA) 0B22- 20 00 BF JSR $BF00 0B25- [80 CA 0D] ; if there was NOT a disk read error, ; then branch 0B28- 90 09 BCC $0B33 ; if there was any error other than an ; I/O error ($27), then branch 0B2A- C9 27 CMP #$27 0B2C- D0 05 BNE $0B33 ; success path is here 0B2E- A9 FF LDA #$FF 0B30- 85 FF STA $FF 0B32- 60 RTS ; failure path is here 0B33- A9 00 LDA #$00 0B35- 85 FF STA $FF 0B37- 60 RTS This isn't a nibble check, per se. But it is definitely a form of copy protection. (Fun fact: it appears to be written so it can be re-used for 5.25- and 3.5-inch floppies.) It relies on one specific sector being unreadable, and fails if it's actually readable. Since Locksmith FDB just wrote a zeroed (but standard) sector to T22,S0F, the MLI read routine unexpectedly succeeds, and the program knows it's been copied. Returning to the caller: 0874- 20 C8 0A JSR $0AC8 0877- F0 D9 BEQ $0852 *852L ; read and write main memory 0852- 8E 04 C0 STX $C004 0855- 8E 02 C0 STX $C002 ; call the quit handler (command $65) 0858- 20 00 BF JSR $BF00 085B- [65 5E 08] ...which explains the behavior I saw on my non-working copy. Let's reproduce the success path. I'm not sure if the side effect of setting zero page $FF is relevant, but let's assume it is. *FF:FF N 879G The program loads without complaint. Turning to my trusty Disk Fixer sector editor, I search for "20 C8 0A" (the call to the copy protection routine) and change it to call the success path at $0B2E instead. T04,S01,$77 change "C8 0A" to "2E 0B" Quod erat liberandum. --------------------------------------- A 4am crack No. 165 ------------------EOF------------------