-------------Mind Castle II------------ A 4am crack 2015-05-27 --------------------------------------- Name: Mind Castle II Genre: adventure Year: 1984 Publisher: MCE, Inc. Media: single-sided 5.25-inch floppy OS: DOS 3.3 Other versions: none (preserved here for the first time) ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA no errors, but copy reboots endlessly Locksmith Fast Disk Backup ditto EDD 4 bit copy (no sync, no count) ditto Copy ][+ nibble editor nothing suspicious Disk Fixer T00 -> looks like a DOS 3.3 RWTS T11 -> DOS 3.3 disk catalog No sign of DOS 3.3 in between, though Why didn't my copies work? probably a nibble check in early boot Next steps: 1. AUTOTRACE to capture early boot 2. Find nibble check and disable it 3. There is no step 3 (I hope) ~ Chapter 1 In Which It Dawns On Us That There Is Most Definitely Going To Be A Step 3 [S6,D1=original disk] [S5,D1=my work disk] ]PR#5 ... CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 CAPTURING BOOT1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS ]CATALOG,S6,D1 C1983 DSR^C#254 018 FREE A 002 HELLO B 063 MCS1.GT B 046 MCS2.GT B 057 MCS3.GT B 057 MCS4.GT B 064 MCS5.GT B 066 MCS6.GT B 035 MCS7.GT A 004 MCS1.SA A 004 MCS2.SA A 004 MCS3.SA A 004 MCS4.SA A 004 MCS5.SA A 005 MCS6.SA A 005 MCS7.SA B 025 SW16/MAIN/HRCG B 026 MCS LOGO B 002 APSOFT/MAIN INTERFACE B 009 CHRSETA/SHPS/SOUND TAB B 004 CHRSETB A 003 MCS INTRO ]RUN HELLO ...hangs... Hmm. ]PR#5 ]LOAD HELLO,S6,D1 ...hangs... Double hmm. ]PR#5 ]BLOAD MCS LOGO,S6,D1 ...hangs... Triple hmm. Turning to my trusty Disk Fixer sector editor, I take a peek at track $11 (the disk catalog). --v-- -------------- DISK EDIT -------------- TRACK $11/SECTOR $0F/VOLUME $FE/BYTE$00 --------------------------------------- $00:>00<11 0E 00 00 00 00 00 @QN@@@@@ $08: 00 00 00 13 0F 02 C8 C5 @@@SOBHE ^^^^^ track/sector list $10: CC CC CF A0 A0 A0 A0 A0 LLO $18: A0 A0 A0 A0 A0 A0 A0 A0 $20: A0 A0 A0 A0 A0 A0 A0 A0 $28: A0 A0 A0 A0 02 00 14 0F B@TO $30: 04 CD C3 D3 B1 AE C7 D4 DMCS1.GT $38: A0 A0 A0 A0 A0 A0 A0 A0 $40: A0 A0 A0 A0 A0 A0 A0 A0 $48: A0 A0 A0 A0 A0 A0 A0 3F ? $50: 00 15 0F 04 CD C3 D3 B2 @UODMCS2 $58: AE C7 D4 A0 A0 A0 A0 A0 .GT $60: A0 A0 A0 A0 A0 A0 A0 A0 $68: A0 A0 A0 A0 A0 A0 A0 A0 $70: A0 A0 2E 00 16 0F 04 CD .@VODM $78: C3 D3 B3 AE C7 D4 A0 A0 CS3.GT --------------------------------------- BUFFER 0/SLOT 6/DRIVE 1/MASK OFF/NORMAL --------------------------------------- COMMAND : _ --^-- It says the HELLO file starts on T13,S0F. But that sector is completely garbled: --v-- -------------- DISK EDIT -------------- TRACK $13/SECTOR $0F/VOLUME $FE/BYTE$00 --------------------------------------- $00:>D0D0 The mystery values are $D7 (in $03F0) and $F9 (in $03F1). ~ Chapter 3 In Which We Go Down The Rabbit Hole And It Occurs To Us That Perhaps We Need A New Set Of Analogies Because Rabbits Are Eating Our Garden In Real Life And We're Kind Of Sick Of It To Be Honest Now that I know what to look for, it's surprisingly easy to find it. Turning to my trusty Disk Fixer sector editor, I search the original disk for "F0 03" and "F1 03" and find plenty of hits on track $00. --v-- "F0 03" ------------- DISK SEARCH ------------- $00/$05-$AF $00/$05-$C0 $00/$06-$E8 $00/$06-$FA "F1 03" ------------- DISK SEARCH ------------- $00/$05-$BA $00/$06-$EB $00/$06-$F7 --^-- T00,S05 is loaded at $BB00; I already know about those. But what's all this on T00,S06? Let's find out. ]PR#5 ... ]BLOAD BOOT1,A$2600 ]CALL -151 *FE89G FE93G *B600<2600.2FFFM *BC00L . . . BCDE- 60 RTS ; seems like one entry point is here BCDF- B1 3E LDA ($3E),Y BCE1- 2C FF BC BIT $BCFF BCE4- 30 07 BMI $BCED BCE6- 18 CLC BCE7- 4D F0 03 EOR $03F0 <-- ! BCEA- 6D F1 03 ADC $03F1 <-- ! BCED- 4A LSR BCEE- 60 RTS ; another entry point is here BCEF- 2A ROL BCF0- 2C FF BC BIT $BCFF BCF3- 30 07 BMI $BCFC BCF5- 38 SEC BCF6- ED F1 03 SBC $03F1 <-- ! BCF9- 4D F0 03 EOR $03F0 <-- ! BCFC- 91 3E STA ($3E),Y BCFE- 60 RTS Those two mystery values are embedded in the RWTS at a deep level. Another quick sector search for "20 DF BC" found the caller of $BCDF at $B805: *B800L ; the "prenibble" routine, which ; converts 256 bytes in memory to 342 ; nibbles (to be written to disk) B800- A2 00 LDX #$00 B802- A0 02 LDY #$02 B804- 88 DEY B805- 20 DF BC JSR $BCDF <-- ! B808- 3E 00 BC ROL $BC00,X B80B- 4A LSR B80C- 3E 00 BC ROL $BC00,X B80F- 99 00 BB STA $BB00,Y B812- E8 INX B813- E0 56 CPX #$56 B815- 90 ED BCC $B804 ...and the caller of $BCEF, at $B8D3: *B8C2L ; the "postnibble" routine, which ; converts 342 nibbles (read from disk) ; to 256 bytes (to be stored in memory) B8C2- A0 00 LDY #$00 B8C4- A2 56 LDX #$56 B8C6- CA DEX B8C7- 30 FB BMI $B8C4 B8C9- B9 00 BB LDA $BB00,Y B8CC- 5E 00 BC LSR $BC00,X B8CF- 2A ROL B8D0- 5E 00 BC LSR $BC00,X B8D3- 20 EF BC JSR $BCEF <-- ! B8D6- C8 INY B8D7- C4 26 CPY $26 B8D9- D0 EB BNE $B8C6 B8DB- 60 RTS Every nibble on this disk is decrypted on read and encrypted on write. No exceptions. Well, one exception. What's this about $BCFF? BCE1- 2C FF BC BIT $BCFF <-- ? BCE4- 30 07 BMI $BCED and BCF0- 2C FF BC BIT $BCFF <-- ? BCF3- 30 07 BMI $BCFC A quick sector search for "FF BC" found where it's set, at $B758. The routine appears to start at $B74B. *B74BL ; ? B74B- 8C F8 06 STY $06F8 ; if ($48) points to an RWTS parameter ; table, then this will get the track ; number B74E- A0 04 LDY #$04 B750- B1 48 LDA ($48),Y ; is it track $11? B752- C9 11 CMP #$11 ; no, branch B754- D0 02 BNE $B758 ; yes, set high bit B756- 09 80 ORA #$80 ; store the result B758- 8D FF BC STA $BCFF B75B- 60 RTS And after one final sector search for "20 4B B7", it appears that $B74B is called almost immediately after the RWTS entry point at $BD00: *BD00L BD00- 84 48 STY $48 BD02- 85 49 STA $49 BD04- A0 02 LDY #$02 BD06- 20 4B B7 JSR $B74B <-- ! BD09- A0 04 LDY #$04 BD0B- 8C F8 04 STY $04F8 (The instruction at $BD06 is supposed to be "STY $06F8", which explains why that instruction was replicated at $B74B.) In other words, track $11 is the only track that is *not* encrypted. (Technically, T00,S00-T00,S09 are also unencrypted, because they're read by the disk controller ROM during boot. But the other sectors on track $00 are encrypted, because they're read by the RWTS to load DOS.) This explains why I could CATALOG the disk successfully from my work disk, but it crashed when I tried to RUN or LOAD anything. I wasn't running the original RWTS that knew how to decrypt each individual sector, and apparently it's not that difficult to crash DOS if you feed it bogus track/sector lists. So, you know, don't do that. Oh, and even if I swapped the original RWTS into memory, I would need to have the magic values in $03F0 and $03F1 in order for the decryption to work. And those are embedded in the desync'ed bitstream after a successful nibble check during boot. Everything is awesome. ~ Chapter 3 In Which Everything Is Awesome When We're Living Our Dream I'm going to use the original disk as a weapon against itself. Once the magic values in page 3 are initialized, I can I can use the original disk's RWTS (already captured) to decrypt every single sector on every single track, then write them out -- unencrypted, thankyouverymuch -- to a blank disk. All I need is Advanced Demuffin and an IOB module. (Read the docs on my work disk for background on IOB modules.) ]PR#5 ... ]CALL -151 ]BLOAD ADVANCED DEMUFFIN 1.5 ; standard Advanced Demuffin setup ; (unchanged) 1400- 4A LSR 1401- 8D 22 0F STA $0F22 1404- 8C 23 0F STY $0F23 1407- 8E 27 0F STX $0F27 140A- A9 01 LDA #$01 140C- 8D 20 0F STA $0F20 140F- 8D 2A 0F STA $0F2A ; initialize decryption keys 1412- A9 D7 LDA #$D7 1414- 8D F0 03 STA $03F0 1417- A9 F9 LDA #$F9 1419- 8D F1 03 STA $03F1 ; call RWTS 141C- A9 0F LDA #$0F 141E- A0 1E LDY #$1E 1420- 4C 00 BD JMP $BD00 *BSAVE IOB,A$1400,L$FB Two things to keep in mind (that I got wrong the first few times I tried to do this): 1. The RWTS calls $B74B to set the flag at $BCFF that determines whether this track is encrypted. If I tell Advanced Demuffin to use the RWTS file at $B800, I won't have that routine at $B74B, so the decryption either won't work at all or it will mistakenly decrypt the unencrypted track $11. Solution: load BOOT1 at $B600. It includes the RWTS at $B800 and the extra routine at $B74B. 2. T00,S00-T00,S09 are not encrypted (because they're read by the disk controller ROM routine, not the RWTS), but the rest of track $00 is encrypted. Solution: put my non-working copy in drive 2, then tell Advanced Demuffin to start the conversion at T00,S0A. [S6,D1=original disk] [S6,D2=non-working copy] [S5,D1=my work disk] *BRUN ADVANCED DEMUFFIN ["5" to switch to slot 5] ["R" to load a new RWTS module] --> At $B6, load "BOOT1" from drive 1 [press "I" to load a new IOB module] --> load "IOB" from drive 1 ["6" to switch to slot 6] ["C" to convert disk] ["Y" to change default values] --v-- ADVANCED DEMUFFIN 1.5 (C) 1983, 2014 ORIGINAL BY THE STACK UPDATES BY 4AM ======================================= INPUT ALL VALUES IN HEX SECTORS PER TRACK? (13/16) 16 START TRACK: $00 START SECTOR: $0A <-- change this END TRACK: $22 END SECTOR: $0F INCREMENT: 1 MAX # OF RETRIES: 0 COPY FROM DRIVE 1 TO DRIVE: 2 ======================================= 16SC $00,$0A-$22,$0F BY1.0 S6,D1->S6,D2 --^-- And here we go... --v-- ADVANCED DEMUFFIN 1.5 (C) 1983, 2014 ORIGINAL BY THE STACK UPDATES BY 4AM =======PRESS ANY KEY TO CONTINUE======= TRK:................................... +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0: .................................. SC1: .................................. SC2: .................................. SC3: .................................. SC4: .................................. SC5: .................................. SC6: .................................. SC7: .................................. SC8: .................................. SC9: .................................. SCA:................................... SCB:................................... SCC:................................... SCD:................................... SCE:................................... SCF:................................... ======================================= 16SC $00,$0A-$22,$0F BY1.0 S6,D1->S6,D2 --^-- ]PR#5 ... ]LOAD HELLO,S6,D2 ]LIST 1 TEXT : HOME : NORMAL : SPEED= 255: PRINT : PRINT CHR$ (4) "MAXFILES1": HIMEM: 35752: PRINT CHR$ (4)"BRUNMCS LOGO": POKE 230,32: POKE - 16297,0: POKE - 16302,0: POKE - 16304,0 10 POKE 104,65: POKE 16640,0: PRINT CHR$ (4) + "RUNMCS INTRO" + CHR$ (13) Finally, I can undo the modifications to the RWTS and the bootloader. Undo the "JSR $B74B" at $BD06: T00,S07,$06 change "204BB7" to "8CF806" Undo the "JSR $BCEF" at $B8D3: T00,S02,$EF change "20EFBC" to "2A913E" Undo the "JSR $BCDF" at $B805: T00,S02,$05 change "20DFBC" to "B13E4A" Neutralize the nibble check at $BB34: T00,S05,$34 change "A9" to "60" Quod erat liberandum. --------------------------------------- A 4am crack No. 319 ------------------EOF------------------