home *** CD-ROM | disk | FTP | other *** search
- **********************************************************
- ** XFD external decruncher for Il Scuro/Defjam! **
- ** written and © 1998 by Codetapper/Action! **
- ** **
- ** This decrunches old games crunched by Il Scuro **
- ** of Defjam. The cruncher used has a bytekiller **
- ** type address cruncher followed by a (lame) **
- ** run length encoded variant. I've called it the **
- ** $B2 RLE decruncher as the RLE flag is a byte **
- ** encoded as $b2. **
- ** **
- ** Files packed with this often require a little **
- ** disassembling to setup intena/intreq and very **
- ** occasionally a hunk of memory is further **
- ** encrypted. You'll have to disasseble the main **
- ** program to check for this. **
- ** **
- ** This was the case with Army Moves and a few **
- ** other older cracks. **
- ** **
- ** Detection is based on finding all cruncher **
- ** sections (main cruncher, $b2 RLE, jump address **
- ** info and the long 'PROG' before the data). **
- ** Sometimes it will not detect it (Arkanoid 2) **
- ** due to different ordering and the load/jump **
- ** addresses in weird locations. You'll just have **
- ** to disassemble these yourself! **
- ** **
- ** Contact me: codetapper@hotmail.com **
- ** Visit the Action HQ: http://zap.to/action/ **
- ** **
- ** Greetings to all Action members: **
- ** Tachyon, Elp, Legionary, DJ DeCreator, **
- ** Hoju, and Shastar! **
- **********************************************************
-
- INCLUDE AINCLUDE:IncDirs.i
-
- IlScuroMinLen equ $1000 ;Just a guess!
-
- SECTION SWITCH,CODE
- INCLUDE "libraries/xfdmaster.i"
-
- ; xfdForeman structure MUST be first thing in all external decrunchers
-
- Forman moveq #-1,d0 ;security
- rts
- dc.l XFDF_ID ;id
- dc.w 1 ;version
- dc.w 0
- dc.l 0,0 ;private
- dc.l S_IlScuro ;first slave
-
- dc.b "$VER: IlScuro 1.3 (25.07.1999) by Codetapper/Action!",13,10,0
- cnop 0,4
-
- ;---------------------------------------------------------
- ; Files packed by Il Scuro/Defjam.
- ;
- ; Decruncher is the same, and "PROG" is located just
- ; before the crunched data. This is sometimes moved
- ; around or encrypted over itself. Then it is often
- ; RLE data so a further decrunch is required!
- ;---------------------------------------------------------
- ; xfdSlave structure
-
- S_IlScuro
- dc.l 0 ;next slave
- dc.w 2 ;version
- dc.w 36 ;master version
- dc.l N_IlScuro ;name
- dc.w XFDPFF_ADDR ;flags
- dc.w 0
- dc.l RB_IlScuro ;recog buffer
- dc.l DB_IlScuro ;decrunch buffer
- dc.l 0 ;recog segment
- dc.l 0 ;decrunch segment
- dc.w 0,0 ;slave/replace id
- dc.l IlScuroMinLen ;min. file length for header and data
-
- N_IlScuro
- dc.b 'Il Scuro/Defjam Compacted',0
- even
-
- ;---------------------------------------------------------
- ; Recog buffer function: receives buffer + length in a0/d0
- ;
- ; Returns:
- ; d0 = 1 if Il Scuro file, 0 if not!
- ; d2 = Offset into file for crunched data
- ; d3 = RLE destination address
- ; d4 = Jump address
- ; d5 = Destination address
- ; d6 = Crunched RLE length
- ;---------------------------------------------------------
-
- RB_IlScuro MOVE.L D7,-(A7)
- MOVE.L D0,D7
- BEQ.B .SkipSave1
- MOVEM.L D2-D6,-(A7)
- .SkipSave1
- move.l a0,a1 ;a1 = Start of file
- .1 move.l a0,d1
- sub.l a1,d1
- cmp.l #IlScuroMinLen,d1
- bgt .NoIlScuro ;Too far into file for a match so quit!
- cmp.w #$41fa,(a0)+ ;lea PackedData(pc),a0
- bne.b .1
- move.l a0,d1
- sub.l a1,d1
- moveq #0,d2
- move.w (a0)+,d2 ;d2 = Offset into file for crunched data
- add.l d1,d2
- cmp.w #$d1fc,(a0)+ ;add.l #$CrunchedLength,a0
- bne.b .1
- move.l (a0)+,d1
- add.l d1,d2 ;This cruncher expects data at the end!
- cmp.w #$43f9,(a0)+ ;lea #$DestinationAddress,a1
- bne.b .1
- move.l (a0)+,d3 ;d3 = RLE destination address
- cmp.w #$2460,(a0)+ ;move.l -(a0),a2
- bne.b .1
- cmp.w #$d5c9,(a0)+ ;add.l a1,a2
- bne.b .1
- cmp.w #$4aa0,(a0)+ ;tst.l -(a0)
- bne.b .1
- cmp.w #$2020,(a0)+ ;move.l -(a0),d0
- bne.b .1
-
- ; Check for the second part of the decruncher, which has some
- ; optional screen flashing before it.
-
- .2 move.l a0,d1
- sub.l a1,d1
- cmp.l #IlScuroMinLen,d1
- bgt .NoIlScuro ;Too far into file for a match so quit!
-
- cmp.w #$7203,(a0)+ ;moveq #3,d1
- bne.b .2
- cmp.w #$6100,(a0)+ ;bsr IlDec20
- bne.b .2
-
- ; Now check for the RLE decoder.
-
- .3 move.l a0,d1
- sub.l a1,d1
- cmp.l #IlScuroMinLen,d1
- bgt.b .NoIlScuro ;Too far into file for a match so quit!
- cmp.w #$4ef9,(a0)+ ;jmp StartAddress
- bne.b .3
- move.l (a0)+,d4 ;d4 = Jump address
- cmp.w #$45f9,(a0)+ ;lea $RLECrunchedAddress,a2
- bne.b .3
- addq #4,a0
- cmp.w #$47f9,(a0)+ ;lea $DestinationAddress,a3
- bne.b .3
- move.l (a0)+,d5 ;d5 = Destination address
- cmp.l #$c1200b2,(a0)+ ;cmp.b #$B2,(a2)
- bne.b .3
- cmp.l #$67000008,(a0)+ ;beq B2Found
- bne.b .3
- cmp.w #$16da,(a0)+ ;move.b (a2)+,(a3)+
- bne.b .3
- cmp.l #$6000fff4,(a0)+ ;bra CheckRLE
- bne.b .3
- cmp.w #$528a,(a0)+ ;addq.l #1,a2
- bne.b .3
- cmp.l #$c120001,(a0)+ ;cmp.b #1,(a2)
- bne.b .3
- cmp.l #$66000004,(a0)+ ;bne CheckJustB2
- bne.b .3
- cmp.w #$4e75,(a0)+ ;rts
- bne.b .3
- cmp.l #$c120000,(a0)+ ;cmp.b #0,(a2)
- bne.b .3
-
- ; Now for the final check, locate "PROG" in the data.
-
- .4 move.l a0,d1
- sub.l a1,d1
- cmp.l #IlScuroMinLen,d1
- bgt.b .NoIlScuro ;Too far into file for a match so quit!
- cmp.w #'PR',(a0)+ ;Search for 'PROG'
- bne.b .4
- cmp.w #'OG',(a0)+
- bne.b .4
-
- moveq #1,d0 ;We'll quit here, it matches!
- bra.b .end
-
- .NoIlScuro
- moveq #0,d0 ;No match for this data.
- .end TST.L D7
- BEQ.B .SkipSave2
- MOVEM.L (A7)+,D2-D6
- .SkipSave2 MOVE.L (A7)+,D7
- RTS
-
- ;---------------------------------------------------------
- ; Decrunch buffer function: receives bufferinfo in a0
- ;---------------------------------------------------------
- DB_IlScuro
- movem.l d2-d7/a2-a6,-(a7)
- move.l a0,a5
- move.l xfdbi_SourceBuffer(a5),a2
-
- ; It's impossible to calculate the correct decrunched
- ; length without actually passing through the file
- ; twice. We'll just allocate the full 512k of his old
- ; cracks. In about 20 games I've never seen one which
- ; was more than 512k so this should be OK.
-
- move.l #$80000,d0
- move.l d0,xfdbi_TargetBufSaveLen(a5)
- move.l d0,xfdbi_TargetBufLen(a5)
-
- move.l xfdbi_TargetBufMemType(a5),d1
- move.l 4.w,a6
- jsr -198(a6)
- move.w #XFDERR_NOMEMORY,xfdbi_Error(a5)
- move.l d0,xfdbi_TargetBuffer(a5)
- beq.b .Exit
-
- ; Let's fill the buffer!
-
- move.l xfdbi_SourceBuffer(a5),a0
- CLR.L D0 * indicate to ignore register saves!
- BSR RB_IlScuro ; d2 = Offset into file for crunched data
- ; d3 = RLE destination address
- ; d4 = Jump address
- ; d5 = Destination address
- ; d6 = Crunched RLE length
- tst.l d0
- beq.b .Exit
-
- move.l d5,xfdbi_DecrAddress(a5)
- move.l d4,xfdbi_JmpAddress(a5)
-
- move.l xfdbi_SourceBuffer(a5),a0
- add.l d2,a0
-
- move.l xfdbi_TargetBuffer(a5),a1
- add.l d3,a1
-
- ; Unpack the data (from a0 to a1)
-
- bsr.b D_IlScuro
-
- ; Unpack the $B2 RLE data (from a2 to a3)
-
- move.l xfdbi_TargetBuffer(a5),a3
- move.l a1,a2
- bsr B2RLEDecode
- move.l d0,xfdbi_TargetBufSaveLen(a5)
-
- ; Successful exit
-
- moveq #1,d0
- .Exit movem.l (a7)+,d2-d7/a2-a6
- rts
-
- ;---------------------------------------------------------
- ; Actual IlScuro decruncher
- ;
- ; Inputs:
- ; a0 = END of packed data
- ; a1 = Destination address
- ;
- ; Outputs:
- ; d0 = Uncrunched length. All other registers preserved.
- ;---------------------------------------------------------
- D_IlScuro
- movem.l a0-a6,-(a7)
- ; lea PackedData(pc),a0 ; Original source
- ; add.l #$2A0F4,a0 ; a0 = End of source
- ; lea $3DE24,a1 ; a1 = Destination address
- move.l -(a0),a2
- add.l a1,a2
- tst.l -(a0)
- move.l -(a0),d0
- IlDec1 ;move.w a2,$DFF180
- moveq #3,d1
- bsr IlDec20
- tst.w d2
- beq.s IlDec8
- cmp.w #7,d2
- bne.s IlDec4
- lsr.l #1,d0
- bne.s IlDec2
- bsr IlDec19
- IlDec2 bcc.s IlDec3
- moveq #10,d1
- bsr IlDec20
- tst.w d2
- bne.s IlDec4
- moveq #$12,d1
- bsr IlDec20
- bra.s IlDec4
-
- IlDec3 moveq #4,d1
- bsr IlDec20
- addq.w #7,d2
- IlDec4 subq.w #1,d2
- IlDec5 moveq #7,d1
- IlDec6 lsr.l #1,d0
- beq.s IlDec7
- roxl.l #1,d3
- dbra d1,IlDec6
-
- move.b d3,-(a2)
- dbra d2,IlDec5
-
- bra.s IlDec8
-
- IlDec7 move.l -(a0),d0
- move #$10,CCR
- roxr.l #1,d0
- roxl.l #1,d3
- dbra d1,IlDec6
-
- move.b d3,-(a2)
- dbra d2,IlDec5
-
- IlDec8 cmp.l a2,a1
- bge.s IlDec18
- moveq #2,d1
- bsr IlDec20
- moveq #2,d3
- moveq #8,d1
- tst.w d2
- beq.s IlDec16
- moveq #4,d3
- cmp.w #2,d2
- beq.s IlDec13
- moveq #3,d3
- cmp.w #1,d2
- beq.s IlDec11
- moveq #2,d1
- bsr.s IlDec20
- cmp.w #3,d2
- beq.s IlDec10
- cmp.w #2,d2
- beq.s IlDec9
- addq.w #5,d2
- move.w d2,d3
- bra.s IlDec13
-
- IlDec9 moveq #2,d1
- bsr.s IlDec20
- addq.w #7,d2
- move.w d2,d3
- bra.s IlDec13
-
- IlDec10 moveq #8,d1
- bsr.s IlDec20
- move.w d2,d3
- bra.s IlDec13
-
- IlDec11 moveq #8,d1
- lsr.l #1,d0
- bne.s IlDec12
- bsr.s IlDec19
- IlDec12 bcs.s IlDec16
- moveq #14,d1
- bra.s IlDec16
-
- IlDec13 moveq #$10,d1
- lsr.l #1,d0
- bne.s IlDec14
- bsr.s IlDec19
- IlDec14 bcc.s IlDec16
- moveq #8,d1
- lsr.l #1,d0
- bne.s IlDec15
- bsr.s IlDec19
- IlDec15 bcs.s IlDec16
- moveq #12,d1
- IlDec16 bsr.s IlDec20
- subq.w #1,d3
- IlDec17 move.b -1(a2,d2.l),-(a2)
- dbra d3,IlDec17
-
- cmp.l a2,a1
- blt IlDec1
- IlDec18 movem.l (a7)+,a0-a6
- rts
-
- IlDec19 move.l -(a0),d0
- move #$10,CCR
- roxr.l #1,d0
- rts
-
- IlDec20 subq.w #1,d1
- clr.l d2
- IlDec21 lsr.l #1,d0
- beq.s IlDec22
- roxl.l #1,d2
- dbra d1,IlDec21
-
- rts
-
- IlDec22 move.l -(a0),d0
- move #$10,CCR
- roxr.l #1,d0
- roxl.l #1,d2
- dbra d1,IlDec21
-
- rts
-
- ;---------------------------------------------------------
- ; $B2 RLE Decoder as used by Il Scuro/Defjam
- ;
- ; Inputs:
- ; a2 = Source address
- ; a3 = Destination address
- ;
- ; Outputs:
- ; d0 = Uncrunched length. All other registers preserved.
- ;---------------------------------------------------------
-
- B2RLEDecode
- movem.l d7/a2-a3,-(a7)
- CheckRLE
- cmp.b #$b2,(a2)
- beq.b B2Found
- move.b (a2)+,(a3)+
- bra.b CheckRLE
-
- B2Found addq.l #1,a2
- cmp.b #1,(a2)
- bne.b CheckJustB2
-
- move.l a3,d0 ;a3 = End of unpacked data
- movem.l (a7)+,d7/a2-a3
- sub.l a3,d0
- ; subq #1,d0 ;d0 = Uncrunched length
- rts
-
- CheckJustB2 tst.b (a2)
- bne.b CopyXBytes
- move.b #$b2,(a3)+
- addq.l #1,a2
- bra.b CheckRLE
-
- CopyXBytes move.b (a2)+,d7
- CopyLoop move.b (a2),(a3)+
- subq.b #1,d7
- bne.b CopyLoop
- addq.l #1,a2
- bra.b CheckRLE
-
- END
-