---------To Kill A Mockingbird--------- A 4am crack 2014-04-08 --------------------------------------- To Kill A Mockingbird is a 1983 educational program distributed by Media Basics, Inc. The original disk is uncopyable by COPYA or Locksmith Fast Disk Backup. EDD 4 bit copy gives no read errors, but the copy just grinds a few times and reboots. Some manual inspection with the Copy ][+ nibble editor reveals that every odd track has a non-standard address prologue: Track | Address | Data ------+----------+---------- $00 | D5 AA 96 | D5 AA AD $01 | D4 AA 96 | D5 AA AD $02 | D5 AA 96 | D5 AA AD $03 | D4 AA 96 | D5 AA AD $04 | D5 AA 96 | D5 AA AD $05 | D4 AA 96 | D5 AA AD And so on. Time for boot tracing with AUTOTRACE. [S5D1=my work disk] [S6D1=original disk] ]PR#5 ... CAPTURING BOOT0 ...boots slot 6... ...boots slot 5... SAVING BOOT0 Hmm, something about track 0 sector 0 is non-standard, because my AUTOTRACE program bailed after capturing it. 0839- EE FE 08 INC $08FE 083C- EE FE 08 INC $08FE 083F- 20 89 FE JSR $FE89 0842- 20 93 FE JSR $FE93 0845- 20 2F FB JSR $FB2F 0848- A6 2B LDX $2B 084A- 4C F0 08 JMP $08F0 That's the first non-standard thing I see: at $084A, a normal DOS 3.3 boot sector would do a JMP ($08FD), which would jump to the code stored in T00,S01 (usually at $B700, but not always, hence the indirection). But this disk has something different in mind. 08F0- A9 AA LDA #$AA 08F2- 85 31 STA $31 08F4- A9 00 LDA #$00 08F6- 8D F1 B6 STA $B6F1 08F9- 4C 00 B7 JMP $B700 OK, so it's storing a constant in zero page $31, then zeroing out a byte in the $B600 range, then doing a direct jump to boot1 at $B700. The zeroing out thing is a nice touch. Track 0, sector 0 is actually loaded twice: once at $0800 by the disk controller ROM routine at $C600, then again at $B600 by the boot0 code at $0800. Then the $0800 page is usually overwritten by the HELLO program or whatever auto-runs after DOS is fully loaded, but the $B600 page remains memory. When you INIT a disk, it's the $B600 page that gets written to track 0, sector 0. All of which means that, if you manage to boot this disk, break out of the program and get to a BASIC prompt, and try to INIT a disk with this custom DOS, the freshly formatted disk will be slightly different than the original, because the value at $B6F1 was zeroed out. I still have no idea what that value is used for, but it's obviously important enough for the bootloader to try to hide it. Continuing, then, with the boot tracing, by patching myself in at $08F9. (This is TRACE1 on my work disk.) ; rudely interrupt boot process to call ; a routine under my control 96F8- A9 4C LDA #$4C 96FA- 8D F9 08 STA $08F9 96FD- A9 16 LDA #$16 96FF- 8D FA 08 STA $08FA 9702- A9 97 LDA #$97 9704- 8D FB 08 STA $08FB 9707- AD FE 08 LDA $08FE 970A- 8D 1C 97 STA $971C 970D- AD FF 08 LDA $08FF 9710- 8D 17 97 STA $9717 9713- 4C 01 08 JMP $0801 ; callback starts here ; copy $B600..$BFFF to a safe location ; that will survive a reboot 9716- A2 0A LDX #$0A 9718- A0 00 LDY #$00 971A- B9 00 B6 LDA $B600,Y 971D- 99 00 20 STA $2000,Y 9720- C8 INY 9721- D0 F7 BNE $971A 9723- EE 1C 97 INC $971C 9726- EE 1F 97 INC $971F 9729- CA DEX 972A- 10 EE BPL $971A ; signal to my work disk that it should ; save BOOT1 now 972C- A9 81 LDA #$81 972E- 8D 00 01 STA $0100 9731- 49 A5 EOR #$A5 9733- 8D 01 01 STA $0101 ; turn off slot 6 disk motor 9736- AD E8 C0 LDA $C0E8 ; reboot into my work disk 9739- 4C 00 C5 JMP $C500 This captures an RWTS that I can load into Advanced Demuffin to let the disk read itself, then copy the data out to a fresh disk with standard prologue and epilogue sequences. [S6D1=my work disk] ]PR#6 ]BRUN ADVANCED DEMUFFIN 1.1 --> LOAD NEW RWTS MODULE At $B8, load "RWTS" from D1 [S6,D1=TKAM original disk] [S6,D2=blank disk] --> FORMAT TARGET DISK ...grind grind grind... --> CONVERT DISK ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC1:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC2:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC3:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC4:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC5:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC6:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC7:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC8:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC9:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCA:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCB:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCC:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCD:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCE:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCF:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR ======================================= 16 SC $00,$00 TO $22,$0F BY $01 TO DRV2 Well that didn't work. At all. The original disk's own RWTS couldn't read a single sector of ... the original disk. WTF? Digging into the custom RWTS I captured, I finally hit upon the root of the problem. Remember that value in zero page $31? That turns out to be used by the RWTS itself. Example: B925- BC 8C C0 LDY $C08C,X B928- 10 FB BPL $B925 B92A- D9 00 BA CMP $BA00,Y B92D- D0 13 BNE $B942 B92F- BD 8C C0 LDA $C08C,X B932- 10 FB BPL $B92F B934- C9 DE CMP #$DE B936- D0 0A BNE $B942 B938- EA NOP B939- BD 8C C0 LDA $C08C,X B93C- 10 FB BPL $B939 B93E- C5 31 CMP $31 B940- F0 5C BEQ $B99E B942- 38 SEC B943- 60 RTS Normally at $B93E, the RWTS would compare to a constant value, like CMP #$AA. But this RWTS is comparing to the value of zero page $31. Which, as you recall, contains the value $AA. Except when it doesn't, like when some enterprising hacker tries to reuse the custom RWTS in a new context (like Advanced Demuffin) that doesn't execute the boot0 code first. So zero page $31 is never set, so the RWTS is looking for the wrong epilogue bytes, so every single disk read fails. At this point, I could try to hack the RWTS even further to get it to work under Advanced Demuffin, but I'm wary of this code and don't know what other tricks are up its sleeve. So I'm going to backtrack and take a different approach. My initial (manual) inspection of the original disk in the Copy ][+ nibble editor revealed a definite pattern to the address prologue sequences. Even tracks (including track 0) use the standard prologue, "D5 AA 96"; odd tracks (starting with track 1) use "D4 AA 96" instead. As it happens, Advanced Demuffin has an option I've never changed before, a track increment value. It defaults to 1 to convert every track, but I could easily change it to 2 to convert every other track. Furthermore, I can control the start and end tracks. So I can convert this disk in two passes. The first pass will copy the even tracks, and the second pass will copy the odd tracks. Using a freshly formatted ProntoDOS disk, I'll manually create an RWTS file for the even tracks, and another RWTS file for the odd tracks. [S6D1=ProntoDOS disk] [S5D1=my work disk] ]PR#6 ]CALL -151 *2800 LOAD NEW RWTS MODULE At $B8, load "NO CHECKSUM RWTS" from D1 [S6,D1=TKAM original disk] [S6,D2=blank disk] --> CONVERT DISK --> CHANGE DEFAULT VALUES? Y I want to start on track 0 and use an increment of 2. ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING ======================================= INPUT ALL VALUES IN HEX SECTORS PER TRACK? (13/16) 16 START TRACK: $00 ^ +-- this is important START SECTOR: $00 END TRACK: $22 END SECTOR: $0F INCREMENT: 2 ^ +-- this is important MAX # OF RETRIES: 0 COPY FROM DRIVE 1 TO DRIVE: 2_ ======================================= 16 SC $00,$00 TO $22,$0F BY $02 TO DRV2 And go... ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK:. . . . . . . . . . . . . . . . . . +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:. . . . . . . . . . . . . . . . . . SC1:. . . . . . . . . . . . . . . . . . SC2:. . . . . . . . . . . . . . . . . . SC3:. . . . . . . . . . . . . . . . . . SC4:. . . . . . . . . . . . . . . . . . SC5:. . . . . . . . . . . . . . . . . . SC6:. . . . . . . . . . . . . . . . . . SC7:. . . . . . . . . . . . . . . . . . SC8:. . . . . . . . . . . . . . . . . . SC9:. . . . . . . . . . . . . . . . . . SCA:. . . . . . . . . . . . . . . . . . SCB:. . . . . . . . . . . . . . . . . . SCC:. . . . . . . . . . . . . . . . . . SCD:. . . . . . . . . . . . . . . . . . SCE:. . . . . . . . . . . . . . . . . . SCF:. . . . . . . . . . . . . . . . . . ======================================= 16 SC $00,$00 TO $22,$0F BY $02 TO DRV2 Now I need to copy the odd tracks, using the "D4AA96 RWTS" file to read every other track of the original disk. [S6D1=my work disk, again] --> LOAD NEW RWTS MODULE At $B8, load "D4AA96 RWTS" from D1 [S6,D1=TKAM original disk] [S6,D2=half-blank disk] --> CONVERT DISK --> CHANGE DEFAULT VALUES? Y ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING ======================================= INPUT ALL VALUES IN HEX SECTORS PER TRACK? (13/16) 16 START TRACK: $01 ^ +-- this is important START SECTOR: $00 END TRACK: $22 END SECTOR: $0F INCREMENT: 2 ^ +-- this is important MAX # OF RETRIES: 0 COPY FROM DRIVE 1 TO DRIVE: 2_ ======================================= 16 SC $01,$00 TO $22,$0F BY $02 TO DRV2 And go... ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK: . . . . . . . . . . . . . . . . . +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0: . . . . . . . . . . . . . . . . . SC1: . . . . . . . . . . . . . . . . . SC2: . . . . . . . . . . . . . . . . . SC3: . . . . . . . . . . . . . . . . . SC4: . . . . . . . . . . . . . . . . . SC5: . . . . . . . . . . . . . . . . . SC6: . . . . . . . . . . . . . . . . . SC7: . . . . . . . . . . . . . . . . . SC8: . . . . . . . . . . . . . . . . . SC9: . . . . . . . . . . . . . . . . . SCA: . . . . . . . . . . . . . . . . . SCB: . . . . . . . . . . . . . . . . . SCC: . . . . . . . . . . . . . . . . . SCD: . . . . . . . . . . . . . . . . . SCE: . . . . . . . . . . . . . . . . . SCF: . . . . . . . . . . . . . . . . . ======================================= 16 SC $01,$00 TO $22,$0F BY $02 TO DRV2 Both passes are a success. I finally have all tracks and all sectors in a standard format. ]PR#6 ]CATALOG,S6,D2 C1983 DSR^C#254 032 FREE A 002 HELLO T 015 FILE1 T 015 FILE2 T 027 FILE3 T 042 FILE4 T 034 FILE5 A 002 READ TEXT FILE A 050 BIRD.PROG2 *B 034 MEDIA BASICS A 051 BIRD.PROG3 A 009 TRAILER B 006 MEN A 009 GRAPH1 A 052 BIRD.PROG1 *B 002 LOMEM: B 026 HIGHER TEXT *B 014 EXPANDED.F T 002 REMARKS T 008 SCRFILE A 011 TEACHER *B 034 RETURN T 002 TEMPDATA T 011 FILE6 A 006 MENU ]RUN HELLO The program runs without complaint. There doesn't appear to be any secondary protection. Of course, my copy still has a custom RWTS that expects every odd track to use a non-standard address prologue. But I don't care about that RWTS anymore. I have all the data I need. I've confirmed that further all disk access is funneled through DOS. (It even runs from drive 2!) So screw that RWTS. It's caused enough problems. Using that freshly formatted ProntoDOS disk from earlier, I call upon the ever-useful Copy ][+ "copy DOS" feature to copy tracks 0-2 of ProntoDOS onto my copy of To Kill A Mockingbird. Now the disk can read itself, and life is good. Quod erat liberandum. POSTSCRIPT: the following disks in my collection have exactly the same protection, so consider them cracked as well: - Binomial Multiplication - Graphing Linear Functions - Simultaneous Linear Equations - Solving Quadratic Equations - Kindercomp --------------------------------------- A 4am crack 2014-04-08 -------------------EOF-----------------