-----Sherlock Holmes in Another Bow---- A 4am crack 2015-08-26 --------------------------------------- Name: Sherlock Holmes in Another Bow Genre: adventure Year: 1985 Authors: Bradley G. Stewart, Peter A. Golden, Michael J. Becker, Alan Smith Publisher: Bantam Software Media: double-sided 5.25-inch floppy OS: custom with DOS 3.3 bootloader Previous cracks: Gadget Master Side A is protected but bootable. Side B is unprotected but unbootable. Life is like that. This has not been a haiku. ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways Side B copies with COPYA. Side A, on the other hand... COPYA fails on last pass Locksmith Fast Disk Backup unable to read track $22; copy swings to a high track, then turns off the drive motor and hangs EDD 4 bit copy (no sync, no count) no errors, but copy displays same behavior as Locksmith FDB Copy ][+ nibble editor there's definitely data on track $22, but it's not in any recognizable pattern --v-- COPY ][ PLUS BIT COPY PROGRAM 8.4 (C) 1982-9 CENTRAL POINT SOFTWARE, INC. --------------------------------------- TRACK: 22 START: 37F9 LENGTH: 0F0F 37D8: B7 FF BA FA BB F7 BD F7 VIEW 37E0: BE BF FB BE F6 FF FE BF 37E8: BE BB EA EA FB AA BA EA 37F0: EB EF DF BF FF F7 F6 EF 37F8: EE AB AB AB FF D5 D5 D5 <-37F9 3800: FF EA EA EA FF F5 F5 F5 3808: FF FA FA FA FF FD FD FD 3810: FF FE FE FE FF FF B6 FD 3818: B7 FF BA FA BB F7 BD F7 --------------------------------------- A TO ANALYZE DATA ESC TO QUIT ? FOR HELP SCREEN / CHANGE PARMS Q FOR NEXT TRACK SPACE TO RE-READ --^-- Disk Fixer T00 -> looks like DOS 3.3 bootloader no sign of full DOS though no sign of a disk catalog anywhere no way to read track $22 Why didn't COPYA work? something strange in the neighborhood of track $22 Why didn't Locksmith FDB work? probably a nibble check that reads the uncopyable track $22 Why didn't my EDD copy work? ditto Next steps: 1. AUTOTRACE to trace the boot as far as possible 2. Find and disable the nibble check 3. Declare victory(*) (*) take a nap(**) (**) we're not getting any younger, you know ~ Chapter 1 In Which We Do Not Get Lucky [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 The RWTS probably won't be that useful, since I can already read most of the disk with third-party tools. I doubt that it contains anything that can read track $22. But maybe we'll get lucky. ]BLOAD BOOT1,A$2600 ]CALL -151 *B600<2600.2EFFM *B700L ; appears to be filling out a standard ; RWTS paramter table B700- 8E E9 B7 STX $B7E9 B703- 8E F7 B7 STX $B7F7 B706- A9 01 LDA #$01 B708- 8D F8 B7 STA $B7F8 B70B- 8D EA B7 STA $B7EA B70E- AD E0 B7 LDA $B7E0 B711- 8D E1 B7 STA $B7E1 *B7E0 B7E0- 10 OK, reading 16 sectors. ; track $16 B714- A9 16 LDA #$16 B716- 8D EC B7 STA $B7EC ; sector $0F B719- A9 0F LDA #$0F B71B- 8D ED B7 STA $B7ED B71E- AC E7 B7 LDY $B7E7 B721- 88 DEY B722- 8C F1 B7 STY $B7F1 *B7E7 B7E7- 50 So we'll end up filling $4000..$4FFF. B725- A9 01 LDA #$01 B727- 8D F4 B7 STA $B7F4 B72A- 8A TXA B72B- 4A LSR B72C- 4A LSR B72D- 4A LSR B72E- 4A LSR B72F- AA TAX B730- A9 00 LDA #$00 B732- 9D F8 04 STA $04F8,X B735- 9D 78 04 STA $0478,X ; read it B738- 20 93 B7 JSR $B793 B73B- A2 FF LDX #$FF B73D- 9A TXS B73E- 8E EB B7 STX $B7EB B741- 20 A1 FE JSR $FEA1 B744- 20 89 FE JSR $FE89 ; and jump to it B747- 4C 00 40 JMP $4000 And that's where I need to interrupt the boot. ~ Chapter 2 In Which Luck Is What You Make It *9600 ~ Chapter 3 In Which We Make Our Own Luck *D02DL D02D- 20 A1 D9 JSR $D9A1 D030- 90 03 BCC $D035 D032- 4C 32 D0 JMP $D032 <-- ! OK, without even seeing it, I'm gonna go out on a limb and say that it's really important for the subroutine at $D9A1 to clear the carry on exit. It's either that, or end up in an infinite loop at $D032. (This may be where my non-functioning copies ended up.) *D9A1L ; clear carry to start D9A1- 18 CLC ; turn on drive motor (hard-coded to ; slot 6, booooo) D9A2- A2 60 LDX #$60 D9A4- BD 8A C0 LDA $C08A,X D9A7- BD 89 C0 LDA $C089,X A fun(*) thing to do is boot original floppies from slot 5. Lots of copy protection routines (including this one) hard-code slot 6, so you can find out when they're called because the slot 6 drive light will suddenly go on. (*) not guaranteed, actual fun may vary D9AA- A9 0C LDA #$0C D9AC- 0A ASL D9AD- A0 00 LDY #$00 ; subroutine moves the drive head based ; on the entry value of the accumulator ; and the current track -- since we're ; on track $16 and we're moving $0C ; tracks forward, we end up on the ; mysterious track $22 D9AF- 20 EF DA JSR $DAEF ; reset data latch, skip some nibbles D9B2- A9 40 LDA #$40 D9B4- 85 FA STA $FA D9B6- A2 60 LDX #$60 D9B8- BD 8E C0 LDA $C08E,X D9BB- BD 8C C0 LDA $C08C,X D9BE- 10 FB BPL $D9BB D9C0- C6 F9 DEC $F9 D9C2- D0 F7 BNE $D9BB D9C4- C6 FA DEC $FA D9C6- D0 F3 BNE $D9BB D9C8- AD AB DA LDA $DAAB D9CB- 8D AC DA STA $DAAC D9CE- 20 45 DA JSR $DA45 ; initialize state DA45- A0 00 LDY #$00 DA47- 18 CLC DA48- 2A ROL DA49- 85 FB STA $FB ; get a nibble DA4B- AD EC C0 LDA $C0EC DA4E- 10 FB BPL $DA4B ; compute a rolling checksum DA50- AA TAX DA51- 45 FB EOR $FB DA53- 2A ROL DA54- 49 41 EOR #$41 DA56- 85 FB STA $FB ; Y is the Death Counter -- if it rolls ; over to 0, branch to failure path ; which turns off the drive motor, sets ; the carry and exits DA58- C8 INY DA59- F0 CD BEQ $DA28 *DA28L DA28- AD E8 C0 LDA $C0E8 DA2B- 38 SEC DA2C- 60 RTS Continuing from $DA5B... ; loop until we find an $F7 nibble DA5B- 8A TXA DA5C- C9 F7 CMP #$F7 DA5E- D0 EB BNE $DA4B ; Now we get the next nibble, but wait! ; We've spent so much time computing ; the checksum that we would ordinarily ; miss the next nibble. But on the ; original disk, there is a timing bit ; (an extra "0" bit) after the $F7, so ; that gives us just enough time to ; catch the next nibble before it goes ; whizzing by as the disk spins. DA60- AD EC C0 LDA $C0EC DA63- 10 FB BPL $DA60 DA65- AA TAX DA66- 45 FB EOR $FB DA68- 2A ROL DA69- 49 41 EOR #$41 DA6B- 85 FB STA $FB DA6D- C8 INY DA6E- 8A TXA DA6F- C9 F7 CMP #$F7 DA71- F0 ED BEQ $DA60 ; that nibble must be $F6 DA73- C9 F6 CMP #$F6 DA75- D0 D4 BNE $DA4B ; get the next nibble (same deal -- ; there's a timing bit after the $F6) DA77- AD EC C0 LDA $C0EC DA7A- 10 FB BPL $DA77 DA7C- AA TAX DA7D- 45 FB EOR $FB DA7F- 2A ROL DA80- 49 41 EOR #$41 DA82- 85 FB STA $FB DA84- C8 INY DA85- 8A TXA DA86- C9 F7 CMP #$F7 DA88- F0 D6 BEQ $DA60 ; that nibble must be $EF DA8A- C9 EF CMP #$EF DA8C- D0 BD BNE $DA4B ; get the next nibble (same deal -- ; there's a timing bit after the $EF) DA8E- AD EC C0 LDA $C0EC DA91- 10 FB BPL $DA8E DA93- AA TAX DA94- 45 FB EOR $FB DA96- 2A ROL DA97- 49 41 EOR #$41 DA99- 85 FB STA $FB DA9B- C8 INY DA9C- 8A TXA DA9D- C9 F7 CMP #$F7 DA9F- F0 BF BEQ $DA60 ; that nibble must be $EE DAA1- C9 EE CMP #$EE DAA3- D0 A6 BNE $DA4B ; get next nibble immediately DAA5- AD EC C0 LDA $C0EC DAA8- 10 FB BPL $DAA5 DAAA- 60 RTS Continuing from $D9D1... ; compare the nibble we just read (at ; $DAA5) D9D1- C9 AB CMP #$AB ; if it's not $AB, jump to failure path D9D3- D0 53 BNE $DA28 It goes on like this for a while, checking a whole sequence of nibbles after that, then doing it a few more times to ensure it wasn't just a fluke that it passed the first time. But my non-working copy has already failed, because it has no timing bits after the $F7, $F6, $EF, or $EE nibbles. The original disk eventually falls through to $DA23 (not shown), which turns off the drive, *clears* the carry, and exits. My non-working copies always end up at $DA28, which turns off the drive, *sets* the carry, and exits. The first instruction at $D9A1 is already a "CLC", which is convenient. Let's change the second instruction to an "RTS" so this routine always signals unconditional success. T16,S09,$A2 change "A2" to "60" Quod erat liberandum. --------------------------------------- A 4am crack No. 423 ------------------EOF------------------