--------------Mask Parade-------------- A 4am crack 2015-05-04 --------------------------------------- Name: Mask Parade Genre: educational Year: 1984 Publisher: Springboard Software Media: double-sided 5.25-inch floppy OS: DOS 3.3 Other versions: none (preserved here for the first time) Similar cracks: - The Time Tunnel (crack no. 162) - Hey Diddle Diddle! (crack no. 203) - Gene Machine (crack no. 297) ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA immediate disk read error Locksmith Fast Disk Backup unable to read any track EDD 4 bit copy (no sync, no count) no errors, but copy hangs on boot Copy ][+ nibble editor all tracks use standard prologues (address: D5 AA 96, data: D5 AA AD) but modified epilogues (address: FF FF FF, data: FF FF FF) Disk Fixer ["O" -> "Input/Output Control"] set Address Epilogue to "FF FF FF" set Data Epilogue to "FF FF FF" Success! All tracks readable! T00 -> looks like a DOS 3.3 RWTS T11 -> DOS 3.3 disk catalog T01,S09 -> startup program is "HELLO" Why didn't COPYA work? modified epilogue bytes (every track) Why didn't Locksmith FDB work? modified epilogue bytes (every track) Why didn't my EDD copy work? probably a nibble check during boot Next steps: 1. AUTOTRACE to capture RWTS 2. Advanced Demuffin to convert disk to standard format 3. Patch the RWTS (if necessary) 4. Find nibble check and bypass it ~ Chapter 1 In Which We Attempt To Use The Original Disk As A Weapon Against Itself [S6,D1=original disk] [S6,D2=blank disk] [S5,D1=my work disk] ]PR#5 CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 /!\ BOOT0 JUMPS TO ($BBFE) CAPTURING BOOT1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS ]BRUN ADVANCED DEMUFFIN 1.5 ["5" to switch to slot 5] ["R" to load a new RWTS module] --> At $B8, load "RWTS" from drive 1 ["6" to switch to slot 6] ["C" to convert disk] --v-- ADVANCED DEMUFFIN 1.5 (C) 1983, 2014 ORIGINAL BY THE STACK UPDATES BY 4AM =======PRESS ANY KEY TO CONTINUE======= TRK:R.................................. +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:................................... SC1:................................... SC2:................................... SC3:................................... SC4:................................... SC5:................................... SC6:................................... SC7:................................... SC8:................................... SC9:................................... SCA:R.................................. SCB:................................... SCC:................................... SCD:................................... SCE:................................... SCF:................................... ======================================= 16SC $00,$00-$22,$0F BY1.0 S6,D1->S6,D2 --^-- Hmm. Even the disk's own RWTS can't read T00,S0A. I'm hoping that part of the copy protection and not a bad disk. ]PR#5 ]CATALOG,S6,D2 C1983 DSR^C#254 378 FREE A 002 HELLO B 025 B.FILES B 031 B.MASK B 004 B.ON B 010 GRAFIX.OBJ B 009 GRAFIX.INFO B 002 CHECK SIDE 2 B 002 MOVE A 004 MENU A 004 SET TO DISK A 025 MASK SET ]RUN HELLO ...gets as far as the main menu, then crashes after reading side B... Hmm. [S5,D1=DOS 3.3 master disk] ]PR#5 ... ]RUN HELLO,S6,D2 ...works... OK, it's probably doing some direct RWTS calls, which are in a different memory location on my work disk because it relocates DOS to the language card on startup. Nothing to worry about. If the program runs properly after booting from an unmodified DOS 3.3 disk, that rules out a whole set of possible post-boot protections. (c.f. Math Blaster, crack no. 121) [S6,D1=demuffin'd copy] ]PR#6 ...still hangs on boot... Let's go find that nibble check. ~ Chapter 2 In Which We Go Looking For That Nibble Check And Run Into An Old Friend ]PR#5 ... ]BLOAD BOOT0,A$800 ]CALL -151 *801L . . all normal, until... . 084A- 6C FE BB JMP ($BBFE) *BLOAD BOOT1,A$2600 *FE89G FE93G ; disconnect DOS *B600<2600.2FFFM ; move RWTS into place *BBFE.BBFF BBFE- 00 BB *BB00L ; Ah, I recognize this routine already. ; It was used by several different ; publishers, and it apparently had ; tweakable options. Turning off an ; option would generate code that makes ; no sense at first glance. ; First, set the RUN flag so that, even ; if I manage to break out to a BASIC ; prompt, any command will act like RUN BB00- A9 FF LDA #$FF BB02- 85 D6 STA $D6 BB04- BD 8D C0 LDA $C08D,X ; Some disks have a "LDA $C08E,X" here ; to require that the disk be write- ; protected. With the option off, it's ; just an unconditional jump. BB07- A9 FF LDA #$FF BB09- EA NOP BB0A- 30 05 BMI $BB11 ;[always skipped] ;BB0C- A2 B1 LDX #$B1 ;BB0E- 4C F0 BB JMP $BBF0 ; Some disks check the low-level reset ; vector (I think this was protection ; against "boot inspectors" like Watson ; that installed themselves in the ; language card and left it active ; during boot). This disk changes the ; CMP to an "LDA #$00", making this ; another unconditional jump. BB11- AD FD FF LDA $FFFD BB14- A9 00 LDA #$00 BB16- F0 05 BEQ $BB1D ;[always skipped] ;BB18- A2 B2 LDX #$B2 ;BB1A- 4C F0 BB JMP $BBF0 BB1D- BD 8C C0 LDA $C08C,X ; Set the first character of the input ; buffer to null. This can be checked ; later to ensure that an attacker (me) ; hasn't interrupted the boot and been ; typing things. BB20- A9 00 LDA #$00 BB22- 8D 00 02 STA $0200 ; look for a magic nibble sequence on ; track 0 BB25- BD 8C C0 LDA $C08C,X BB28- 10 FB BPL $BB25 BB2A- C9 EB CMP #$EB BB2C- D0 F7 BNE $BB25 BB2E- BD 8C C0 LDA $C08C,X BB31- 10 FB BPL $BB2E BB33- C9 D5 CMP #$D5 BB35- D0 EE BNE $BB25 BB37- BD 8C C0 LDA $C08C,X BB3A- 10 FB BPL $BB37 BB3C- C9 AA CMP #$AA BB3E- D0 E5 BNE $BB25 ; wipe most of memory ($0800..$95FF) ; although, ironically, not the part ; I'm using for boot tracing BB40- A9 4C LDA #$4C BB42- A0 00 LDY #$00 BB44- 99 00 95 STA $9500,Y BB47- 88 DEY BB48- D0 FA BNE $BB44 BB4A- CE 46 BB DEC $BB46 BB4D- AD 46 BB LDA $BB46 BB50- C9 07 CMP #$07 BB52- D0 EC BNE $BB40 ; fiddle with the RWTS to ignore ; epilogue bytes BB54- A9 18 LDA #$18 BB56- 8D 42 B9 STA $B942 ; sector $0A BB59- A9 0A LDA #$0A BB5B- 8D ED B7 STA $B7ED BB5E- D0 05 BNE $BB65 ...[some zeroes used for data later]... ; track $00 BB65- A9 00 LDA #$00 BB67- 8D EC B7 STA $B7EC ; into $4000 BB6A- 8D F0 B7 STA $B7F0 BB6D- A9 40 LDA #$40 BB6F- 8D F1 B7 STA $B7F1 ; read command BB72- A9 01 LDA #$01 BB74- 8D F4 B7 STA $B7F4 ; set up rest of RWTS table BB77- 8D F8 B7 STA $B7F8 BB7A- 8D EA B7 STA $B7EA BB7D- 8E E9 B7 STX $B7E9 BB80- 8E F7 B7 STX $B7F7 ; more RWTS fiddling, so sector reads ; save raw nibble data in $6C00 range BB83- A0 6C LDY #$6C BB85- 8C 10 B9 STY $B910 BB88- 8C CE B8 STY $B8CE BB8B- 8C D2 B8 STY $B8D2 BB8E- 88 DEY BB8F- 8C 21 B9 STY $B921 ; a sector read, with modified RWTS BB92- 20 E7 BB JSR $BBE7 ; copy the raw nibble data elsewhere BB95- A0 55 LDY #$55 BB97- B9 00 6C LDA $6C00,Y BB9A- 99 00 5C STA $5C00,Y BB9D- 88 DEY BB9E- 10 F7 BPL $BB97 BBA0- AD 02 6B LDA $6B02 BBA3- 85 06 STA $06 ; another sector read BBA5- 20 E7 BB JSR $BBE7 BBA8- AD 02 6B LDA $6B02 BBAB- 85 07 STA $07 ; and another BBAD- 20 E7 BB JSR $BBE7 BBB0- AD 02 6B LDA $6B02 BBB3- 85 08 STA $08 ; compare this read's nibble data to ; the previous read's nibble data BBB5- A0 55 LDY #$55 BBB7- B9 00 6C LDA $6C00,Y BBBA- D9 00 5C CMP $5C00,Y ; fail if anything doesn't match BBBD- D0 2F BNE $BBEE BBBF- 88 DEY BBC0- 10 F5 BPL $BBB7 ; more comparisons of the side effects ; generated by the modified RWTS BBC2- A5 06 LDA $06 BBC4- C5 07 CMP $07 BBC6- D0 04 BNE $BBCC BBC8- C5 08 CMP $08 BBCA- F0 17 BEQ $BBE3 ; success path is here -- ; first, restore the RWTS code BBCC- A9 38 LDA #$38 BBCE- 8D 42 B9 STA $B942 BBD1- A0 BC LDY #$BC BBD3- 8C 10 B9 STY $B910 BBD6- 8C CE B8 STY $B8CE BBD9- 8C D2 B8 STY $B8D2 BBDC- 88 DEY BBDD- 8C 21 B9 STY $B921 ; then continue with boot1 as normal BBE0- 4C 00 B7 JMP $B700 BBE3- 4C 54 BB JMP $BB54 ... BBE7- A9 B7 LDA #$B7 BBE9- A0 E8 LDY #$E8 BBEB- 4C B5 B7 JMP $B7B5 ; failure path from comparison at $BBBD BBEE- A2 B3 LDX #$B3 ; general failure path is here -- ; clear screen, show text screen, write ; error code, and jump to The Badlands BBF0- 20 58 FC JSR $FC58 BBF3- 20 2D FF JSR $FF2D BBF6- 8E 03 04 STX $0403 BBF9- 4C 5B B7 JMP $B75B I'm guessing my non-working copy never got as far as wiping main memory, since the search for the nibble sequence is unconditional and neverending. That explains the behavior I saw -- it spun forever with the drive motor on, and it never got off track 0. The important takeaway here is that there don't appear to be any long-term side effects of this copy protection. If it succeeds, it restores everything that it modified (in the RWTS code), then it just jumps to $B700 to start the boot1 phase. But that's it; nothing else seems to rely on some magic number that it pulls from the raw nibbles or anything. It doesn't decrypt anything. It doesn't even clear the carry flag. ~ Chapter 3 In Which We Remove All Traces Of Copy Protection Using An Automated Tool That I Wrote For Just Such An Occasion [S6,D1=demuffin'd copy] [S5,D1=my work disk] ]PR#5 ... ]BRUN PDP ; fix epilogue byte checking in RWTS T00,S03,$91 change FF to DE T00,S03,$9B change FF to AA T00,S03,$35 change FF to DE T00,S03,$3F change FF to AA T00,S02,$9E change FF to DE T00,S02,$A3 change FF to AA T00,S02,$A8 change FF to EB ; neutralize some routines for RWTS ; fiddling at runtime (not used by this ; disk as far as I can tell, but no ; harm in patching them) T00,S04,$69 change A9 to 60 T00,S04,$7D change A9 to 60 ; bypass nibble check after boot0 T00,S00,$4B change FEBB to FD08 ; fix nibble table (ooh, I didn't see ; this in my investigation -- hooray ; for automation) T00,S04,$29 change AA to 96 Side B uses identical protection (including PDP patches). Quod erat liberandum. --------------------------------------- A 4am crack No. 302 ------------------EOF------------------