--------------Wordzzzearch------------- A 4am crack 2017-11-22 --------------------------------------- Name: Wordzzzearch Genre: educational Year: 1989 Credits: Methods & Solutions Publisher: Mindplay, Inc. Platform: Apple ][+ or later Media: single-sided 5.25-inch floppy OS: DOS 3.3 Previous cracks: none ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA read error on third pass Locksmith Fast Disk Backup unable to read track $14 copy boots DOS, shows a title screen, then hangs with the drive motor on EDD 4 bit copy (no sync, no count) no errors, but copy boots DOS, shows a title screen, then displays "DISK ERROR 35W" and hangs Copy ][+ nibble editor track $14 is almost entirely sync bytes, with the occasional $D5 nibble (almost certainly a protection track) Disk Fixer entire disk is standard except T14 T00,S00 -> DOS 3.3 bootloader T01,S09 -> startup program is "HELLO" standard DOS 3.3 disk catalog on T11 Why didn't any of my copies work? specially formatted nibble sequence on track $14, designed to fool even the best bit copiers Next steps: 1. Find the protection check that is reading track $14 2. Disable it 3. Declare victory (*) (*) go to the gym ~ Chapter 1 In Which We Get Lucky One thing that all protection checks have in common is they need to access the disk drive. Since most protection checks exploit edge cases of how bits are stored on disk, they need to use the lowest level access methods to manipulate those bits manually. The lowest level way to "read" a disk is the data latch softswitch address in the $C0xx range. For slot 6, it's $C0EC, but to allow disks to boot from any slot, developers usually use code like this: LDX LDA $C08C,X There's nothing that says you have to use the X-register as the index or the accumulator as the load register. But most disks do, out of convention I suppose (or fear of messing up such low-level code in subtle ways). Also, since developers don't actually want people finding their protection- related code, they may try to encrypt it or obfuscate it on disk, in memory, or both. But eventually, the code must exist and the code must run, and it must run on my machine, and I have the final say on what my machine does or does not do. But sometimes you get lucky. Turning to my trusty Disk Fixer sector editor, I search the non-working copy for "BD 8C C0", which is the opcode sequence for "LDA $C08C,X". [Disk Fixer] ["F"ind] ["H"ex] ["BD 8C C0"] --v-- ------------- DISK SEARCH ------------- $00/$02-$75 $00/$02-$8B $00/$02-$B4 $00/$02-$E1 $00/$02-$EB $00/$02-$F6 $00/$03-$2F $00/$03-$39 $00/$03-$4F $00/$03-$59 $00/$03-$64 $00/$03-$71 $00/$03-$79 $00/$03-$8B $00/$03-$95 $00/$06-$A4 $00/$06-$C0 $00/$07-$27 $00/$07-$37 $00/$07-$3C $0B/$01-$73 $0B/$01-$83 $0B/$01-$9E $0B/$01-$AF $0B/$01-$B9 $0B/$01-$C8 $13/$03-$73 $13/$03-$83 $13/$03-$9E $13/$03-$AF $13/$03-$B9 $13/$03-$C8 --^-- The matches on track $00 are part of DOS 3.3, i.e. not suspicious. But the cluster of matches on track $0B and $13 are highly suspect. ~ Chapter 2 In Which We Find Ourselves In Enemy Territory The protection routine appears to start at offset $3E. --v-- T0B,S01 ----------- DISASSEMBLY MODE ---------- ; get boot slot (x16) 003E:A6 2B LDX $2B ; save zero page addresses on stack 0040:A5 FD LDA $FD 0042:48 PHA 0043:A5 FE LDA $FE 0045:48 PHA ; get RWTS parameter table address 0046:20 E3 03 JSR $03E3 0049:84 FD STY $FD 004B:85 FE STA $FE ; track $14 -- the mystery track! 004D:A0 04 LDY #$04 004F:A9 14 LDA #$14 0051:91 FD STA ($FD),Y ; RWTS command = seek 0053:A0 0C LDY #$0C 0055:A9 00 LDA #$00 0057:91 FD STA ($FD),Y ; slow down IIgs (has no effect on ; other machines) 0059:AD 36 C0 LDA $C036 005C:29 7F AND #$7F 005E:8D 36 C0 STA $C036 ; disable last line of RWTS that turns ; off the drive motor 0061:A9 60 LDA #$60 0063:8D 4D BE STA $BE4D ; call the RWTS to execute the seek to ; track $14 0066:20 E3 03 JSR $03E3 0069:20 D9 03 JSR $03D9 ; restore the RWTS code (but the drive ; motor is still on) 006C:A9 BD LDA #$BD 006E:8D 4D BE STA $BE4D ; if the seek failed for some reason, ; exit 0071:B0 65 BCS $00D8 ; find $D5 nibble 0073:BD 8C C0 LDA $C08C,X 0076:10 FB BPL $0073 0078:48 PHA 0079:68 PLA 007A:C9 D5 CMP #$D5 007C:D0 F5 BNE $0073 ; initialize a checksum 007E:A0 00 LDY #$00 0080:8C 5D 49 STY $495D ; count number of $F7 nibbles before ; another $D5 nibble 0083:BD 8C C0 LDA $C08C,X 0086:10 FB BPL $0083 0088:C9 D5 CMP #$D5 008A:F0 0F BEQ $009B 008C:C9 F7 CMP #$F7 008E:D0 01 BNE $0091 0090:C8 INY ; the sum of the nibbles themselves ; constitutes the checksum 0091:18 CLC 0092:6D 5D 49 ADC $495D 0095:8D 5D 49 STA $495D 0098:4C D5 48 JMP $48D5 009B:98 TYA 009C:F0 E0 BEQ $007E ; skip $FF nibbles 009E:BD 8C C0 LDA $C08C,X 00A1:10 FB BPL $009E 00A3:48 PHA 00A4:68 PLA 00A5:C9 FF CMP #$FF 00A7:F0 F5 BEQ $009E ; if next nibble is $D5, fail 00A9:C9 D5 CMP #$D5 00AB:F0 35 BEQ $00E2 ; skip several more nibbles 00AD:A0 05 LDY #$05 00AF:BD 8C C0 LDA $C08C,X 00B2:10 FB BPL $00AF 00B4:48 PHA 00B5:68 PLA 00B6:88 DEY 00B7:D0 F6 BNE $00AF ; skip $FF nibbles 00B9:BD 8C C0 LDA $C08C,X 00BC:10 FB BPL $00B9 00BE:48 PHA 00BF:68 PLA 00C0:C9 FF CMP #$FF 00C2:F0 F5 BEQ $00B9 ; if next nibble is not $D5, fail 00C4:C9 D5 CMP #$D5 00C6:D0 1A BNE $00E2 ; skip $FF nibbles 00C8:BD 8C C0 LDA $C08C,X 00CB:10 FB BPL $00C8 00CD:C9 FF CMP #$FF 00CF:D0 11 BNE $00E2 ; verify checksum, branch on failure 00D1:AD 5D 49 LDA $495D 00D4:C9 10 CMP #$10 00D6:D0 0A BNE $00E2 ; success path falls through to here -- ; turn off drive motor, restore zero ; page, and return to caller gracefully 00D8:BD 88 C0 LDA $C088,X 00DB:68 PLA 00DC:85 FE STA $FE 00DE:68 PLA 00DF:85 FD STA $FD 00E1:60 RTS ; all failures lead here -- ; wipe memory 00E2:A2 60 LDX #$60 00E4:A9 A0 LDA #$A0 00E6:99 FF 4F STA $4FFF,Y 00E9:C8 INY 00EA:D0 FA BNE $00E6 00EC:EE 3A 49 INC $493A 00EF:CA DEX 00F0:D0 F4 BNE $00E6 00F2:AD 8A C0 LDA $C08A ; display encrypted error message ; "DISK ERROR 35W" 00F5:20 2F FB JSR $FB2F 00F8:20 58 FC JSR $FC58 00FB:A0 0E LDY #$0E 00FD:B9 5E 49 LDA $495E,Y [continued on T0B,S00] 0000:49 BB EOR #$BB 0002:99 B4 05 STA $05B4,Y 0005:88 DEY 0006:10 F5 BPL $FFFD 0008:78 SEI ; hang forever 0009:30 FE BMI $0009 (This is the behavior I saw on my non- working EDD bit copy.) There are no side effects. Replacing the first byte with an "RTS" will bypass the entire thing. T0B,S01,$3E: A6 -> 60 ]PR#6 ...works... There is an identical protection check on T13,S03 which seems to be an unused sector, but I patched it anyway because life is short. T13,S03,$3E: A6 -> 60 Quod erat liberandum. --------------------------------------- A 4am crack No. 1540 ------------------EOF------------------