----------------Pentapus--------------- A 4am crack 2019-05-28 --------------------------------------- Name: Pentapus Genre: action Year: 1983 Publisher: Turning Point Software Platform: Apple ][+ or later Media: 5.25-inch disk Sides: 1 OS: DOS 3.3 ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA fails on last pass Locksmith Fast Disk Backup unable to read tracks $21 and $22 EDD 4 bit copy (no sync, no count) errors on T21 and T22 copy boots but immediately says "INVALID DISKETTE! RETURN TO TURNING POINT SOFTWARE" I will not be doing that. Copy ][+ nibble editor T21 seems unformatted T22 is almost entirely $FF nibbles with some $D5 and a few other scattered ones thrown in for good measure Disk Fixer DOS 3.3-style bootloader but no DOS no disk catalog on track $11 game loads straight from RWTS reads Why didn't COPYA work? specially formatted tracks at the end of the disk Why didn't Locksmith FDB work? likewise Why didn't my EDD copy work? unclear -- protection check looking at track $22 that couldn't copy properly? Next steps: 1. Trace the boot 2. Disable the protection check 3. Declare victory (*) (*) go to the gym ~ Chapter 1 In Which It's All Over But The Screaming Turning to my trusty Disk Fixer sector editor, track 0 starts off as a normal DOS 3.3-shaped bootloader before jumping to $B700 (stored on sector 1). We shall pick up the action there. T00,S01 ----------- DISASSEMBLY MODE ---------- 0000:8E E9 B7 STX $B7E9 0003:8E F7 B7 STX $B7F7 0006:A9 01 LDA #$01 0008:8D F8 B7 STA $B7F8 000B:8D EA B7 STA $B7EA 000E:AD C2 B7 LDA $B7C2 0011:8D C3 B7 STA $B7C3 0014:8A TXA 0015:4A LSR 0016:4A LSR 0017:4A LSR 0018:4A LSR 0019:AA TAX 001A:A9 00 LDA #$00 001C:9D F8 04 STA $04F8,X 001F:9D 78 04 STA $0478,X 0022:20 79 B7 JSR $B779 ... ; priming for an RWTS read into $0800 0079:A9 08 LDA #$08 007B:8D F1 B7 STA $B7F1 007E:8D 97 B7 STA $B797 ; sector $0C 0081:A9 0C LDA #$0C 0083:8D ED B7 STA $B7ED ; track $00 0086:A9 00 LDA #$00 0088:8D EC B7 STA $B7EC 008B:A9 01 LDA #$01 008D:8D F4 B7 STA $B7F4 0090:20 98 B7 JSR $B798 0093:B0 E4 BCS $0079 ; self-modified earlier (at $B77E) to ; jump to $0800 after reading 0095:4C 00 FF JMP $FF00 0098:A9 B7 LDA #$B7 009A:A0 E8 LDY #$E8 009C:4C B5 B7 JMP $B7B5 OK, let's look at track 0, sector $0C. T00,S0C ----------- DISASSEMBLY MODE ---------- 0000:4C 85 08 JMP $0885 ... ; will examine this in a moment 0085:20 03 08 JSR $0803 ; turn off drive motor 0088:BD 88 C0 LDA $C088,X ; carry clear = success 008B:90 F7 BCC $0084 ; The Badlands -- clear the screen and ; display the error message I saw on my ; non-working copy 008D:20 58 FC JSR $FC58 0090:A0 84 LDY #$84 0092:99 00 08 STA $0800,Y 0095:88 DEY 0096:D0 FA BNE $0092 0098:8C F4 03 STY $03F4 009B:B9 B2 08 LDA $08B2,Y 009E:F0 06 BEQ $00A6 00A0:99 34 04 STA $0434,Y 00A3:C8 INY 00A4:D0 F5 BNE $009B 00A6:A8 TAY 00A7:B9 C4 08 LDA $08C4,Y 00AA:F0 E4 BEQ $0090 00AC:99 2C 05 STA $052C,Y 00AF:C8 INY 00B0:D0 F5 BNE $00A7 OK, so the subroutine at $0803 very much needs to return with the carry clear. ; set up another RWTS call, on ; track $22 (the mystery track!) 0003:A9 22 LDA #$22 0005:8D EC B7 STA $B7EC ; seek only 0008:A9 00 LDA #$00 000A:8D F4 B7 STA $B7F4 ; patch RWTS to return without turning ; off the drive motor 000D:A9 60 LDA #$60 000F:8D 4D BE STA $BE4D ; seek to track $22 0012:A0 E8 LDY #$E8 0014:A9 B7 LDA #$B7 0016:20 00 BD JSR $BD00 ; restore code we just patched 0019:A9 BD LDA #$BD 001B:8D 4D BE STA $BE4D 001E:B0 64 BCS $0084 ; the meat of the protection check -- ; reading and counting nibbles on the ; mystery track $22 0020:BD 8C C0 LDA $C08C,X 0023:10 FB BPL $0020 0025:48 PHA 0026:68 PLA 0027:C9 D5 CMP #$D5 0029:D0 F5 BNE $0020 ; initial counter 002B:A0 00 LDY #$00 002D:84 FE STY $FE ; find next $D5 or $F7 nibble 002F:BD 8C C0 LDA $C08C,X 0032:10 FB BPL $002F 0034:C9 D5 CMP #$D5 0036:F0 0D BEQ $0045 0038:C9 F7 CMP #$F7 003A:D0 01 BNE $003D ; meanwhile, count the nibbles in ; between (the non-$D5/$F7 nibbles are ; $FF, so this is a fancy way of ; subtracting 1 from zero page $FE) 003C:C8 INY 003D:18 CLC 003E:65 FE ADC $FE 0040:85 FE STA $FE 0042:4C 2F 08 JMP $082F 0045:98 TYA 0046:F0 E3 BEQ $002B ; find next $D5 nibble 0048:BD 8C C0 LDA $C08C,X 004B:10 FB BPL $0048 004D:48 PHA 004E:68 PLA 004F:C9 FF CMP #$FF 0051:F0 F5 BEQ $0048 0053:C9 D5 CMP #$D5 0055:F0 24 BEQ $007B ; skip next 5 nibbles 0057:A0 05 LDY #$05 0059:BD 8C C0 LDA $C08C,X 005C:10 FB BPL $0059 005E:48 PHA 005F:68 PLA 0060:88 DEY 0061:D0 F6 BNE $0059 ; find next $D5 nibble 0063:BD 8C C0 LDA $C08C,X 0066:10 FB BPL $0063 0068:48 PHA 0069:68 PLA 006A:C9 FF CMP #$FF 006C:F0 F5 BEQ $0063 006E:C9 D5 CMP #$D5 0070:D0 09 BNE $007B ; next nibble must be $FF 0072:BD 8C C0 LDA $C08C,X 0075:10 FB BPL $0072 0077:C9 FF CMP #$FF 0079:F0 02 BEQ $007D ; otherwise we fail and return to the ; caller 007B:38 SEC 007C:60 RTS ; and the previous count must be #$F0 ; or some multiple of #$100 that wraps ; around to #$F0 007D:A5 FE LDA $FE 007F:C9 10 CMP #$10 0081:D0 F8 BNE $007B ; as we figured out already by looking ; at the caller, this subroutine clears ; the carry bit on success 0083:18 CLC 0084:60 RTS This patch will change the protection subroutine at $0803 so it clears the carry and returns. T00,S0C,$03: A922 -> 1860 Quod erat liberandum. --------------------------------------- A 4am crack No. 2033 ------------------EOF------------------