----------Math Blaster Mystery--------- A 4am crack 2015-09-19 --------------------------------------- Name: Math Blaster Mystery Version: 1.3 Genre: educational Year: 1989 Authors: Larene Wade Spitler, Julie Baumgartner, Anne Hertz, J.M. Albanese Publisher: Davidson & Associates, Inc. Media: double-sided 5.25-inch floppy OS: ProDOS 1.4 Identical cracks: #200 Math Blaster Mystery 1.0 #166 Word Attack Plus French #165 Alge-Blaster Plus I am missing the data disk. In previous versions, the data disk was unprotected and easily copyable, so if you find it, please upload it to the usual places. Only side A is bootable, so I'll start there. ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA disk read error on last pass Locksmith Fast Disk Backup read error on T22,S00; copy boots ProDOS then quits to program selector EDD 4 bit copy (no sync, no count) works Copy ][+ nibble editor it appears that the mystery sector on track $22 is simply missing (the track is shorter than usual) Disk Fixer no way to read T22,S00 Why didn't any of my copies work? Probably a nibble check in the first SYSTEM file that reads the unreadable sector on track $22 ~ Chapter 1 Success Is Failure, Failure Is Success, Black Is White, Night Is Day, Teaching Is Dead [S6,D1=original disk, side A] [S7,D1=ProDOS hard drive] ]PR#7 ... ]CAT,S6,D1 /MBM NAME TYPE BLOCKS MODIFIED PRODOS SYS 32 17-APR-87 AFORTH BIN 50 14-AUG-89 PS.SYSTEM SYS 4 7-APR-88 SETUP.DAT TXT 1 11-AUG-89 IN.DRIVERS TXT 5 4-AUG-87 GEN.OBJ TXT 9 14-AUG-89 FILEREQ.OVL TXT 11 14-AUG-89 CALC.OVL TXT 8 14-AUG-89 TK.ABS BIN 28 4-OCT-88 INIT.OVL TXT 4 14-AUG-89 TEXT.STR TXT 4 14-AUG-89 PR.DRIVERS TXT 12 18-MAY-87 NEW.FONT BIN 7 21-APR-89 GADG.DAT TXT 5 17-AUG-89 BLOCKS FREE: 85 BLOCKS USED: 195 ProDOS always loads the first .SYSTEM file at $2000 and jumps to it. ]BLOAD PS.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,S00) 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 is definitely a form of copy protection. It relies on a specific sector being unreadable, and fails if it's actually readable. Fun fact(*): it is written so it can be re-used for 5.25- and 3.5-inch floppies. Since Locksmith FDB just wrote a zeroed (but standard) sector to T22,S00, the MLI read routine unexpectedly succeeds, and the program knows it's been copied. (*) not guaranteed, actual fun may vary Continuing from $0874... 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. [S6,D1=non-working copy] *FF:FF N 879G The program loads without complaint. Out of curiosity, I reproduced this state and tried it with $FF=0. *FF:00 N 879G It still loads without complaint. The only thing that really matters is the value of the accumulator on the way out of the routine. Backtracking all the way back to $2003, I can change "JMP $0874" to "JMP $0879" and bypass the entire thing. T0A,S01,$04 change "74" to "79" Side B is unprotected. Quod erat liberandum. --------------------------------------- A 4am crack No. 457 ------------------EOF------------------