---------------Homeworker-------------- A 4am crack 2016-10-20 --------------------------------------- Name: Homeworker Version: 2.1 Genre: educational Year: 1987 Publisher: Davidson and Associates Platform: Apple //e or later (128K) Media: double-sided 5.25-inch floppy OS: ProDOS 1.1.1 Previous cracks: none (of this version) Only side A is bootable, so I'll start there. ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA fails on last pass Locksmith Fast Disk Backup read error on T22,S00; copy boots to title screen and hangs EDD 4 bit copy (no sync, no count) works Copy ][+ nibble editor T22,S00 is there, looks normal, not sure what the problem is Disk Fixer T00 -> looks like standard ProDOS T22,S00 readable when I turn off checksums (sector is empty) Why didn't COPYA work? intentionally unformatted track Why didn't Locksmith FDB work? Probably a runtime protection check to ensure T22,S00 is unreadable EDD works. What does that tell us? The protection check is probably very simple, just checking that that block or sector is unreadable. Next steps: 1. Search for protection check 2. Disable it 3. Declare victory(*) (*) Go to the gym ~ Chapter 1 How Do I Read Thee? Let Me Count The Ways On the theory that some code on disk is trying to access T22,S00, and thus noticing if it's unexpectedly readable, let's enumerate some of the ways that could happen: - Reading a file that is mapped to the unreadable sector on track $22. Copy II+ disk map shows that track $22 is marked as "used" but there are no files mapped there, so let's rule that out. - Manually seeking to the track and looking for a nibble sequence. Given that this disk is ProDOS-based, there is no explicit support for "seeking to a particular track" unless you're calling ProDOS internals. (But that's always possible, of course!) Without calling into ProDOS, this technique would require low-level disk access (turning on the drive and hitting the right stepper motors and whatnot). A sector search with Disk Fixer didn't find any suspicious instances of "BD 89 C0" (LDA $C089,X) ; drive on "AD E9 C0" (LDA $C0E9) ; drive on "BD 80 C0" (LDA $C080,X) ; stepper or any similar variations that would point to low-level disk access. - Issuing a ProDOS MLI "raw block read" and checking the return code. This is a popular technique under ProDOS, partly because it can be adapted to work on 3.5-inch and 5.25-inch disks. Combined with the knowledge that EDD bit copy produced a working copy, I suspect this is what I'm looking for. Thus, my next move is to search for "20 00 BF 80" (JSR $BF00 / [80]) -- the standard opcode sequence for calling the ProDOS MLI with command $80 (block read). --v-- ------------- DISK SEARCH ------------- $00/$0F-$A2 $11/$09-$69 PRESS [RETURN] --^-- The match on track $00 is part of ProDOS, but the other match on track $11 is quite interesting indeed. ~ Chapter 2 Success Is Failure, Failure Is Success, Black Is White, Night Is Day, Teaching Is Dead The routine appears to start a few lines earlier, at offset $45: T11,S09 ----------- DISASSEMBLY MODE ---------- 0045:A9 00 LDA #$00 0047:8D C4 A8 STA $A8C4 ; boot slot 004A:AD 30 BF LDA $BF30 004D:8D C6 AA STA $AAC6 0050:A9 03 LDA #$03 0052:8D C5 AA STA $AAC5 ; an address? ($A8C5) 0055:A9 C5 LDA #$C5 0057:8D C7 AA STA $AAC7 005A:A9 A8 LDA #$A8 005C:8D C8 AA STA $AAC8 ; a word? ($0110) 005F:A9 10 LDA #$10 0061:8D C9 AA STA $AAC9 0064:A9 01 LDA #$01 0066:8D CA AA STA $AACA ; call the ProDOS MLI 0069:20 00 BF JSR $BF00 006C:[80] ; ID=raw block read 006D:[C5 AA] ; parameter address Aha! $0110 is the block number -- as a track/sector it would cover T22,S00. So we're issuing a raw block read to try to read the unreadable sector! ; no error = bad (remember the original ; disk has an unreadable sector, so if ; the MLI returns no error, we've found ; an unauthorized copy) 006F:90 07 BCC $0078 ; success path falls through to here -- ; set a zero page address and continue ; elsewhere 0071:A9 FF LDA #$FF 0073:85 FF STA $FF ; 99% sure this jumps ahead to offset ; $7C (i.e. this code is loaded at ; $AB00, so we're jumping ahead to the ; code three lines down) 0075:4C 7C AB JMP $AB7C ; failure path is here (from offset $6F ; above) -- set that zero page address ; to zero and exit 0078:A9 00 LDA #$00 007A:85 FF STA $FF 007C:60 RTS The difference between and original and a copy is the value of zero page $FF. Somewhere in the caller, that is being checked. Let's make sure it's always the right value, by changing the failure path to set it to the same value as the success path: T11,S09,$79: 00 -> FF ]PR#6 ...works... Side B is unprotected. Quod erat liberandum. --------------------------------------- A 4am crack No. 883 ------------------EOF------------------