----------Oliver's Crosswords---------- A 4am crack 2017-06-22 --------------------------------------- Name: Oliver's Crosswords Genre: educational Year: 1990 Publisher: Micrograms Publishing Platform: Apple ][+ or later Media: 2 single-sided 5.25-inch disks OS: custom Previous cracks: none ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA no errors, but copy hangs on boot with a text screen full of code Locksmith Fast Disk Backup ditto EDD 4 bit copy (no sync, no count) works Copy ][+ nibble editor disk volume is 000, which is unusual, but otherwise tracks look normal -- 16-sector, standard address fields, standard everything really Disk Fixer all tracks readable ProDOS-style bootloader and disk catalog, but no "PRODOS" file Booting my ProDOS hard drive, I can get a disk catalog. ]PR#7 ... ]CAT,S6,D1 /BOOT NAME TYPE BLOCKS MODIFIED BAD3.4 SYS 7 PI.TITLE BIN 17 ST.FONT BIN 5 CR.CWRDS.MAIN BIN 13 CWRDS BIN 15 UTL BIN 8 SETA BIN 16 SETB BIN 16 SETC BIN 18 SETD BIN 18 SETE BIN 22 SETF BIN 21 BLOCKS FREE: 97 BLOCKS USED: 183 Usually the first .SYS file is called "PRODOS", but this disk has "BAD3.4" instead. Why didn't COPYA or Locksmith FDB work? probably a nibble check in early boot Why *did* EDD work? the nibble check probably isn't very strong Next steps: 1. Find the protection check and disable it 2. Declare victory (*) (*) go to the gym ~ Chapter 1 In Which We Take A Shortcut That Turns Out To Be Not So Short The fastest way to find a runtime protection check is to search for the instruction that turns on the drive motor. Generally this is "LDA $C089,X" (following the convention that the X register contains the boot slot x 16), but it could also be hard-coded to slot 6 like "LDA $C0E9" or some other variant. [Disk Fixer] ["F"]ind ["H"]ex "BD 89 C0" One match, on T00,S0E, which is part of the ProDOS-style bootloader. No other matches anywhere, which is odd. --> "AD E9 C0" No matches whatsoever. WTF. Maybe it's encrypted to prevent exactly the thing I'm trying to do right now? Let's try searching for the instruction that loads the data latch to fetch a single nibble from disk: "LDA $C08C,X". --> "BD 8C C0" Again, just the one match on T00,S0E. This is looking less and less like a shortcut. Maybe the hard-coded variant "LDA $C0EC"? After that I'm out of ideas and I'm going to trace the boot from the beginning. --> "AD EC C0" --v-- ------------- DISK SEARCH ------------- $01/$0B-$1E $01/$0B-$27 $01/$0B-$30 $01/$0C-$5E $01/$0C-$67 $01/$0C-$70 $01/$0C-$80 $01/$0C-$88 $01/$0C-$C3 $01/$0C-$CC $01/$0C-$D5 --^-- Praise be. Let's see what we found. (Side note: according to Copy II Plus "disk map," this code is in that mysterious "BAD3.4" .SYS file.) --v-- T01,S0C ----------- DISASSEMBLY MODE ---------- ; match address prologue ($D5 $AA $96) 0050:A9 00 LDA #$00 0052:85 FC STA $FC 0054:88 DEY 0055:D0 07 BNE $005E 0057:C6 FC DEC $FC 0059:D0 03 BNE $005E 005B:20 C5 09 JSR $09C5 005E:AD EC C0 LDA $C0EC 0061:10 FB BPL $005E 0063:C9 D5 CMP #$D5 0065:D0 ED BNE $0054 0067:AD EC C0 LDA $C0EC 006A:10 FB BPL $0067 006C:C9 AA CMP #$AA 006E:D0 EE BNE $005E 0070:AD EC C0 LDA $C0EC 0073:10 FB BPL $0070 0075:C9 96 CMP #$96 0077:D0 E5 BNE $005E ; parse address field and store it in ; $082C+ (instead of zero page) 0079:A0 03 LDY #$03 007B:A9 00 LDA #$00 007D:8D 2B 08 STA $082B 0080:AD EC C0 LDA $C0EC 0083:10 FB BPL $0080 0085:2A ROL 0086:85 F9 STA $F9 0088:AD EC C0 LDA $C0EC 008B:10 FB BPL $0088 008D:25 F9 AND $F9 008F:99 2C 08 STA $082C,Y 0092:4D 2B 08 EOR $082B 0095:88 DEY 0096:10 E5 BPL $007D 0098:A8 TAY 0099:D0 AD BNE $0048 ; looks like we're checking the track ; to see if it's the right one, and ; recalibrating if it's not (DOS 3.3 ; does this too but not inline) 009B:AD 2E 08 LDA $082E 009E:C5 EB CMP $EB 00A0:F0 0B BEQ $00AD 00A2:0A ASL 00A3:85 ED STA $ED 00A5:A5 EB LDA $EB 00A7:20 31 0A JSR $0A31 00AA:4C D2 08 JMP $08D2 00AD:AD 2D 08 LDA $082D 00B0:C5 EC CMP $EC 00B2:D0 94 BNE $0048 00B4:60 RTS ; separate entry point for reading the ; data prologue and data field 00B5:A9 00 LDA #$00 00B7:85 FC STA $FC 00B9:88 DEY 00BA:D0 07 BNE $00C3 00BC:C6 FC DEC $FC 00BE:D0 03 BNE $00C3 00C0:20 C5 09 JSR $09C5 ; match data prologue $D5 $AA $AD 00C3:AD EC C0 LDA $C0EC 00C6:10 FB BPL $00C3 00C8:C9 D5 CMP #$D5 00CA:D0 ED BNE $00B9 00CC:AD EC C0 LDA $C0EC 00CF:10 FB BPL $00CC 00D1:C9 AA CMP #$AA 00D3:D0 EE BNE $00C3 00D5:AD EC C0 LDA $C0EC 00D8:10 FB BPL $00D5 00DA:C9 AD CMP #$AD 00DC:D0 E5 BNE $00C3 ; 6-and-2 decoding 00DE:A9 00 LDA #$00 00E0:A2 56 LDX #$56 00E2:AC EC C0 LDY $C0EC 00E5:10 FB BPL $00E2 00E7:59 00 0C EOR $0C00,Y 00EA:CA DEX 00EB:9D 00 0C STA $0C00,X 00EE:D0 F2 BNE $00E2 00F0:AC EC C0 LDY $C0EC 00F3:10 FB BPL $00F0 00F5:59 00 0C EOR $0C00,Y 00F8:9D 00 0F STA $0F00,X 00FB:E8 INX 00FC:D0 F2 BNE $00F0 00FE:AC EC C0 LDY $C0EC [continued on T01,S0B] 0001:10 FB BPL $FFFE 0003:59 00 0C EOR $0C00,Y 0006:F0 02 BEQ $000A 0008:38 SEC 0009:60 RTS ; separate entry point for epilogue ; checking 000A:A9 00 LDA #$00 000C:85 FC STA $FC 000E:88 DEY 000F:D0 0D BNE $001E 0011:C6 FC DEC $FC 0013:D0 09 BNE $001E ; turn on text page 2, which is not ; something you generally see inside ; RWTS code (this might be where my ; non-working copy ended up) 0015:2C 51 C0 BIT $C051 0018:2C 55 C0 BIT $C055 001B:4C A5 09 JMP $09A5 ; match standard epilogue ($DE $AA) 001E:AD EC C0 LDA $C0EC 0021:10 FB BPL $001E 0023:C9 DE CMP #$DE 0025:D0 E7 BNE $000E 0027:AD EC C0 LDA $C0EC 002A:10 FB BPL $0027 002C:C9 AA CMP #$AA 002E:D0 EE BNE $001E ; match... a third epilogue nibble?!? 0030:AD EC C0 LDA $C0EC 0033:10 FB BPL $0030 0035:C9 BE CMP #$BE 0037:D0 E5 BNE $001E 0039:18 CLC 003A:60 RTS --^-- Oh wow. That's not what I was expecting at all, but that's the problem. There is no protection check. The protection is purely structural -- this RWTS code is super-strict and requires a third (non-standard) epilogue nibble. Technically, both the address epilogue and the data epilogue are three nibbles $DE $AA $EB. But even standard DOS 3.3 never checks more than the first two. (ProDOS only checks the first one.) Literally nothing checks the third nibble of the epilogue. Except this disk. And it's non-standard ($BE instead of $EB). So the disk looks like it's unprotected (even copies with COPYA), but the copy can't read itself because the third epilogue nibble is wrong. The solution is to patch this RWTS so it ignores the third epilogue nibble. The least invasive way to do that is to change the "BNE" after "CMP #$BE" so it branches to the next instruction, effectively making it a NOP. T01,S0B,$38: E5 -> 00 ]PR#6 ...works... Disk 2 has identical proteection. Quod erat liberandum. --------------------------------------- A 4am crack No. 1269 ------------------EOF------------------