----------The Mask of the Sun---------- A 4am crack 2017-08-21 --------------------------------------- Name: The Mask of the Sun Version: 2.1 Genre: adventure Year: 1982 Credits: Ultrasoft Publisher: Broderbund Software Platform: Apple ][+ or later Media: double-sided 5.25-inch floppy OS: DOS 3.3 Previous cracks: none of this version (Asimov has uncracked .nib images of unknown provenance) Only side A is bootable. Technically, side B is bootable in the sense that it boots to a message that says "BOOT OTHER SIDE." Let's not be pedantic, OK? ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA (side A) read error on first pass Locksmith Fast Disk Backup unable to read track $03 or above EDD 4 bit copy (no sync, no count) works Copy ][+ nibble editor no obvious signs of why track $03+ would be unreadable Disk Fixer T00,S00 looks like a standard DOS 3.3 bootloader in fact, tracks 0-2 look like a standard copy of DOS 3.3 T01,S09 -> startup program is "START" Why didn't COPYA work? something funky going on on track 3+ Why didn't Locksmith FDB work? ditto EDD worked. What does that tell us? No half or quarter tracks, because I didn't even try to copy those. Just the structural changes (prologues and epilogues) and an RWTS patched to read them. Next steps: 1. Convert disk to standard format with Advanced Demuffin 2. Patch RWTS to read standard format 3. Declare victory (*) (*) Go to the gym ~ Chapter 1 In Which We Attempt To Intercept The Note Turning to my trusty Disk Fixer sector editor, I can examine the bootloader to see if anything stands out. T00,S00 is identical to an unprotected DOS 3.3 disk. T00,S01, loaded at $B700, is usually responsible for loading the rest of DOS from tracks 2, 1, and 0, then jumping to $9D84 to initialize DOS and load the startup program. Looking at the code, everything appears to be in order, until the final jump: --v-- T00,S01 ----------- DISASSEMBLY MODE ---------- 002E:4A LSR 002F:AA TAX 0030:A9 00 LDA #$00 0032:9D F8 04 STA $04F8,X 0035:9D 78 04 STA $0478,X ; read DOS from disk 0038:20 93 B7 JSR $B793 ; reset stack 003B:A2 FF LDX #$FF 003D:9A TXS 003E:8E EB B7 STX $B7EB ; machine initialization 0041:20 93 FE JSR $FE93 0044:20 89 FE JSR $FE89 ; jump to... wait, what? 0047:4C 8D B7 JMP $B78D --^-- Since this sector is loaded at $B700, that extra code is in this very sector. --v-- T00,S01 ----------- DISASSEMBLY MODE ---------- 008D:20 6D BA JSR $BA6D 0090:4C 84 9D JMP $9D84 --^-- $BA00 is on T00,S04. $BA69..$BA95 is unused in some versions of DOS, which makes it the perfect place to sneak in a few bytes of... extra code. I don't like extra. Extra is bad. And lo, it turns out there is something very suspicious there: an RWTS swapper! It starts at $BA69, with a second entry point at $BA6D (which is what we're calling during boot). --v-- T00,S04 ----------- DISASSEMBLY MODE ---------- 0069:A2 6E LDX #$6E 006B:D0 0B BNE $0078 006D:A2 8A LDX #$8A 006F:EA NOP 0070:D0 06 BNE $0078 0072:A2 6F LDX #$6F 0074:A0 00 LDY #$00 0076:F0 02 BEQ $007A 0078:A0 36 LDY #$36 ; encrypt nibble translation table 007A:A9 12 LDA #$12 007C:5D 00 BA EOR $BA00,X 007F:9D 00 BA STA $BA00,X ; modify EOR operand (below) 0082:8C 8C BA STY $BA8C 0085:A0 3F LDY #$3F 0087:BE 29 BA LDX $BA29,Y 008A:8A TXA ; self-modified above, at $BA82 008B:49 FF EOR #$FF 008D:9D 00 BA STA $BA00,X 0090:88 DEY 0091:10 F4 BPL $0087 0093:60 RTS --^-- Due to hardware limitations, Apple II floppy drives are not able to store all possible data values directly. This translation table is how DOS converts the "raw" data on disk to the bytes in memory (and back). Any alteration of this translation table would be like swapping letters of the alphabet to exchange notes in class. You could still read it if you knew which letters had been swapped, but anyone who intercepted the note and tried to read it would be baffled. We're the ones trying to intercept the note. It's not going to work unless we can capture one of the translators. ~ Chapter 2 In Which We Attempt To Capture A Translator I have two floppy drives, one in slot 6 and the other in slot 5. My "work disk" (in slot 5) runs Diversi-DOS 64K, which is compatible with Apple DOS 3.3 but relocates most of DOS to the language card on boot. This frees up most of main memory (only using a single page at $BF00..$BFFF), which is useful for loading large files or examining code that lives in areas typically reserved for DOS. [S6,D1=original disk] [S5,D1=my work disk] The floppy drive firmware code at $C600 is responsible for aligning the drive head and reading sector 0 of track 0 into main memory at $0800. Because the drive can be connected to any slot, the firmware code can't assume it's loaded at $C600. If the floppy drive card were removed from slot 6 and reinstalled in slot 5, the firmware code would load at $C500 instead. To accommodate this, the firmware does some fancy stack manipulation to detect where it is in memory (which is a neat trick, since the 6502 program counter is not generally accessible). However, due to space constraints, the detection code only cares about the lower 4 bits of the high byte of its own address. $C600 (or $C500, or anywhere in $Cx00) is read-only memory. I can't change it, which means I can't stop it from transferring control to the boot sector of the disk once it's in memory. BUT! The disk firmware code works unmodified at any address. Any address that ends with $x600 will boot slot 6, including $B600, $A600, $9600, &c. ; copy drive firmware to $9600 *9600S6,D2 --^-- [S6,D1=original disk] [S6,D2=blank disk] 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 $03,$00-$22,$0F BY1.0 S6,D1->S6,D2 --^-- Tracks 0-2 are unprotected, so I used Copy II Plus manual sector copy to copy them. (Not shown; it's under "bit copy" if you're looking for it. Just start on track 0 and end on track 2.) Now I have a disk that boots but can't read itself (above track 2), because it still thinks that track 3 and above use the altered nibble translation table. They don't; I just normalized them with Advanced Demuffin. So I need to disable that routine. Since there are multiple entry points ($BA69, $BA6D, and I think one at $BA72 as well), I should disable it where they all converge, at $BA7A. [S6,D1=non-working copy] T00,S04,$7A: A9 -> 60 ]PR#6 ...works... Side B is also protected with the same altered nibble translation table, on tracks $01-$22. (Track 0 is standard.) I used Advanced Demuffin with the same captured RWTS. There is no additional code on side B, so no post-demuffin patches were required. Quod erat liberandum. --------------------------------------- A 4am crack No. 1380 ------------------EOF------------------