home *** CD-ROM | disk | FTP | other *** search
- ; Unpacks EXEPACKed files. Uses MS embedded unpacker, after installing a few
- ; position independant patches in it (to make it build the relocation table).
- ; Note that the EXEPACK process round the image size to paragraph boundaries,
- ; i e EXEPACK + UNEXEPAC may add up to 15 pad bytes at the file end.
-
- ; Released to the Public Domain by Dan Norstedt 1991
-
- ; Version 1.0
-
- ; Build by: MASM UNEXEPAC;
- ; LINK UNEXEPAC;
- ; EXE2BIN UNEXEPAC UNEXEPAC.COM
-
- CODE SEGMENT PUBLIC
- ASSUME CS:CODE,DS:CODE
-
- ORG 100H
-
- START: CLD
- MOV DI,Offset ZERBUF
- XOR AX,AX
- MOV CH,1
- REP STOSW ; Set up a pad block (for reloc table)
- CMP Byte Ptr DS:[5DH],20H ; Any argument?
- JZ READIN
- MOV DX,Offset USETXT ; Display usage text
- JMP OUTMSG
- USETXT DB "Usage: UNEXEPAC <packedfile.EXE >unpacked.EXE$"
-
- WRKSTK:
-
- OUTMS2: JMP OUTMSG
-
- READNX: MOV AX,DS
- ADD AX,0F80H
- MOV DS,AX ; Adjust to next buffer
- SUB AX,Word Ptr CS:[2] ; Overflow?
- MOV DX,Offset TOOTXT
- JAE OUTMS2
- MOV CX,AX ; No, how much more can we read in?
- SHL CX,1
- SHL CX,1
- SHL CX,1
- SHL CX,1
- CMP AX,0F80H ; Has CX a valid value < F800
- JB READIX ; Yes, use it
- READIN: MOV CX,0F800H ; Set up maximum read in chunk size
- READIX: MOV SP,Offset WRKSTK ; Change stack to safe place:init code
- MOV AH,3FH
- XOR BX,BX
- MOV DX,Offset BUFFER ; Read in data
- INT 21H
- MOV DX,Offset REATXT
- JC OUTMS2
- CMP AX,CX ; Got all we asked for?
- JZ READNX ; Yes, try to get more
- MOV AX,CS
- ADD AX,Word Ptr CS:[BUFFER+08H] ; Get load image offset (PARA)
- ADD AX,(Offset BUFFER-Offset START+100H)/10H-10H ; Buffer offset
- MOV ES,AX ; Save faked PSP paragraph
- ADD AX,10H
- MOV Word Ptr CS:[EXEBASE],AX ; Save load image offset
- ADD AX,Word Ptr CS:[BUFFER+16H]
- MOV DS,AX ; Save faked CS
- MOV SI,Word Ptr CS:[BUFFER+14H] ; Get faked IP
- CMP Word Ptr [SI-2],"BR" ; Check for EXEPACK signature
- MOV DX,Offset NOPTXT
- JNZ OUTMSG ; Isn't EXEPACKed, tell user
- CMP Word Ptr CS:[BUFFER+06H],0 ; Any relocation entries?
- JNZ OUTMSG ; Yes, we can't handle it
- CLD
- MOV CX,100H ; Patch exe unpacker code
- FINDEX: LODSB
- CMP AL,03H ; Find code where exe unpacker
- LOOPNZ FINDEX ; is about to transfer control
- CMP Word Ptr [SI],01F0H ; to the now unpacked program
- LOOPNZ FINDEX
- JNZ OUTMSG
- MOV Byte Ptr [SI-1],0EAH ; Replace it by a JMP Far
- MOV Word Ptr [SI],Offset UNPDON ; straight to our own code
- LODSW
- MOV Word Ptr [SI],CS
- MOV Byte Ptr [SI+2],9AH ; Use overflow to a CALL Far
- MOV Word Ptr [SI+3],Offset WRIREL ; island to our reloc table
- MOV Word Ptr [SI+5],CS ; write routine
- MOV Byte Ptr [SI+7],0C3H ; RET Near
- MOV BX,SI ; Save call island offset
- MOV SI,Word Ptr CS:[BUFFER+14H] ; Reload exe unpacker offset
- MOV CX,100H
- FINDRE: LODSB
- CMP AL,26H ; Look for ADD ES:[DI],DX
- FINDRX: LOOPNZ FINDRE
- JCXZ GOAHEA
- CMP Word Ptr [SI],1D01H
- JNZ FINDRX
- MOV Byte Ptr [SI-1],0E8H ; Replace it to CALL Near to
- SUB BX,SI ; our call island
- MOV [SI],BX
- ADD BX,SI
- JMP Short FINDRX ; Repeat; there may be more
-
- WERROR: MOV DX,Offset WRITXT
- OUTMSG: MOV AH,9
- PUSH CS
- POP DS
- INT 21H ; Write error message
- MOV AX,4C01H
- INT 21H
-
- GOAHEA PROC FAR ; Declare for RET Far at end
- MOV AH,40H
- MOV BX,1
- MOV CX,1CH ; Write exe header template:
- XOR DX,DX ; Fill in real values later
- INT 21H
- JC WERROR
- PUSH DS
- PUSH Word Ptr CS:[BUFFER+14H] ; Jump to MS exe unpacker
- PUSH ES
- POP DS ; DS and ES set up as expected
- RET ; SS and SP is our stack but
- GOAHEA ENDP ; the unpacker doesn't care
-
- WRIREL PROC FAR
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DS
- MOV AX,ES ; Compute real value
- SUB AX,Word Ptr CS:[EXEBASE]
- PUSH AX ; Save reloc segment value
- PUSH DI ; Save reloc offset value
- MOV AH,40H
- MOV BX,1
- MOV CX,4
- MOV DX,SP
- PUSH SS
- POP DS
- INT 21H ; Write reloc entry to file
- WERRO2: JC WERROR
- INC Word Ptr CS:[BUFFER+06H] ; Increment reloc entry count
- POP AX
- POP AX
- POP DS
- POP DX
- POP CX
- POP BX
- POP AX
- RET
- WRIREL ENDP
-
- UNPDON: MOV BP,DS ; Save minimum allocation
- LES AX,Dword Ptr DS:[0] ; Get CS:IP
- PUSH CS
- POP DS ; Restore our DS
- MOV Word Ptr DS:[BUFFER+0EH],SI ; Save SS
- MOV Word Ptr DS:[BUFFER+10H],DI ; Save SP
- MOV Word Ptr DS:[BUFFER+14H],AX ; Save IP
- MOV Word Ptr DS:[BUFFER+16H],ES ; Save CS
- MOV DX,4
- MOV AX,7H
- ADD AX,Word Ptr CS:[BUFFER+06H] ; Compute size written so far
- MUL DX
- MOV CX,AX
- NEG CX
- AND CH,1 ; Compute needed pad MOD 512
- ADD AX,CX ; Compute size after padding
- ADC DX,0
- SHR DX,1 ; Convert it to paragraphs
- RCR AX,1
- SHR DX,1
- RCR AX,1
- SHR DX,1
- RCR AX,1
- SHR DX,1
- RCR AX,1
- PUSH AX
- MOV DX,Offset ZERBUF
- MOV AH,40H
- MOV BX,1
- AND CX,CX
- JZ NORADJ
- INT 21H ; Write pad bytes
- JC WERRO2
- NORADJ: POP BX
- XCHG Word Ptr DS:[BUFFER+08H],BX ; Save padded size, paragraphs
- MOV DX,Offset BUFFER ; (BX now image offse, para)
- MOV SI,DS
- LEA SI,[SI+BX+(Offset BUFFER-Offset START+100H)/10H] ; Image, para
- MOV AX,Word Ptr DS:[BUFFER+02H]
- DEC AX ; Compute original size
- AND AX,1FFH
- SHR AX,1
- SHR AX,1
- SHR AX,1
- SHR AX,1
- MOV DX,Word Ptr DS:[BUFFER+04H]
- SHL DX,1
- SHL DX,1
- SHL DX,1
- SHL DX,1
- SHL DX,1
- ADD AX,DX
- SUB AX,20H-1
- SUB AX,BX
- MOV DS,SI
- NEG SI
- LEA SI,[SI+BP]
- SUB AX,SI
- ADD Word Ptr CS:[BUFFER+0AH],AX ; New min allocation value
- CMP Word Ptr CS:[BUFFER+0CH],0FFFFH ; Old max alloc = -1?
- JZ ALLMAX
- ADD Word Ptr CS:[BUFFER+0CH],AX ; No, compute new max alloc
- ALLMAX: MOV AX,SI ; Recompute file size
- SHL AL,1
- SHL AL,1
- SHL AL,1
- MOV AH,0
- SHL AX,1
- MOV Word Ptr CS:[BUFFER+02H],AX ; Save size MOD 512
- MOV AX,SI ; Get image size
- ADD AX,Word Ptr CS:[BUFFER+08H] ; Get reloc size (= 0 MOD 512)
- SHR AX,1
- SHR AX,1
- SHR AX,1
- SHR AX,1
- SHR AX,1
- TEST SI,1FH ; = 0 MOD 512 ?
- JZ EXACBL
- INC AX ; No, add overflow "sector"
- EXACBL: MOV Word Ptr CS:[BUFFER+04H],AX ; Save "sector" count
- WRILOP: MOV CX,SI
- SHL CX,1
- SHL CX,1
- SHL CX,1
- SHL CX,1
- SUB SI,0F80H
- JB WRILEX
- MOV CX,0F800H
- WRILEX: MOV AH,40H ; Write all of image
- MOV BX,1
- XOR DX,DX
- INT 21H
- JC WERRO3
- MOV AX,DS
- ADD AX,0F80H
- MOV DS,AX
- CMP SI,0F000H
- JB WRILOP
-
- MOV AX,4200H ; Seek to beginning of file
- MOV BX,1
- XOR CX,CX
- XOR DX,DX
- INT 21H
- JC WERRO3
- PUSH CS
- POP DS
- MOV AH,40H ; Write updated exe header
- MOV BX,1
- MOV CX,1CH
- MOV Word Ptr DS:[BUFFER+18H],CX ; Fill in start of reloc table
- MOV DX,Offset BUFFER
- GOOEXI: INT 21H
- MOV AX,4C00H
- JNC GOOEXI
- WERRO3: JMP WERROR
-
- NOPTXT DB "File is not EXEpacked$"
- TOOTXT DB "Out of memory$"
- WRITXT DB "Write error$"
- REATXT DB "Read error$"
-
- EXEBASE Label Word
-
- ZERBUF EQU EXEBASE+2
-
- ORG ZERBUF+1FCH-300H
- BUFALI:
- ORG $+((Offset START-Offset BUFALI) AND 15)
-
- BUFFER EQU $+300H
-
- CODE ENDS
- END START
-