---------------Jumblezzz--------------- A 4am crack 2017-11-19 --------------------------------------- Name: Jumblezzz Genre: educational Year: 1987 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 $15 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 $15 is almost entirely sync bytes, with the occasional $D5 nibble (almost certainly a protection track) Disk Fixer entire disk is standard except T15 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 $15, designed to fool even the best bit copiers Next steps: 1. Find the protection check that is reading track $15 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 $17/$0A-$52 $17/$0A-$62 $17/$0A-$7D $17/$0A-$8E $17/$0A-$98 $17/$0A-$A7 --^-- The matches on track $00 are part of DOS 3.3, i.e. not suspicious. But the cluster of matches on track $17 are highly suspect. ~ Chapter 2 In Which We Find Ourselves In Enemy Territory The protection routine appears to start at offset $1D. --v-- T17,S0A ----------- DISASSEMBLY MODE ---------- ; get boot slot (x16) 001D:A6 2B LDX $2B ; save zero page addresses on stack 001F:A5 FD LDA $FD 0021:48 PHA 0022:A5 FE LDA $FE 0024:48 PHA ; get RWTS parameter table address 0025:20 E3 03 JSR $03E3 0028:84 FD STY $FD 002A:85 FE STA $FE ; track $15 -- the mystery track! 002C:A0 04 LDY #$04 002E:A9 15 LDA #$15 0030:91 FD STA ($FD),Y ; RWTS command = seek 0032:A0 0C LDY #$0C 0034:A9 00 LDA #$00 0036:91 FD STA ($FD),Y ; slow down IIgs (has no effect on ; other machines) 0038:AD 36 C0 LDA $C036 003B:29 7F AND #$7F 003D:8D 36 C0 STA $C036 ; disable last line of RWTS that turns ; off the drive motor 0040:A9 60 LDA #$60 0042:8D 4D BE STA $BE4D ; call the RWTS to execute the seek to ; track $15 0045:20 E3 03 JSR $03E3 0048:20 D9 03 JSR $03D9 ; restore the RWTS code (but the drive ; motor is still on) 004B:A9 BD LDA #$BD 004D:8D 4D BE STA $BE4D ; if the seek failed for some reason, ; exit 0050:B0 65 BCS $00B7 ; find $D5 nibble 0052:BD 8C C0 LDA $C08C,X 0055:10 FB BPL $0052 0057:48 PHA 0058:68 PLA 0059:C9 D5 CMP #$D5 005B:D0 F5 BNE $0052 ; initialize a checksum 005D:A0 00 LDY #$00 005F:8C E6 91 STY $91E6 ; count number of $F7 nibbles before ; another $D5 nibble 0062:BD 8C C0 LDA $C08C,X 0065:10 FB BPL $0062 0067:C9 D5 CMP #$D5 0069:F0 0F BEQ $007A 006B:C9 F7 CMP #$F7 006D:D0 01 BNE $0070 006F:C8 INY ; the sum of the nibbles themselves ; constitutes the checksum 0070:18 CLC 0071:6D E6 91 ADC $91E6 0074:8D E6 91 STA $91E6 0077:4C 5E 91 JMP $915E 007A:98 TYA 007B:F0 E0 BEQ $005D ; skip $FF nibbles 007D:BD 8C C0 LDA $C08C,X 0080:10 FB BPL $007D 0082:48 PHA 0083:68 PLA 0084:C9 FF CMP #$FF 0086:F0 F5 BEQ $007D ; if next nibble is $D5, fail 0088:C9 D5 CMP #$D5 008A:F0 35 BEQ $00C1 ; skip several more nibbles 008C:A0 05 LDY #$05 008E:BD 8C C0 LDA $C08C,X 0091:10 FB BPL $008E 0093:48 PHA 0094:68 PLA 0095:88 DEY 0096:D0 F6 BNE $008E ; skip $FF nibbles 0098:BD 8C C0 LDA $C08C,X 009B:10 FB BPL $0098 009D:48 PHA 009E:68 PLA 009F:C9 FF CMP #$FF 00A1:F0 F5 BEQ $0098 ; if next nibble is not $D5, fail 00A3:C9 D5 CMP #$D5 00A5:D0 1A BNE $00C1 ; skip $FF nibbles 00A7:BD 8C C0 LDA $C08C,X 00AA:10 FB BPL $00A7 00AC:C9 FF CMP #$FF 00AE:D0 11 BNE $00C1 ; verify checksum, branch on failure 00B0:AD E6 91 LDA $91E6 00B3:C9 10 CMP #$10 00B5:D0 0A BNE $00C1 ; success path falls through to here -- ; turn off drive motor and continue ; elsewhere 00B7:BD 88 C0 LDA $C088,X ; restore zero page 00BA:68 PLA 00BB:85 FE STA $FE 00BD:68 PLA 00BE:85 FD STA $FD ; return to caller gracefully 00C0:60 RTS ; all failures lead here -- ; wipe memory 00C1:A2 80 LDX #$80 00C3:A9 A0 LDA #$A0 00C5:99 FF 08 STA $08FF,Y 00C8:C8 INY 00C9:D0 FA BNE $00C5 00CB:EE C3 91 INC $91C3 00CE:CA DEX 00CF:D0 F4 BNE $00C5 00D1:AD 8A C0 LDA $C08A ; display encrypted error message ; "DISK ERROR 35W" 00D4:20 2F FB JSR $FB2F 00D7:20 58 FC JSR $FC58 00DA:A0 0E LDY #$0E 00DC:B9 E7 91 LDA $91E7,Y 00DF:49 BB EOR #$BB 00E1:99 B4 05 STA $05B4,Y 00E4:88 DEY 00E5:10 F5 BPL $00DC 00E7:78 SEI ; hang forever 00E8:30 FE BMI $00E8 (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. T17,S0A,$1D: A6 -> 60 ]PR#6 ...works... Quod erat liberandum. --------------------------------------- A 4am crack No. 1528 ------------------EOF------------------