----------------Arkanoid--------------- A 4am crack 2015-03-03 --------------------------------------- Name: Arkanoid Genre: arcade Year: 1988 Publisher: Taito America Corp. Media: single-sided 5.25-inch floppy OS: custom Other versions: an uncredited crack on Asimov _________________________ { } { "Brave Clarice. You } { will let me know when } { those lambs stop } { screaming, won't you?" } { } { Silence of the Lambs } {_________________________} ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA no read errors, but copy squeals and crashes Locksmith Fast Disk Backup ditto EDD 4 bit copy (no sync, no count) ditto Disk Fixer T00 -> custom bootloader T11 -> DOS 3.3 disk catalog with one file ("HELLO") which is blank no other signs of DOS, so I assume this is just a diversion Why didn't any of my copies work? Probably a nibble check during boot. It's definitely intentional code detecting that the disk is a copy. (Seriously, it *squeals*.) Next steps: 1. Boot trace 2. Find and disable the nibble check 3. Record the squeal for posterity ~ Chapter 1 In Which We Wake Up In The Dark [S6,D1=original disk] [S5,D1=my work disk] ]PR#5 CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 ]BLOAD BOOT0,A$800 ]CALL -151 *801L ; create denibblization table (copied ; verbatim from drive controller ROM ; routine at $C602..$C620) 0801- A0 00 LDY #$00 0803- A2 03 LDX #$03 0805- 86 3C STX $3C 0807- 8A TXA 0808- 0A ASL 0809- 24 3C BIT $3C 080B- F0 10 BEQ $081D 080D- 05 3C ORA $3C 080F- 49 FF EOR #$FF 0811- 29 7E AND #$7E 0813- B0 08 BCS $081D 0815- 4A LSR 0816- D0 FB BNE $0813 0818- 98 TYA 0819- 9D 80 09 STA $0980,X 081C- C8 INY 081D- E8 INX 081E- 10 E5 BPL $0805 ; probably an address ($BC00) 0820- A2 00 LDX #$00 0822- 86 80 STX $80 0824- A2 BC LDX #$BC 0826- 86 81 STX $81 ; maybe a sector count? 0828- A2 05 LDX #$05 082A- 8E FB 08 STX $08FB ; dunno 082D- A2 D8 LDX #$D8 082F- 86 47 STX $47 ; assume slot 6 and get drive ready 0831- A2 60 LDX #$60 0833- BD 8E C0 LDA $C08E,X 0836- BD 8A C0 LDA $C08A,X ; find and parse next address field 0839- 20 56 08 JSR $0856 ; is it the sector we wanted? 083C- AC FB 08 LDY $08FB 083F- B9 EB 08 LDA $08EB,Y 0842- C5 2D CMP $2D ; nope 0844- D0 F3 BNE $0839 ; match data field prologue 0846- 20 8F 08 JSR $088F ; read sector data, store it in ($80) 0849- 20 D3 08 JSR $08D3 ; decrement page 084C- C6 81 DEC $81 ; decrement sector count 084E- CE FB 08 DEC $08FB 0851- D0 DA BNE $082D ; jump to boot1 0853- 4C 00 BC JMP $BC00 That is probably the least obfuscated custom bootloader I've ever seen. I can interrupt it at $0853 and capture the boot1 code in $B800..$BCFF. *9600 *4000L ; slow down IIgs to 1 Mhz (does nothing ; on older machines) 4000- AD 36 C0 LDA $C036 4003- 29 7F AND #$7F 4005- 8D 36 C0 STA $C036 ; here we go 4008- A9 00 LDA #$00 400A- 8D F7 40 STA $40F7 400D- 20 90 40 JSR $4090 *4090L ; turn on slot 6 drive motor manually ; (always suspicious) 4090- A2 60 LDX #$60 4092- BD 8E C0 LDA $C08E,X 4095- BD 8A C0 LDA $C08A,X ; position drive head on track $21 4098- A9 42 LDA #$42 409A- 85 31 STA $31 409C- A2 60 LDX #$60 409E- 20 40 B8 JSR $B840 ; zero some memory 40A1- A9 00 LDA #$00 40A3- 8D F9 40 STA $40F9 40A6- 8D F8 40 STA $40F8 40A9- A0 0F LDY #$0F 40AB- 99 FA 40 STA $40FA,Y 40AE- 88 DEY 40AF- 10 FA BPL $40AB 40B1- 20 B5 40 JSR $40B5 40B4- 60 RTS ; just a memory move 40B5- 20 0B 41 JSR $410B 40B8- EE F8 40 INC $40F8 40BB- A9 19 LDA #$19 40BD- 8D 7B 41 STA $417B 40C0- 8D 89 41 STA $4189 40C3- 20 19 41 JSR $4119 *4119L 4119- A2 60 LDX #$60 411B- DD 8E C0 CMP $C08E,X ; wait loop 411E- A9 C0 LDA #$C0 4120- 8D 9F 41 STA $419F 4123- 8D A0 41 STA $41A0 4126- EE 9F 41 INC $419F 4129- D0 08 BNE $4133 412B- EE A0 41 INC $41A0 412E- D0 03 BNE $4133 4130- 4C 97 41 JMP $4197 ; look for address prologue 4133- BD 8C C0 LDA $C08C,X 4136- 10 FB BPL $4133 4138- C9 D5 CMP #$D5 413A- D0 EA BNE $4126 413C- BD 8C C0 LDA $C08C,X 413F- 10 FB BPL $413C 4141- C9 AA CMP #$AA 4143- D0 E1 BNE $4126 4145- BD 8C C0 LDA $C08C,X 4148- 10 FB BPL $4145 414A- C9 96 CMP #$96 414C- D0 D8 BNE $4126 414E- 20 B0 41 JSR $41B0 4151- 20 B0 41 JSR $41B0 *41B0L ; get 4-4 encoded value from address ; field 41B0- BD 8C C0 LDA $C08C,X 41B3- 10 FB BPL $41B0 41B5- 38 SEC 41B6- 2A ROL 41B7- 8D C0 41 STA $41C0 41BA- BD 8C C0 LDA $C08C,X 41BD- 10 FB BPL $41BA 41BF- 29 00 AND #$00 41C1- 8D C0 41 STA $41C0 41C4- 60 RTS ; keep trying until we find track $21 4154- C9 21 CMP #$21 4156- 8D F7 40 STA $40F7 4159- D0 CB BNE $4126 ; keep trying until we find sector $0F 415B- 20 B0 41 JSR $41B0 415E- C9 0F CMP #$0F 4160- D0 C4 BNE $4126 ; look for a nibble sequence "D5 AA" ; which is the first 2/3 of the data ; prologue, but I'm betting there's ; another one in between the address ; and data fields at the end of T21 4162- BD 8C C0 LDA $C08C,X 4165- 10 FB BPL $4162 4167- C9 D5 CMP #$D5 4169- D0 F7 BNE $4162 416B- BD 8C C0 LDA $C08C,X 416E- 10 FB BPL $416B 4170- C9 AA CMP #$AA 4172- D0 F3 BNE $4167 ; now do some math on the nibbles that ; follow 4174- A0 00 LDY #$00 4176- BD 8C C0 LDA $C08C,X 4179- 10 FB BPL $4176 417B- 19 C5 41 ORA $41C5,Y 417E- 99 C5 41 STA $41C5,Y 4181- C8 INY 4182- D0 F2 BNE $4176 4184- BD 8C C0 LDA $C08C,X 4187- 10 FB BPL $4184 4189- 19 C5 42 ORA $42C5,Y 418C- 99 C5 42 STA $42C5,Y 418F- C8 INY 4190- D0 F2 BNE $4184 ; turn off drive motor 4192- 20 AA 41 JSR $41AA 4195- 18 CLC 4196- 60 RTS 4197- 20 0B 41 JSR $410B 419A- 20 AA 41 JSR $41AA 419D- 38 SEC 419E- 60 RTS Execution continues at $40C6: ; if nibble check failed to find ; T21,S0F then just bail 40C6- B0 2D BCS $40F5 ; more checks on the nibbles we read ; after T21,S0F 40C8- AD 20 43 LDA $4320 40CB- C9 99 CMP #$99 40CD- D0 26 BNE $40F5 40CF- A9 59 LDA #$59 40D1- 8D 7B 41 STA $417B 40D4- 8D 89 41 STA $4189 40D7- 20 19 41 JSR $4119 40DA- A2 00 LDX #$00 40DC- A0 0F LDY #$0F 40DE- B9 20 43 LDA $4320,Y 40E1- F0 01 BEQ $40E4 40E3- E8 INX 40E4- 88 DEY 40E5- 10 F7 BPL $40DE 40E7- FE FA 40 INC $40FA,X 40EA- E0 03 CPX #$03 40EC- 90 07 BCC $40F5 ; if everything checks out, execution ; falls through to here ; $40F8 was initialized with 0 and only ; incremented once, so this decrements ; it back to 0 40EE- CE F8 40 DEC $40F8 40F1- EE F9 40 INC $40F9 40F4- 60 RTS 40F5- 60 RTS Execution continues at $4010: ; check counter set by nibble check 4010- AD F8 40 LDA $40F8 ; non-zero is bad, jump to The Badlands 4013- D0 03 BNE $4018 ; success path falls through to here -- ; jump to actual game code 4015- 4C 00 02 JMP $0200 ; The Badlands ; switch to text screen (full of ; executable code at this point) 4018- AD 51 C0 LDA $C051 ; $40F7 contains the track, and this ; prints it to the upper-left corner ; of the text screen (for debugging?) 401B- AD F7 40 LDA $40F7 401E- 4A LSR 401F- 4A LSR 4020- 4A LSR 4021- 4A LSR 4022- AA TAX 4023- BD 80 40 LDA $4080,X 4026- 8D 00 04 STA $0400 4029- AD F7 40 LDA $40F7 402C- 29 0F AND #$0F 402E- AA TAX 402F- BD 80 40 LDA $4080,X 4032- 8D 01 04 STA $0401 ; and a space -- this is all very ; intentional and deliberate and weird 4035- A9 A0 LDA #$A0 4037- 8D 02 04 STA $0402 ; now squeal 403A- 20 65 40 JSR $4065 ; now crash 403D- 00 BRK ; The Squealing routine 4065- A2 00 LDX #$00 4067- A0 00 LDY #$00 4069- EE 30 C0 INC $C030 406C- A9 FF LDA #$FF 406E- A9 FF LDA #$FF 4070- A9 FF LDA #$FF 4072- A9 FF LDA #$FF 4074- CE 30 C0 DEC $C030 4077- E8 INX 4078- D0 EF BNE $4069 407A- C8 INY 407B- C0 FF CPY #$FF 407D- 90 EA BCC $4069 407F- 60 RTS ~ Chapter 4 In Which We Take One Byte And Run Away As Fast As We Can It looks like I can just disable the branch at $4013. Changing the "BNE" to a "BIT" will give me a one byte patch: T20,S00,$13 change "D0" to "24" Quod erat liberandum. --------------------------------------- A 4am crack No. 237 ------------------EOF------------------