1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

dos/exe: migrated to ElfLinker

This commit is contained in:
László Molnár 2006-06-29 00:44:12 +02:00
parent 455329a745
commit e9a851c0d4
9 changed files with 1768 additions and 406 deletions

View File

@ -31,6 +31,7 @@
#include "filter.h"
#include "packer.h"
#include "p_exe.h"
#include "linker.h"
static const
#include "stub/i086-dos16.exe.h"
@ -125,7 +126,7 @@ int PackExe::buildLoader(const Filter *)
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
"NRV2BEX3",
ph.c_len > 0xffff ? "N2B64K02" : "",
"NRV2BEX9,NRV2B16E",
"NRV2BEX9",
NULL
);
else if (ph.method == M_NRV2D_8)
@ -137,7 +138,7 @@ int PackExe::buildLoader(const Filter *)
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
"NRV2DEX3",
ph.c_len > 0xffff ? "N2D64K02" : "",
"NRV2DEX9,NRV2D16E",
"NRV2DEX9",
NULL
);
else if (ph.method == M_NRV2E_8)
@ -149,7 +150,7 @@ int PackExe::buildLoader(const Filter *)
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
"NRV2EEX3",
ph.c_len > 0xffff ? "N2E64K02" : "",
"NRV2EEX9,NRV2E16E",
"NRV2EEX9",
NULL
);
else
@ -481,67 +482,55 @@ void PackExe::pack(OutputFile *fo)
}
extra_info[eisize++] = (unsigned char) flag;
linker->defineSymbol("original_cs", ih.cs);
linker->defineSymbol("original_ip", ih.ip);
linker->defineSymbol("original_sp", ih.sp);
linker->defineSymbol("original_ss", ih.ss);
linker->defineSymbol("reloc_size",
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
>= relocsize ? 0 : MAXRELOCS) - relocsize);
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
// patch loader
if (flag & USEJUMP)
{
// I use a relocation entry to set the original cs
unsigned n = find_le32(loader,lsize,get_le32("IPCS"));
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
n += packedsize + 2;
oh.relocs = 1;
oh.firstreloc = (n&0xf) + ((n>>4)<<16);
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
}
else
{
patch_le16(loader,lsize,"IP",ih.ip);
if (ih.cs)
patch_le16(loader,lsize,"CS",ih.cs);
oh.relocs = 0;
oh.firstreloc = ih.cs*0x10000 + ih.ip;
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
}
// g++ 3.1 does not like the following line...
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
if (flag & SP)
patch_le16(loader,lsize,"SP",ih.sp);
if (flag & SS)
patch_le16(loader,lsize,"SS",ih.ss);
if (relocsize)
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
linker->defineSymbol("copy_offset", firstcopy - 2);
linker->defineSymbol("words_to_copy",firstcopy / 2);
patchPackHeader(loader,e_len);
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
unsigned destpara = oh.ss - ph.c_len/16;
patch_le16(loader,e_len,"ES",destpara-e_len/16);
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
patch_le16(loader,e_len,"SI",firstcopy-2);
patch_le16(loader,e_len,"CX",firstcopy/2);
// finish --stub support
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
// throwCantPack("FIXME");
linker->defineSymbol("exe_stack_sp", oh.sp);
linker->defineSymbol("exe_stack_ss", oh.ss);
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
linker->defineSymbol("attribute", get_le16(ibuf + 4));
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
oh.m512 = outputlen & 511;
oh.p512 = (outputlen + 511) >> 9;
oh.ip = 0;
if (device_driver)
{
patch_le16(loader, e_len, "OP", oh.sp);
patch_le16(loader, e_len, "OS", oh.ss);
// copy .sys header
memcpy(loader + 4, ibuf + 4, 2);
memcpy(loader + 8, ibuf + 8, 2);
// copy original strategy
memcpy(loader + 10, ibuf + 6, 2);
oh.ip = getLoaderSection("EXEENTRY") - 2;
}
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0;
linker->relocate();
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader,e_len);
//fprintf(stderr,"\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
@ -717,6 +706,12 @@ void PackExe::unpack(OutputFile *fo)
}
Linker* PackExe::newLinker() const
{
return new ElfLinker();
}
/*
vi:ts=4:et
*/

View File

@ -69,6 +69,7 @@ protected:
virtual int fillExeHeader(struct exe_header_t *) const;
virtual int buildLoader(const Filter *ft);
virtual Linker* newLinker() const;
struct exe_header_t
{

View File

@ -263,9 +263,8 @@ i086-dos16.com.h : $(srcdir)/src/$$T.asm
i086-dos16.exe% : tc_list = i086 default
i086-dos16.exe.h : $(srcdir)/src/$$T.asm
$(call tc,pp-nasm) --MMD=$@ $< -o tmp/$T.tmp1
$(call tc,app-nasm) tmp/$T.tmp1 tmp/$T.tmp2
$(call tc,nasm) -f bin -l tmp/$T.bin.lst tmp/$T.tmp2 -o tmp/$T.bin
gcc -c -x assembler-with-cpp $< -o tmp/$T.bin
objdump -trwh tmp/$T.bin >> tmp/$T.bin
$(call tc,bin2h) --ident=nrv_loader tmp/$T.bin $@

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
/*
; n2b_d8e.ash -- ucl_nrv2b_decompress_8 in 16-bit assembly (dos/exe)
;
; This file is part of the UCL data compression library.
@ -35,19 +36,11 @@
; cx = 0
; bx = 0x800F
; bp = 1
*/
CPU 8086
%ifndef jmps
%define jmps jmp short
%endif
%ifndef jmpn
%define jmpn jmp near
%endif
CPU 8086
; __NRV2B16S__
section NRV2B16S
literal_n2b:
movsb
decompr_start_n2b:
@ -58,31 +51,31 @@ dec1_n2b:
jc literal_n2b
inc cx
mov ax, es
%ifdef __N2B64K01__
section N2B64K01
add di, di
jnc di_ok_n2b
add ah, 8
mov es, ax
di_ok_n2b:
shr di, 1
%endif; __NRV2BEX1__
section NRV2BEX1
offset_loop_n2b:
call getbit_cx_n2b
jcxz decomp_done_n2b
jnc offset_loop_n2b
dec cx
dec cx
jz offset_ok_n2b
%ifdef __N2BX8601__
jzs offset_ok_n2b
section N2BX8601
add cx, cx
add cx, cx
add cx, cx
add cx, cx
%else; __N2B28601__
CPU 286
section N2B28601
CPU 286
shl cx, 4
CPU 8086
%endif; __NRV2BEX2__
CPU 8086
section NRV2BEX2
mov bp, cx
mov bl, [si]
inc si
@ -100,7 +93,7 @@ length_loop_n2b:
inc cx
copy_match_n2b:
cmp bp, 0xd1
sbb cx, byte -2
sbb cx, -2
sub ax, bp
jb handle_underflow_n2b
@ -115,7 +108,7 @@ ds_ok_n2b:
mov ds, dx
jmps decompr_start_n2b
handle_underflow_n2b:
%ifdef __N2BX8602__
section N2BX8602
shl ax, 1
shl ax, 1
shl ax, 1
@ -124,13 +117,13 @@ handle_underflow_n2b:
xor ax, ax
mov ds, ax
pop ax
%else; __N2B28602__
CPU 286
section N2B28602
CPU 286
shl ax, 4
push byte 0
push 0
pop ds
CPU 8086
%endif; __NRV2BEX3__
CPU 8086
section NRV2BEX3
add ax, bx
add ax, di
jmps ds_ok_n2b
@ -142,26 +135,22 @@ gb2_n2b:
adc cx, cx
getbit_n2b:
add bh, bh
jnz f2_n2b
jnzs f2_n2b
reloadbh_n2b:
mov bh, [si]
%ifdef __N2B64K02__
section N2B64K02
adc si, si
jnc si_ok_n2b
add dh, 8
mov ds, dx
si_ok_n2b:
shr si, 1
%endif; __NRV2BEX9__
section NRV2BEX9
inc si
adc bh, bh
f2_n2b:
ret
decomp_done_n2b:
; __NRV2B16E__
CPU 8086
; vi:ts=8:et
/* vi:ts=8:et */

View File

@ -1,3 +1,4 @@
/*
; n2d_d8e.ash -- ucl_nrv2d_decompress_8 in 16-bit assembly (dos/exe)
;
; This file is part of the UCL data compression library.
@ -35,19 +36,11 @@
; cx = 0
; bx = 0x800F
; bp = 1
*/
CPU 8086
%ifndef jmps
%define jmps jmp short
%endif
%ifndef jmpn
%define jmpn jmp near
%endif
CPU 8086
; __NRV2D16S__
section NRV2D16S
literal_n2d:
movsb
decompr_start_n2d:
@ -58,14 +51,14 @@ dec1_n2d:
jc literal_n2d
inc cx
mov ax, es
%ifdef __N2D64K01__
section N2D64K01
add di, di
jnc di_ok_n2d
add ah, 8
mov es, ax
di_ok_n2d:
shr di, 1
%endif; __NRV2DEX1__
section NRV2DEX1
offset_loop_n2d:
call getbit_cx_n2d
jc offset_loopend_n2d
@ -78,16 +71,16 @@ offset_loop_n2d:
offset_loopend_n2d:
dec cx
dec cx
jz offset_ok_n2d
%ifdef __N2DX8601__
jzs offset_ok_n2d
section N2DX8601
add cx, cx
add cx, cx
add cx, cx
%else; __N2D28601__
CPU 286
section N2D28601
CPU 286
shl cx, 3
CPU 8086
%endif; __NRV2DEX2__
CPU 8086
section NRV2DEX2
mov bp, cx
mov bl, [si]
inc si
@ -109,8 +102,8 @@ length_loop_n2d:
inc cx
inc cx
copy_match_n2d:
cmp bp, byte 0x51
sbb cx, byte -2
cmp bp, 0x51
sbb cx, -2
sub ax, bp
jb handle_underflow_n2d
@ -125,7 +118,7 @@ ds_ok_n2d:
mov ds, dx
jmps decompr_start_n2d
handle_underflow_n2d:
%ifdef __N2DX8602__
section N2DX8602
shl ax, 1
shl ax, 1
shl ax, 1
@ -134,13 +127,13 @@ handle_underflow_n2d:
xor ax, ax
mov ds, ax
pop ax
%else; __N2D28602__
CPU 286
section N2D28602
CPU 286
shl ax, 4
push byte 0
push 0
pop ds
CPU 8086
%endif; __NRV2DEX3__
CPU 8086
section NRV2DEX3
add ax, bx
add ax, di
jmps ds_ok_n2d
@ -152,26 +145,22 @@ gb2_n2d:
adc cx, cx
getbit_n2d:
add bh, bh
jnz f2_n2d
jnzs f2_n2d
reloadbh_n2d:
mov bh, [si]
%ifdef __N2D64K02__
section N2D64K02
adc si, si
jnc si_ok_n2d
add dh, 8
mov ds, dx
si_ok_n2d:
shr si, 1
%endif; __NRV2DEX9__
section NRV2DEX9
inc si
adc bh, bh
f2_n2d:
ret
decomp_done_n2d:
; __NRV2D16E__
CPU 8086
; vi:ts=8:et
/* vi:ts=8:et */

View File

@ -1,3 +1,4 @@
/*
; n2e_d8e.ash -- ucl_nrv2e_decompress_8 in 16-bit assembly (dos/exe)
;
; This file is part of the UCL data compression library.
@ -35,19 +36,11 @@
; cx = 0
; bx = 0x800F
; bp = 1
*/
CPU 8086
%ifndef jmps
%define jmps jmp short
%endif
%ifndef jmpn
%define jmpn jmp near
%endif
CPU 8086
; __NRV2E16S__
section NRV2E16S
literal_n2e:
movsb
decompr_start_n2e:
@ -58,14 +51,14 @@ dec1_n2e:
jc literal_n2e
inc cx
mov ax, es
%ifdef __N2E64K01__
section N2E64K01
add di, di
jnc di_ok_n2e
add ah, 8
mov es, ax
di_ok_n2e:
shr di, 1
%endif; __NRV2EEX1__
section NRV2EEX1
offset_loop_n2e:
call getbit_cx_n2e
jc offset_loopend_n2e
@ -78,16 +71,16 @@ offset_loop_n2e:
offset_loopend_n2e:
dec cx
dec cx
jz offset_ok_n2e
%ifdef __N2EX8601__
jzs offset_ok_n2e
section N2EX8601
add cx, cx
add cx, cx
add cx, cx
%else; __N2E28601__
CPU 286
section N2E28601
CPU 286
shl cx, 3
CPU 8086
%endif; __NRV2EEX2__
CPU 8086
section NRV2EEX2
mov bp, cx
mov bl, [si]
inc si
@ -113,8 +106,8 @@ length_loop_n2e:
inc cx
inc cx
copy_match_n2e:
cmp bp, byte 0x51
sbb cx, byte -3
cmp bp, 0x51
sbb cx, -3
sub ax, bp
jb handle_underflow_n2e
@ -130,7 +123,7 @@ ds_ok_n2e:
jmps decompr_start_n2e
handle_underflow_n2e:
%ifdef __N2EX8602__
section N2EX8602
shl ax, 1
shl ax, 1
shl ax, 1
@ -139,13 +132,13 @@ handle_underflow_n2e:
xor ax, ax
mov ds, ax
pop ax
%else; __N2E28602__
CPU 286
section N2E28602
CPU 286
shl ax, 4
push byte 0
push 0
pop ds
CPU 8086
%endif; __NRV2EEX3__
CPU 8086
section NRV2EEX3
add ax, bx
add ax, di
jmps ds_ok_n2e
@ -158,26 +151,21 @@ gb2_n2e:
adc cx, cx
getbit_n2e:
add bh, bh
jnz f2_n2e
jnzs f2_n2e
reloadbh_n2e:
mov bh, [si]
%ifdef __N2E64K02__
section N2E64K02
adc si, si
jnc si_ok_n2e
add dh, 8
mov ds, dx
si_ok_n2e:
shr si, 1
%endif; __NRV2EEX9__
section NRV2EEX9
inc si
adc bh, bh
f2_n2e:
ret
decomp_done_n2e:
; __NRV2E16E__
CPU 8086
; vi:ts=8:et
/* vi:ts=8:et */

View File

@ -1,3 +1,4 @@
/*
; l_exe.asm -- loader & decompressor for the dos/exe format
;
; This file is part of the UPX executable compressor.
@ -24,133 +25,121 @@
; Markus F.X.J. Oberhumer Laszlo Molnar
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
;
*/
#define EXE
#include "arch/i086/macros.ash"
%define EXE
%define jmps jmp short
%define jmpn jmp near
BITS 16
ORG 0
SECTION .text
CPU 8086
; __DEVICEENTRY__
section DEVICEENTRY
dd -1
dw 0
dw strategy ; .sys header
dw 0 ; opendos wants this field untouched
.long -1
.short attribute
.short strategy /* .sys header */
.short interrupt /* opendos wants this field untouched */
original_strategy:
dw 'ST'
.short orig_strategy
strategy:
push cs
push word [cs:original_strategy]
push [cs:original_strategy]
push ax
push bx
push cx
push dx
mov ax, cs
add ax, 'OS' ; calculate normal EXE stack
mov bx, 'OP'
add ax, offset exe_stack_ss
mov bx, offset exe_stack_sp
mov cx, ss
mov dx, sp
mov ss, ax ; switch to stack EXE normally has
mov ss, ax /* switch to stack EXE normally has */
mov sp, bx
push cx ; save device stack on EXE stack
push cx /* save device stack on EXE stack */
push dx
push si
push di
push bp
push ds
push es
db 0x72 ; "jc 0xf9" but flag C is 0 => nop
.byte 0x72 /* "jc 0xf9" but flag C is 0 => nop */
exe_as_device_entry:
stc ; flag C is 1
stc /* flag C is 1 */
pushf
; =============
; ============= ENTRY POINT
; =============
; __EXEENTRY__
/* ============= */
section EXEENTRY
exe_entry:
mov cx, 'CX' ; first_copy_len/2
mov si, 'SI' ; cx*2-2
mov cx, offset words_to_copy
mov si, offset copy_offset
mov di, si
push ds
db 0xa9
.byte 0xa9
do_copy:
mov ch, 0x80 ; 64 kbyte
mov ch, 0x80 /* 64 kbyte */
mov ax, cs
addaxds:
add ax, 'DS' ; MSB is referenced by the "sub" below
add ax, offset source_segment /* MSB is referenced by the "sub" below */
mov ds, ax
add ax, 'ES'
add ax, offset destination_segment
mov es, ax
std
rep
movsw
cld
; __DEVICESUB__
sub [byte cs:si + addaxds + 4], byte 0x10
; __EXESUB__
sub [byte cs:si + addaxds - exe_entry + 4], byte 0x10
; __JNCDOCOPY__
jnc do_copy
section DEVICESUB
subb [cs:si + addaxds + 4], 0x10
section EXESUB
subb [cs:si + addaxds - exe_entry + 4], 0x10
section JNCDOCOPY
jncs do_copy
xchg ax, dx
scasw
lodsw
%ifdef __EXERELPU__
section EXERELPU
push cs
%endif; __EXEMAIN4__
section EXEMAIN4
push cs
push cs
push es
pop ds
pop es
push ss
mov bp, 'BP' ; entry point [0x1,0x10]
mov bx, 'BX' ; 0x800F + 0x10*bp - 0x10
mov bp, offset decompressor_entry
mov bx, offset bx_magic /* 0x800F + 0x10*bp - 0x10 */
push bp
retf
lret
%include "include/header.ash"
#include "include/header2.ash"
; __EXECUTPO__
section EXECUTPO
; =============
; ============= DECOMPRESSION
; =============
#include "arch/i086/nrv2b_d8.ash"
#include "arch/i086/nrv2d_d8.ash"
#include "arch/i086/nrv2e_d8.ash"
CPU 286
%include "arch/i086/nrv2b_d8.ash"
%include "arch/i086/nrv2d_d8.ash"
%include "arch/i086/nrv2e_d8.ash"
CPU 8086
; =============
; ============= RELOCATION
; =============
; __EXEMAIN5__
section EXEMAIN5
pop bp
%ifdef __EXERELOC__
%ifdef __EXEADJUS__
/* RELOCATION */
section EXEADJUS
mov ax, es
sub ah, 0x6 ; MAXRELOCS >> 12
sub ah, 0x6 /* MAXRELOCS >> 12 */
mov ds, ax
%else; __EXENOADJ__
section EXENOADJ
push es
pop ds
%endif; __EXERELO1__
lea si, [di+'RS']
section EXERELO1
lea si, [di + reloc_size]
lodsw
pop bx
xchg ax, cx ; number of 0x01 bytes (not exactly)
xchg ax, cx /* number of 0x01 bytes (not exactly) */
lodsw
xchg ax, dx ; seg_hi
xchg ax, dx /* seg_hi */
reloc_0:
lodsw
xchg ax, di
@ -164,35 +153,35 @@ reloc_1:
reloc_2:
lodsb
dec ax
jz reloc_5
jzs reloc_5
inc ax
jnz reloc_1
%ifdef __EXEREL9A__
section EXEREL9A
inc di
reloc_4:
inc di
cmp byte [es:di], 0x9a
cmpb [es:di], 0x9a
jne reloc_4
cmp [es:di+3], dx
ja reloc_4
mov al, 3
jmps reloc_1
%endif; __EXERELO2__
section EXERELO2
reloc_5:
add di, 0xfe
%ifdef __EXEREBIG__
jc reloc_0
%endif; __EXERELO3__
section EXEREBIG
jcs reloc_0
section EXERELO3
loop reloc_2
%endif; __EXEMAIN8__
; =============
/* POSTPROCESSING */
section EXEMAIN8
pop es
push es
pop ds
; __DEVICEEND__
section DEVICEEND
popf
jc loaded_as_exe
pop es
@ -200,43 +189,33 @@ reloc_5:
pop bp
pop di
pop si
pop bx ; get original device SS:SP
pop bx /* get original device SS:SP */
pop ax
mov ss, ax ; switch to device driver stack
mov ss, ax /* switch to device driver stack */
mov sp, bx
pop dx
pop cx
pop bx
pop ax
retf ; return to original strategy
lret /* return to original strategy */
loaded_as_exe:
%ifdef __EXESTACK__
lea ax, ['SS'+bp]
section EXESTACK
lea ax, [original_ss + bp]
mov ss, ax
%endif; __EXEDUMMS__
%ifdef __EXESTASP__
mov sp, 'SP'
%endif; __EXEDUMMP__
section EXESTASP
mov sp, offset original_sp
; =============
section EXEJUMPF
.byte 0xea /* jmpf cs:ip */
.word original_ip, original_cs
%ifdef __EXEJUMPF__
jmp 'CS':'IP'
%else; __EXERETUR__
%ifdef __EXERCSPO__
add bp, 'CS'
%endif; __EXERETIP__
section EXERCSPO
add bp, offset original_cs
section EXERETIP
push bp
mov ax, 'IP'
mov ax, offset original_ip
push ax
retf
%endif; __EXEDUMMZ__
eof:
; __EXETHEND__
section .data
dd -1
dw eof
lret
; vi:ts=8:et:nowrap
/* vi:ts=8:et:nowrap */

View File

@ -44,7 +44,7 @@ section UPX1HEAD
dw 0 # 18 compressed len
db 0 # 20 filter
db 45 # 21 header checksum
#elif EXE
#elif defined(EXE)
db 0,0,0 # 16 uncompressed len
db 0,0,0 # 19 compressed len
db 0,0,0 # 22 original file size