-----------Computer Literacy----------- A 4am crack 2014-08-05 --------------------------------------- "Computer Literacy: Introduction" is a 1982 educational program distributed by Control Data Corporation. The content is adapted from "Introduction to Computers" by Dr. John Aikin and Greg Starling. COPYA fails miserably and immediately with a disk read error. EDD 4 bit copy gives no read errors, but the copy does not work; it just hangs on boot. Turning to my trusty Copy ][+ sector editor, I press "P" to get to the Sector Editor Patcher, and select "DOS 3.3 PATCHED". This option ignores checksum bytes and epilogue sequences -- as long as the address and data prologue are standard ("D5 AA 96" and "D5 AA AD", respectively), this will allow me to read each sector. And lo and behold, it works! I can read the data from every sector on every track, with one exception: T00,S0A. Given that the original disk boots correctly, I'm going to guess that this sector is either unused (in which case, I have a damaged original disk but caught a lucky break) or part of a copy protection scheme (in which case I don't care). Let's see if I can capture the RWTS from the original disk. [S6,D1=original disk] [S5,D1=my work disk] ]PR#5 CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 For those of you just tuning in, my work disk uses a custom program that I affectionately call "AUTOTRACE" to automate the process of boot tracing as far as possible. For some disks (like this one, apparently), it just captures track 0, sector 0 (saved in a file called "BOOT0") and stops. For other disks that load in the same way that an unprotected DOS 3.3 disk loads, it captures the next stage of the boot process as well (in a file called "BOOT1"). BOOT1 contains sectors 0-9 on track 0, which are loaded into memory at $B600..$BFFF. This generally contains the RWTS routines which the program uses to read the rest of the disk. If the RWTS is fairly normal as well (and my AUTOTRACE program just spot- checks a few memory locations to guess at its "normalcy"), AUTOTRACE extracts the RWTS routines (generally loaded from track 0, sectors 2-9 into $B800.. $BFFF) and saves *that* into a third file called "RWTS". There's a good chance I'll be able to load that "RWTS" file into a tool called Advanced Demuffin (written in 1983 by The Stack) to convert the disk into a standard disk readable by unprotected DOS 3.3 disks or any other third-party tools. If anything looks fishy or non- standard, AUTOTRACE just stops, and I have to check the files it saved so far to determine why. In this case, it stopped after capturing T00,S00. So I need to look at that sector and figure out why. ]CALL -151 *800<2800.28FFM *801L ... Everything here looks pretty normal (i.e. just like an unprotected DOS 3.3 disk), until it goes to jump to the boot1 code. Usually that happens with an indirect JMP ($08FD), which, in a normal boot0, will end up continuing execution at $B700 which is stored in track 0, sector 1. But in this case, I see: 084A- 6C FE BB JMP ($BBFE) Highly suspect. I definitely want to see what evil lurks at whatever address $BBFE is pointing to. That area of memory is normally reserved for the denibblizing process when reading data from a sector. It's scratch space, essentially. It's overwritten every time the disk reads itself (after boot1 is loaded). But $BBFE isn't loaded yet, because I interrupted the boot process before it could be loaded. So now I need to trace the boot again, but a little bit further -- far enough for boot0 to load boot1 (including the suspicious pointer at $BBFE), but no further. My work disk has another program, unimaginatively named AUTOTRACE1, which does just that. It loads track 0, sector 0, then patches the boot0 code at $084A to call back to a routine under my control (instead of jumping to the original disk's boot1 code). ]BRUN AUTOTRACE1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS Let's see what we have. ]CALL -151 *FE89G FE93G ; disconnect DOS *B600<2000.29FFM ; move RWTS in place *BBFE.BBFF BBFE- 00 BB *BB00L BB00- A9 00 LDA #$00 BB02- 85 D6 STA $D6 BB04- BD 8D C0 LDA $C08D,X BB07- A9 FF LDA #$FF BB09- EA NOP BB0A- 30 05 BMI $BB11 BB0C- A2 B1 LDX #$B1 BB0E- 4C F0 BB JMP $BBF0 BB11- AD FD FF LDA $FFFD BB14- A9 00 LDA #$00 BB16- F0 05 BEQ $BB1D BB18- A2 B2 LDX #$B2 BB1A- 4C F0 BB JMP $BBF0 ; search for a nibble sequence BB1D- BD 8C C0 LDA $C08C,X BB20- A9 00 LDA #$00 BB22- 8D 00 02 STA $0200 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 RWTS to ignore epilogue ; bytes (WTF) BB54- A9 18 LDA #$18 BB56- 8D 42 B9 STA $B942 BB59- A9 0A LDA #$0A ; read T00,S0A into $4000 (hey, this ; means that unreadable sector was part ; of the copy protection after all) BB5B- 8D ED B7 STA $B7ED BB5E- D0 05 BNE $BB65 ... BB65- A9 00 LDA #$00 BB67- 8D EC B7 STA $B7EC BB6A- 8D F0 B7 STA $B7F0 BB6D- A9 40 LDA #$40 BB6F- 8D F1 B7 STA $B7F1 BB72- A9 01 LDA #$01 BB74- 8D F4 B7 STA $B7F4 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 ; another 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 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 BBBD- D0 2F BNE $BBEE BBBF- 88 DEY BBC0- 10 F5 BPL $BBB7 ; some more comparisons, just because 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 is here BBEE- A2 B3 LDX #$B3 BBF0- 20 58 FC JSR $FC58 BBF3- 20 2D FF JSR $FF2D BBF6- 8E 03 04 STX $0403 BBF9- 4C 5B B7 JMP $B75B 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. With that knowledge, I can safely ignore it and focus on getting the disk into a standard format, using Advanced Demuffin and the "RWTS" file that my AUTOTRACE program saved. For the longest time, I thought that Advanced Demuffin would only load RWTS files from slot 6, drive 1. That's where the original disk was during boot tracing, and that's where it needs to be during demuffining (which is a real word that I totally just made up), and that means I ended up swapping floppy disks like some kind of 12th century barbarian. Then I re-read the Advanced Demuffin tech notes (which I have included on almost every work disk I've ever produced, but apparently never read in their entirety). And I discovered that it's trivial to tell Advanced Demuffin to load RWTS files from slot 5. Note to self: read the fine manual. [S6,D1=original disk] [S6,D2=blank disk] [S5,D1=my work disk] ]PR#6 ]BRUN ADVANCED DEMUFFIN 1.1 --> EXIT TO MONITOR *F1F:50 ; use slot 5 *800G ; resume --> LOAD NEW RWTS MODULE At $B8, load "RWTS" from drive 1 --> EXIT TO MONITOR *F1F:60 ; use slot 6 *800G ; resume --> FORMAT TARGET DISK ...grind grind grind... --> CONVERT DISK This disk is 16 sectors, and the default options (copy the entire disk, all tracks, all sectors) don't need to be changed. --v-- ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======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:................................... ======================================= 16 SC $00,$00 TO $22,$0F BY $01 TO DRV2 --^-- The disk's own RWTS gave a read error on T00,S0A, but that's OK. I already know that that's part of the copy protection, so I don't care about it. The rest of the disk reads just fine. This is the power and the genius of Advanced Demuffin. Every disk must be able to read itself. So, let it read itself, then capture the data and write it out in a standard format. There are two problems with this copy: 1. Depending on how the original disk was written, my copy may or may not be able to read itself. I may need to patch the disk's RWTS to deal with the fact that the disk is now in a standard format. 2. Even if it can read itself, it won't run, because it's executing a copy protection routine during boot to check if the disk is original. (Hint: it's not.) I already have enough information to fix problem #2. The copy protection is located at $BB00, and it is executed immediately after boot0 (T00,S00) loads boot1 (T00,S01-09). This line of code: 084A- 6C FE BB JMP ($BBFE) ...needs to look like this: 084A- 6C FD 08 JMP ($08FD) T00,S00,$4B change "FE BB" to "FD 08" Now the disk boots far enough to start grinding because it can't read itself. The RWTS still expects the rest of the disk to be in a non-standard format, but that's no longer true -- Advanced Demuffin wrote out each sector in a standard format. So I need to patch the RWTS on my copy so it can read itself. The original disk uses a modified version of DOS 3.3. (It's so close, that I was able to capture it with my automated tools.) So I'm really just reverting the modifications they made 30 years ago. Better late than never. For future reference (mostly mine), here's a nice chart of the memory locations for all the prologues and epilogues in a DOS 3.3-shaped RWTS. If the RWTS stores $B700 in T00,S01 (most do), then $B8xx will be in T00,S02; $B9xx in T00,S03; and so on. 0x | read | write ---------------+-------+------- D5 | $B955 | $BC7A prologue AA | $B95F | $BC7F / 96 | $B96A | $BC84 ADDRESS -------+-------+------- \ DE | $B991 | $BCAE epilogue AA | $B99B | $BCB3 EB | | $BCB8 ---------------+-------+------- D5 | $B8E7 | $B853 prologue AA | $B8F1 | $B858 / AD | $B8FC | $B85D DATA ----------+-------+------- \ DE | $B935 | $B89E epilogue AA | $B93F | $B8A3 EB | | $B8A8 ---------------+-------+------- (Memorize that chart; it will be on the final exam.) Using my trusty Copy ][+ sector editor, I found 7 bytes that differ from the standard DOS 3.3 RWTS: T00,S02,$9E change "FF" to "DE" T00,S02,$A3 change "FF" to "AA" T00,S02,$A8 change "FF" to "EB" T00,S03,$35 change "FF" to "DE" T00,S03,$3F change "FF" to "AA" T00,S03,$91 change "FF" to "DE" T00,S03,$9B change "FF" to "AA" With these patches in place, my copy can now boot and read itself. It loads and runs without complaint. There doesn't appear to be any further copy protection. Quod erat liberandum. --------------------------------------- A 4am crack No. 103 ------------------EOF------------------