▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ░▒▓█ rapid1337.com █▓▒░ ╓──────────────────────────────────────────╖ ║ Z-Out ║ ╟──────────────────────────────────────────╢ ║ Rainbow Arts/Advantec (1990) ║ ╟──────────────────────────────────────────╢ ║ ·· security/z-out.html ·· ║ ╙──────────────────────────────────────────╜ ============================================================================ Title ..: Z-Out Author .: staff Date ...: 2008-02-12 Section : Security ============================================================================ Z-Out Rainbow Arts/Advantec (1990) – I used original disk from the IPF file #609 EU Retail – AR and/or a disassembler/debugger (not specific tuto) – an assembler (AsmOne/DevPac/Barfly…) if you want to rewrite the boot. Do a quick scan of the disk with X-Copy : something is wrong at the first track. Seems to be a disk based protection. Make a copy of disk. boot it : the screen stay black after reading the track 1. From AR, disassemble where the program is stopped (F4D6) : Compare start of sector with $4521 (MFM sync marker). cross backward : this test routine start at F4D0 and is called from F3E2 (fa f4d0) : read sector 1 at D2F6. at F408, test if read error. jump to F434 if ok. here is the routine called for reading sector (motor on, trackload…) at F56E, he jumps to F4D0 : the uncode MFM routine. It’s used as the "protection". so, reboot. stop with AR after track 49 loaded. Then, disassemble at F4D0 (d F4D0) : the code is here. first try : put RTS at F4D2 to skip the whole routine. restart (x) lets loading until track 1. …it’s Ok! Intro start ! but what is this sector. Important one ? only protection ? disassemble more : at F4D0 he decode the data from D2F6 to D396. at F448, he copy D2F6 to D396 at F45c, D2F6 is used with sub prog at F616 : seems to be a writing track routine! this game save the hiscore on disk : at sector 1 ! the hiscore is used as protection. so, for the patch, we have to nop the test of $4521 else the hiscore is not decoded. And also erase the $4521 at write sub prog (at F6Ac). put 6x 4E71 at F4D6 and 3x 4E71 at F6AC. (I’ve not tested the hiscore saving because I used winuae : unsupported format for writing) patching: I loaded and disassembled the starter program – 44 block loaded @ 50000 from block 22. It’s the main program crunched. Starting at 50024, decrunch it to 40000, then jump to 40000, copy the main program at 0 and jump to 500 to start. The program load some files and load Intro at B000. the "protection" is in the Intro code. it’s possible to patch directly from boot : after loading prog at 50000, change boot ... ``` move.w #$4e75,$5012a ; replace JMP $40000 by RTS jsr $50024 ; replace JMP by JSR : decrunch to 40000 and return here ``` after this line, we have to install the patch of the Intro, but not yet loaded at this moment…patch copied at free space $b8. ``` lea $b8.w,a0 move.l a0,$40100+$5DA ; replace JSR $B000 by JSR $B8 ``` I use $40100 as base, because it’s the part of the prog copied at 0. and I copy the patch at $40100+$b8…the patch will be at $b8! lea patchintro(pc),a1 ; copy patch to $b8 (unused address) ``` lea $40100+$b8,a0 moveq #sizepatch-1,d7 ``` .cpy ``` move.b (a1)+,(a0)+ ``` dbf d7,.cpy ``` jmp $40000 ; copy prog to $500 and start ``` here is the patch: patchintro: ; skip test $4521 ``` move.l #$4e714e71,$f4d6 move.l #$4e714e71,$f4da move.l #$4e714e71,$f4de ``` ; skip $4521 in write score ``` move.l #$4e714e71,$f6ac move.w #$4e71,$f6b0 ``` ``` jmp $B000 ; start Intro ``` sizepatch=*-patchintro write new boot and restart : the loading is ok! Start game, play. Quit game (Esc) : program jump to Intro (read hiscore – track 1) that works. You can test the whole game by using builtin trainer : J+1 to 6 for level, J+K for invulnerability. to fix the hiscore save, try to replace sync word $4521 with standard one : $4489 new patch: ... ``` move.w #$4e71,$f4da move.w #$4e71,$f4e0 move.w #$4489,$f488 move.l #$44894489,$f6ae jmp $B000 ``` (not tested on real amiga. doesnt work on winuae) ———————- Original game have some bugs. why not fix them now ? – first bug : the Intro logo is not centered ! incredible! lets go with AR: take a look at the copperlist intro : c1 the logo is at the bottom of screen/copperlist. found at BD40 : $e0,$2,$e2,$3e84,… bitplan pointer for logo. a shift of 128 pixels (16 bytes – $10) : add $10 to values of bplxpt : 3e84 -> 3e94 … try : it’s ok! is this address directly in copperlist or from a pointer? searching BD40 : nothing. searching BD42 : found at C492.(or searching $23e84 – fa 23e84 : found at bd83). The logo pointer is at BD80 so, add the fix to the patchintro: ... ``` move.l #$23e94,$bd80 ; $23e84 -> $23e94 ``` ... reboot, and enjoy. others bugs are found by crackers or whdload patchers: fixes for the main program ($40000) – problem with weapons in 2 players mode : fixed by Angels/Defjam ``` move.b #$14,$40100+$3E5A ; clr.w $12(a3) -> clr.w $14(a3) move.b #$14,$40100+$3E60 ; addq.w #1,$12(a3) -> addq.w #1,$14(a3) ``` – gfx bug in level 5 : fixed by Harry/WHDteam ``` move.b #$20,$40100+$7C34 ; copperlist wait $4000 -> $2000 ``` – trainer keys J+K replaced by J+I (pb with a2000/4000 keyboard): by WHD patchers (Jotd/Harry) ``` move.b #$17,$40100+$1A9B ; replace keycode "K" by "I" ``` final boot code : dc.b 'DOS',0 dc.l 0 dc.l $370 ; original code Start ``` move.w #$180,$DFF096 clr.w $DFF180 move.l a1,-(sp) ``` lea loc_0_400AA(pc),a5 movea.l 4.w,a6 ``` move.l #$20004,d1 ``` jsr -$D8(a6) ; availmem(req)(d1) ``` move.l d0,4(a5) move.l #4,d1 ``` jsr -$C6(a6) ; allocmem(size,req)(d0,d1) add.l d0,4(a5) ``` clr.w d0 move.l d0,(a5) ``` movea.l (sp)+,a1 ``` move.w #2,$1C(a1) move.l #$50000,$28(a1) ; load crunched main program move.l #44*512,$24(a1) ; len: 44*512 move.l #22*512,$2C(a1) ; offset: 22*512 ``` jsr -$1C8(a6) ``` move.w #9,$1C(a1) clr.l $24(a1) ``` jsr -$1C8(a6) ``` move.w #$7FFF,$DFF09A move.w #$7FFF,$DFF096 movem.l d0-a6,-(sp) ``` nop nop nop ``` movem.l (sp)+,d0-a6 move.l 0(a5),d0 ; ptAllocMem C00000 move.l 4(a5),d1 ; ptAvailMem+ptAllocMem C7E800 ``` ; patch ``` move.w #$4e75,$5012a ; replace JMP $40000 by RTS jsr $50024 ; decrunch to 40000 and return here ``` ; patch 40000 main prog ; trainer key j+k replaced by j+i (pb with a2000/4000 keyboard) ``` move.b #$17,$40100+$1A9B ; replace keycode "K" by "I" ``` ; fix weapons in 2 players mode (by Angels/Defjam) ``` move.b #$14,$40100+$3E5A ; clr.w $12(a3) -> clr.w $14(a3) move.b #$14,$40100+$3E60 ; addq.w #1,$12(a3) -> addq.w #1,$14(a3) ``` ; gfx bug in level 5 ``` move.b #$20,$40100+$7C34 ; copperlist wait $4000 -> $2000 ``` ; install patch Intro ``` movem.l d7/a0-a1,-(sp) lea $b8.w,a0 move.l a0,$40100+$5DA ; replace JSR $B000.L by JSR $B8.w ``` lea patchintro(pc),a1 ; copy patch to $b8 (unused address) ``` lea $40100+$b8,a0 moveq #sizep-1,d7 ``` .cpy ``` move.b (a1)+,(a0)+ ``` dbf d7,.cpy ``` movem.l (sp)+,d7/a0-a1 ``` ``` jmp $40000 ; copy prog to $500 and start ``` patchintro: ; correct centering of Advantec logo ``` move.l #$23e94,$bd80 ; $23e84 -> $23e94 ``` ; skip test sync word ``` move.l #$4e714e71,$f4d6 move.l #$4e714e71,$f4da move.l #$4e714e71,$f4de ``` ; or skip only bne/beq ; move.w #$4e71,$f4da ; move.w #$4e71,$f4e0 ; move.w #$4489,$f488 ; standard sync word ; skip write score sync word ``` move.l #$4e714e71,$f6ac move.w #$4e71,$f6b0 ``` ; or put standard sync word ; move.l #$44894489,$f6ae ``` jmp $B000 ``` sizep=*-patchintro loc_0_400AA: ds.l 2 that’s all ---------------------------------------------------------------------------- -- rapid1337.com -- The dumping ground for all things tech // knowledge is the weapon --