--------------Crozzzwords-------------- A 4am crack 2017-11-20 --------------------------------------- Name: Crozzzwords Genre: educational Year: 1987 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 "POP" 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 $1A/$0A-$89 $1A/$0A-$99 $1A/$0A-$B4 $1A/$0A-$C5 $1A/$0A-$CF $1A/$0A-$DE --^-- The matches on track $00 are part of DOS 3.3, i.e. not suspicious. But the cluster of matches on track $1A are highly suspect. ~ Chapter 2 In Which We Find Ourselves In Enemy Territory The protection routine appears to start at offset $54. --v-- T1A,S0A ----------- DISASSEMBLY MODE ---------- ; get boot slot (x16) 0054:A6 2B LDX $2B ; save zero page addresses on stack 0056:A5 FD LDA $FD 0058:48 PHA 0059:A5 FE LDA $FE 005B:48 PHA ; get RWTS parameter table address 005C:20 E3 03 JSR $03E3 005F:84 FD STY $FD 0061:85 FE STA $FE ; track $14 -- the mystery track! 0063:A0 04 LDY #$04 0065:A9 14 LDA #$14 0067:91 FD STA ($FD),Y ; RWTS command = seek 0069:A0 0C LDY #$0C 006B:A9 00 LDA #$00 006D:91 FD STA ($FD),Y ; slow down IIgs (has no effect on ; other machines) 006F:AD 36 C0 LDA $C036 0072:29 7F AND #$7F 0074:8D 36 C0 STA $C036 ; disable last line of RWTS that turns ; off the drive motor 0077:A9 60 LDA #$60 0079:8D 4D BE STA $BE4D ; call the RWTS to execute the seek to ; track $14 007C:20 E3 03 JSR $03E3 007F:20 D9 03 JSR $03D9 ; restore the RWTS code (but the drive ; motor is still on) 0082:A9 BD LDA #$BD 0084:8D 4D BE STA $BE4D ; if the seek failed for some reason, ; exit 0087:B0 65 BCS $00EE ; find $D5 nibble 0089:BD 8C C0 LDA $C08C,X 008C:10 FB BPL $0089 008E:48 PHA 008F:68 PLA 0090:C9 D5 CMP #$D5 0092:D0 F5 BNE $0089 ; initialize a checksum 0094:A0 00 LDY #$00 0096:8C 6D 47 STY $476D ; count number of $F7 nibbles before ; another $D5 nibble 0099:BD 8C C0 LDA $C08C,X 009C:10 FB BPL $0099 009E:C9 D5 CMP #$D5 00A0:F0 0F BEQ $00B1 00A2:C9 F7 CMP #$F7 00A4:D0 01 BNE $00A7 00A6:C8 INY ; the sum of the nibbles themselves ; constitutes the checksum 00A7:18 CLC 00A8:6D 6D 47 ADC $476D 00AB:8D 6D 47 STA $476D 00AE:4C E5 46 JMP $46E5 00B1:98 TYA 00B2:F0 E0 BEQ $0094 ; skip $FF nibbles 00B4:BD 8C C0 LDA $C08C,X 00B7:10 FB BPL $00B4 00B9:48 PHA 00BA:68 PLA 00BB:C9 FF CMP #$FF 00BD:F0 F5 BEQ $00B4 ; if next nibble is $D5, fail 00BF:C9 D5 CMP #$D5 00C1:F0 35 BEQ $00F8 ; skip several more nibbles 00C3:A0 05 LDY #$05 00C5:BD 8C C0 LDA $C08C,X 00C8:10 FB BPL $00C5 00CA:48 PHA 00CB:68 PLA 00CC:88 DEY 00CD:D0 F6 BNE $00C5 ; skip $FF nibbles 00CF:BD 8C C0 LDA $C08C,X 00D2:10 FB BPL $00CF 00D4:48 PHA 00D5:68 PLA 00D6:C9 FF CMP #$FF 00D8:F0 F5 BEQ $00CF ; if next nibble is not $D5, fail 00DA:C9 D5 CMP #$D5 00DC:D0 1A BNE $00F8 ; skip $FF nibbles 00DE:BD 8C C0 LDA $C08C,X 00E1:10 FB BPL $00DE 00E3:C9 FF CMP #$FF 00E5:D0 11 BNE $00F8 ; verify checksum, branch on failure 00E7:AD 6D 47 LDA $476D 00EA:C9 10 CMP #$10 00EC:D0 0A BNE $00F8 ; success path falls through to here -- ; turn off drive motor, restore zero ; page, and return to caller gracefully 00EE:BD 88 C0 LDA $C088,X 00F1:68 PLA 00F2:85 FE STA $FE 00F4:68 PLA 00F5:85 FD STA $FD 00F7:60 RTS ; all failures lead here -- ; wipe memory 00F8:A2 70 LDX #$70 00FA:A9 A0 LDA #$A0 00FC:99 FF 48 STA $48FF,Y 00FF:C8 INY [continued on T1A,S09] 0000:D0 FA BNE $FFFC 0002:EE 4A 47 INC $474A 0005:CA DEX 0006:D0 F4 BNE $FFFC 0008:AD 8A C0 LDA $C08A ; display encrypted error message ; "DISK ERROR 35W" 000B:20 2F FB JSR $FB2F 000E:20 58 FC JSR $FC58 0011:A0 0E LDY #$0E 0013:B9 6E 47 LDA $476E,Y 0016:49 BB EOR #$BB 0018:99 B4 05 STA $05B4,Y 001B:88 DEY 001C:10 F5 BPL $0013 001E:78 SEI ; hang forever 001F:30 FE BMI $001F (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. T1A,S0A,$54: A6 -> 60 ]PR#6 ...works... Quod erat liberandum. --------------------------------------- A 4am crack No. 1534 ------------------EOF------------------