dos/djgpp2 using nrv2e converted to ElfLinker
This commit is contained in:
parent
5964a06386
commit
f022c9d510
@ -31,6 +31,7 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_djgpp2.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/i386-dos32.djgpp2.h"
|
||||
@ -82,6 +83,12 @@ unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
||||
}
|
||||
|
||||
|
||||
Linker* PackDjgpp2::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
@ -101,7 +108,7 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
addLoader("DJCALLT2", NULL);
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("DJRETURN,+40DXXXX,UPX1HEAD", NULL);
|
||||
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
@ -228,6 +235,29 @@ void PackDjgpp2::stripDebug()
|
||||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
|
||||
#if 0
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
int const mru = ph.n_mru ? 1+ ph.n_mru : 0;
|
||||
if (mru && mru!=256) {
|
||||
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||
patch_le32(0x80 + (char *)loader, lsize - 0x80, "NMRU", mru - is_pwr2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@ -300,6 +330,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
|
||||
// patch coff header #2
|
||||
const unsigned lsize = getLoaderSize();
|
||||
assert(lsize % 4 == 0);
|
||||
text->size = lsize; // new size of .text
|
||||
data->size = ph.c_len; // new size of .data
|
||||
|
||||
@ -313,21 +344,14 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
||||
coff_hdr.f_nscns = 3;
|
||||
|
||||
// prepare loader
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
// patch loader
|
||||
patchPackHeader(loader, lsize);
|
||||
patch_le32(loader, lsize, "ENTR", coff_hdr.a_entry);
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4);
|
||||
patchDecompressor(loader, lsize);
|
||||
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||
//patchDecompressor(loader, lsize); // FIXME
|
||||
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||
if (ph.method == M_LZMA)
|
||||
patch_le32(loader, lsize, "ESP0", bss->vaddr + bss->size);
|
||||
patch_le32(loader, lsize, "OUTP", text->vaddr - hdrsize);
|
||||
patch_le32(loader, lsize, "INPP", data->vaddr);
|
||||
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||
defineFilterSymbols(linker, &ft);
|
||||
|
||||
// we should not overwrite our decompressor during unpacking
|
||||
// the original coff header (which is put just before the
|
||||
@ -344,6 +368,14 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
memcpy(obuf+data->size, "UPX", 3);
|
||||
data->size = ALIGN_UP(data->size, 4);
|
||||
|
||||
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||
linker->relocate();
|
||||
|
||||
// prepare loader
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
// write coff header, loader and compressed file
|
||||
fo->write(&coff_hdr, sizeof(coff_hdr));
|
||||
fo->write(loader, lsize);
|
||||
|
||||
@ -60,6 +60,7 @@ protected:
|
||||
unsigned range = 0,
|
||||
unsigned upper_limit = ~0u) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
long coff_offset;
|
||||
|
||||
|
||||
@ -313,9 +313,11 @@ i086-dos16.sys.h : $(srcdir)/src/$$T.asm
|
||||
i386-dos32.djgpp2% : tc_list = arch-i386 default
|
||||
|
||||
i386-dos32.djgpp2.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
|
||||
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin
|
||||
$(call tc,m-objcopy) --strip-unneeded tmp/$T.bin
|
||||
$(call tc,m-objcopy) -R .text -R .data -R .bss tmp/$T.bin
|
||||
$(call tc,m-objcopy) -R .note -R .comment tmp/$T.bin
|
||||
$(call tc,m-objdump) -trwh tmp/$T.bin >> tmp/$T.bin
|
||||
$(call tc,bin2h) --ident=nrv_loader tmp/$T.bin $@
|
||||
|
||||
i386-dos32.djgpp2-stubify.h : $(srcdir)/src/$$T.asm
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
617
src/stub/src/arch/i386/macros2.ash
Normal file
617
src/stub/src/arch/i386/macros2.ash
Normal file
@ -0,0 +1,617 @@
|
||||
/*
|
||||
; macros.ash --
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
;
|
||||
; Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
; Copyright (C) 1996-2006 Laszlo Molnar
|
||||
; All Rights Reserved.
|
||||
;
|
||||
; UPX and the UCL library are free software; you can redistribute them
|
||||
; and/or modify them under the terms of the GNU General Public License as
|
||||
; published by the Free Software Foundation; either version 2 of
|
||||
; the License, or (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program; see the file COPYING.
|
||||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
.intel_syntax noprefix
|
||||
|
||||
.macro section name
|
||||
.section \name
|
||||
.code32
|
||||
.endm
|
||||
|
||||
.macro CPU id
|
||||
.ifc \id, 386
|
||||
//.arch i386, nojumps
|
||||
.endif
|
||||
.ifc \id, 486
|
||||
.arch i486, nojumps
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro jmps target
|
||||
.byte 0xeb, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jos target
|
||||
.byte 0x70, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jnos target
|
||||
.byte 0x71, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jcs target
|
||||
.byte 0x72, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jncs target
|
||||
.byte 0x73, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jzs target
|
||||
.byte 0x74, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jnzs target
|
||||
.byte 0x75, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jnas target
|
||||
.byte 0x76, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jas target
|
||||
.byte 0x77, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jss target
|
||||
.byte 0x78, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jnss target
|
||||
.byte 0x79, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jps target
|
||||
.byte 0x7a, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jnps target
|
||||
.byte 0x7b, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jls target
|
||||
.byte 0x7c, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jnls target
|
||||
.byte 0x7d, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jngs target
|
||||
.byte 0x7e, \target - . - 1
|
||||
.endm
|
||||
|
||||
.macro jgs target
|
||||
.byte 0x7f, \target - . - 1
|
||||
.endm
|
||||
|
||||
#define jes jzs
|
||||
#define jnes jnzs
|
||||
#define jbes jnas
|
||||
|
||||
/*
|
||||
;; =============
|
||||
;; ============= 32-BIT CALLTRICK & JUMPTRICK
|
||||
;; =============
|
||||
|
||||
;; call & jump trick : 2 in 1
|
||||
*/
|
||||
|
||||
.macro cjt32 addvalue
|
||||
section CALLTR00
|
||||
mov ecx, offset filter_length
|
||||
calltrickloop:
|
||||
mov al, [edi]
|
||||
inc edi
|
||||
sub al, 0xE8
|
||||
ct1:
|
||||
cmp al, 1
|
||||
ja calltrickloop
|
||||
section CTCLEVE1
|
||||
cmpb [edi], offset filter_cto
|
||||
jnzs calltrickloop
|
||||
section CALLTR01
|
||||
mov eax, [edi]
|
||||
mov bl, [edi + 4]
|
||||
section CTBSHR01
|
||||
shr ax, 8
|
||||
section CTBROR01
|
||||
xchg ah, al
|
||||
section CTBSWA01
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
section CALLTR02
|
||||
sub eax, edi
|
||||
sub bl, 0xE8
|
||||
|
||||
.if \addvalue
|
||||
add eax, \addvalue
|
||||
.endif
|
||||
|
||||
mov [edi], eax
|
||||
add edi, 5
|
||||
mov al, bl
|
||||
loop ct1
|
||||
|
||||
section CALLTR10
|
||||
//;; 32-bit call XOR jump trick
|
||||
mov ecx, offset filter_length
|
||||
ctloop1:
|
||||
section CALLTRE8
|
||||
mov al,0xE8
|
||||
section CALLTRE9
|
||||
mov al,0xE9
|
||||
section CALLTR11
|
||||
ctloop2:
|
||||
repnz
|
||||
scasb
|
||||
jnzs ctend
|
||||
section CTCLEVE2
|
||||
cmpb [edi], offset filter_cto
|
||||
jnzs ctloop2
|
||||
section CALLTR12
|
||||
mov eax, [edi]
|
||||
section CTBSHR11
|
||||
shr ax, 8
|
||||
section CTBROR11
|
||||
xchg ah, al
|
||||
section CTBSWA11
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
section CALLTR13
|
||||
sub eax, edi
|
||||
|
||||
.if \addvalue
|
||||
add eax, \addvalue
|
||||
.endif
|
||||
|
||||
stosd
|
||||
jmps ctloop1
|
||||
ctend:
|
||||
section CTTHEEND
|
||||
.endm
|
||||
|
||||
#if 0
|
||||
|
||||
;; call/jump/jcc trick; also used more than once (and/or optionally), so
|
||||
;; ecx has byte count (not count of applied instances), and
|
||||
;; edi points to buffer.
|
||||
%macro ckt32 2
|
||||
; 1st param: effective addvalue (typically 0 or edi; any rvalue)
|
||||
; 2nd param: where is cto8 (dl, bl, or literal)
|
||||
|
||||
section CKLLTR00
|
||||
%ifnidn %1,0
|
||||
mov esi, %1
|
||||
%endif
|
||||
jmps ckstart
|
||||
ckloop3:
|
||||
mov al, [edi]
|
||||
add edi, byte 1
|
||||
section CKLLTR10 Jcc only
|
||||
cmp al, 0x80 ; lo of 6-byte Jcc
|
||||
jb ckloop2
|
||||
cmp al, 0x8f ; hi of 6-byte Jcc
|
||||
ja ckloop2
|
||||
cmp byte [edi -2], 0x0F ; prefix of 6-byte Jcc
|
||||
je ckmark
|
||||
ckloop2:
|
||||
section CKLLTR20
|
||||
sub al, 0xE8
|
||||
cmp al, 0xE9 - 0xE8
|
||||
ja ckcount
|
||||
ckmark:
|
||||
cmp byte [edi], %2 ; cto8
|
||||
jnz ckcount
|
||||
mov eax, [edi]
|
||||
|
||||
shr ax, 8
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
; above 3 instr are equivalent to the following 2 instr:
|
||||
; mov al, 0 ; clear cto8 [setup partial-write stall]
|
||||
; bswap eax ; not on 386: need 486 and up
|
||||
|
||||
sub eax, edi
|
||||
%ifnidn %1,0
|
||||
add eax, esi
|
||||
%endif
|
||||
mov [edi], eax
|
||||
add edi, byte 4
|
||||
ckstart:
|
||||
sub ecx, byte 4
|
||||
section CKLLTR30 Jcc only
|
||||
mov al, [edi]
|
||||
add edi, byte 1
|
||||
loop ckloop2 ; prefix cannot overlap previous displacement
|
||||
section CKLLTR40
|
||||
ckcount:
|
||||
sub ecx, byte 1
|
||||
jg ckloop3
|
||||
ckend:
|
||||
%endmacro
|
||||
|
||||
;; =============
|
||||
;; ============= 32-BIT RELOCATIONS
|
||||
;; =============
|
||||
|
||||
%macro reloc32 3
|
||||
section RELOC320
|
||||
reloc_main:
|
||||
xor eax, eax
|
||||
mov al, [%1]
|
||||
inc %1
|
||||
or eax, eax
|
||||
jz reloc_endx
|
||||
cmp al, 0xEF
|
||||
ja reloc_fx
|
||||
reloc_add:
|
||||
add %2, eax
|
||||
%if 1
|
||||
mov eax, [%2]
|
||||
xchg ah, al
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
add eax, %3
|
||||
mov [%2], eax
|
||||
%else
|
||||
add [%2], %3
|
||||
%endif
|
||||
jmps reloc_main
|
||||
reloc_fx:
|
||||
and al, 0x0F
|
||||
shl eax, 16
|
||||
mov ax, [%1]
|
||||
add %1, byte 2
|
||||
section REL32BIG
|
||||
or eax, eax
|
||||
jnz reloc_add
|
||||
mov eax, [%1]
|
||||
add %1, byte 4
|
||||
section RELOC32J
|
||||
jmps reloc_add
|
||||
reloc_endx:
|
||||
section REL32END
|
||||
%endmacro
|
||||
|
||||
|
||||
;; =============
|
||||
;; ============= 32-BIT CALL TRICK UNFILTER WITH MostRecentlyUsed BUFFER
|
||||
;; =============
|
||||
|
||||
;;;; names of pseudo-sections for addLoader:
|
||||
;; LXUNFnnn Linux unfilter
|
||||
;; LXMRUnnn MostRecentlyUsed recoding of destinations
|
||||
;; MRUARBnn arbitrary number of entries in wheel
|
||||
;; MRUBITSn power of 2 entries in wheel (smaller code)
|
||||
;; MRUBYTEn 256 entries in wheel (smallest code)
|
||||
|
||||
%macro ctojr32 0
|
||||
%push ctojr32
|
||||
|
||||
;; I got confused by the syntactic sugar of the fake %ifdefs.
|
||||
;; I can read the section name more easily when it is at the left margin.
|
||||
;; Also, some of the logic to select the sections is not that simple,
|
||||
;; and any mismatch between the logic and the %ifdefs is very confusing.
|
||||
;; Instead, I use comments after the section name, and blank lines for grouping.
|
||||
|
||||
section LXUNF000 enter at +0 for decompression; +2 for unfiltering
|
||||
jmps decompr0
|
||||
section LXUNF002
|
||||
;; 2+ address of decompress subroutine
|
||||
;; unfilter(upx_byte *, length, cto8)
|
||||
lxunfilter:
|
||||
pop edx ; return address
|
||||
pop eax ; upx_byte *, same as addvalue
|
||||
pop ecx ; length
|
||||
xchg eax, edi ; edi= pointer; eax= saved_edi
|
||||
pusha ; save C-convention ebx, ebp, esi, edi; also eax, edx
|
||||
|
||||
; at most one of the next 2
|
||||
section MRUBYTE0 256==n_mru
|
||||
xor ebx, ebx ; zero
|
||||
section LXMRU005 0!=n_mru
|
||||
mov ebx, 'NMRU' ; modified N_MRU or N_MRU -1
|
||||
|
||||
section LXMRU006 0!=n_mru
|
||||
push byte 0x0f ; prefix of 6-byte Jcc <d32>
|
||||
pop eax
|
||||
mov ah, [esp + 8*4] ; cto8
|
||||
section LXMRU007 0==n_mru
|
||||
push byte 0x0f ; prefix of 6-byte Jcc <d32>
|
||||
pop ebx
|
||||
mov bh, [esp + 8*4] ; cto8
|
||||
|
||||
section LXUNF008
|
||||
mov dl, [esp + 8*4] ; cto8
|
||||
|
||||
section LXUNF010
|
||||
jmpn lxunf0
|
||||
decompr0:
|
||||
|
||||
;; These %define are only if 0!=n_mru;
|
||||
;; else 0x0F==bl && cto8==bh==dh && 0xE8==dl && addvalue==esi .
|
||||
%define %$n_mru [esi]
|
||||
%define %$n_mru1 [esi]
|
||||
%define %$tail [esi + 4*1]
|
||||
%define %$cto8_e8e9 [esi + 4*2]
|
||||
%define %$cto8_0f [esi + 4*3]
|
||||
%define %$addvalue [esi + 4*4]
|
||||
%define %$tmp ebp
|
||||
%define %$hand ebx
|
||||
%define %$hand_l bl
|
||||
%define %$kh edx
|
||||
%define %$kh_l dl
|
||||
|
||||
section LXJCC010
|
||||
lxunf2: ; have seen 0x80..0x8f of possible recoded 6-byte Jcc <d32>
|
||||
movzx ebp, word [edi] ; 2 bytes, zero-extended
|
||||
|
||||
section LXMRU045 0!=n_mru
|
||||
sub ebp, %$cto8_0f
|
||||
section LXMRU046 0==n_mru
|
||||
sub ebp, ebx
|
||||
|
||||
section LXJCC020 0==n_mru, or Jcc excluded ('sub' of equals clears Carry)
|
||||
jne unfcount
|
||||
section LXJCC021 0!=n_mru and Jcc participates; must set Carry
|
||||
sub ebp, byte 1 ; set Carry iff in range
|
||||
jnb unfcount
|
||||
|
||||
section LXJCC023 found Jcc; re-swap 0x8Y opcode and 0x0f prefix
|
||||
mov byte [edi -1], bl ; 0x0f prefix
|
||||
dec ecx ; preserve Carry
|
||||
mov byte [edi], al ; Jcc opcode
|
||||
inc edi ; preserve Carry
|
||||
|
||||
section LXUNF037
|
||||
%define %$jc eax
|
||||
|
||||
lxunf: ; in: Carry set iff we should apply mru and 0!=n_mru
|
||||
mov eax, [edi] ; BE32 displacement with cto8 in low 8 bits
|
||||
|
||||
section LXUNF386 0!=n_mru && 386
|
||||
pushf
|
||||
section LXUNF387 ==386
|
||||
shr ax, 8
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
section LXUNF388 0!=n_mru && 386
|
||||
popf
|
||||
jnc unf_store ; do not apply mru
|
||||
|
||||
section LXUNF486 >=486
|
||||
mov al, byte 0
|
||||
CPU 486
|
||||
bswap eax ; preserve Carry (2-byte instruction)
|
||||
CPU 386
|
||||
section LXUNF487 0!=n_mru && >=486
|
||||
jnc unf_store ; do not apply mru
|
||||
|
||||
section LXMRU065 0!=n_mru
|
||||
shr %$jc, 1 ; eax= jc, or mru index
|
||||
jnc mru4 ; not 1st time for this jc
|
||||
section MRUBYTE3
|
||||
dec %$hand_l
|
||||
section MRUARB30
|
||||
dec %$hand
|
||||
section MRUBITS3
|
||||
and %$hand, %$n_mru1
|
||||
section MRUARB40
|
||||
jge mru3
|
||||
add %$hand, %$n_mru
|
||||
mru3:
|
||||
section LXMRU070
|
||||
|
||||
mov [esp + 4*%$hand], %$jc ; 1st time: mru[hand] = jc
|
||||
jmps unf_store
|
||||
|
||||
mru4: ; not 1st time for this jc
|
||||
lea %$kh, [%$jc + %$hand] ; kh = jc + hand
|
||||
section MRUBYTE4
|
||||
movzx %$kh, %$kh_l
|
||||
section MRUBITS4
|
||||
and %$kh, %$n_mru1
|
||||
section MRUARB50
|
||||
cmp %$kh, %$n_mru
|
||||
jb mru5
|
||||
sub %$kh, %$n_mru
|
||||
mru5:
|
||||
section LXMRU080
|
||||
mov %$jc, [esp + 4*%$kh] ; jc = mru[kh]
|
||||
section MRUBYTE5
|
||||
dec %$hand_l
|
||||
section MRUARB60
|
||||
dec %$hand
|
||||
section MRUBITS5
|
||||
and %$hand, %$n_mru1
|
||||
section MRUARB70
|
||||
jge mru6
|
||||
add %$hand, %$n_mru
|
||||
mru6:
|
||||
section LXMRU090
|
||||
|
||||
mov %$tmp, [esp + 4*%$hand] ; tmp = mru[hand]
|
||||
test %$tmp,%$tmp
|
||||
jnz mru8
|
||||
|
||||
push %$jc ; ran out of registers
|
||||
mov eax, %$tail
|
||||
|
||||
section MRUBYTE6
|
||||
dec al
|
||||
section MRUARB80
|
||||
dec eax
|
||||
section MRUBITS6
|
||||
and eax, %$n_mru1
|
||||
section MRUARB90
|
||||
jge mru7
|
||||
add eax, %$n_mru
|
||||
mru7:
|
||||
section LXMRU100
|
||||
|
||||
xor %$tmp,%$tmp
|
||||
mov %$tail, eax
|
||||
xchg [4+ esp + 4*eax], %$tmp ; tmp = mru[tail]; mru[tail] = 0
|
||||
pop %$jc
|
||||
mru8:
|
||||
mov [esp + 4*%$kh ], %$tmp ; mru[kh] = tmp
|
||||
mov [esp + 4*%$hand], %$jc ; mru[hand] = jc
|
||||
section LXUNF040
|
||||
unf_store:
|
||||
sub eax, edi
|
||||
sub ecx, byte 4
|
||||
|
||||
; one of the next2
|
||||
section LXMRU110 0!=n_mru
|
||||
add eax, %$addvalue
|
||||
section LXMRU111 0==n_mru
|
||||
add eax, esi ; addvalue (same as initial pointer)
|
||||
|
||||
section LXUNF041
|
||||
mov [edi], eax
|
||||
add edi, byte 4
|
||||
jmps unfcount
|
||||
section LXUNF042
|
||||
lxunf0: ;; continuation of entry prolog for unfilter
|
||||
section LEXEC016 bug in APP: jmp and label must be in same .asx/.asy
|
||||
jmp lxunf0 ; this instr does not really go here!
|
||||
|
||||
section LXMRU010 0!=n_mru
|
||||
push eax ; cto8_0f
|
||||
section LXJMPA00 only JMP, and not CALL, is filtered
|
||||
mov al, 0xE9
|
||||
section LXCALLB0 only CALL, or both CALL and JMP are filtered
|
||||
mov al, 0xE8
|
||||
section LXUNF021 common tail
|
||||
push eax ; cto8_e8e9
|
||||
push byte 0 ; tail
|
||||
push ebx ; n_mru or n_mru1
|
||||
mov esi, esp ; flat model "[esi]" saves a byte over "[ebp]"
|
||||
|
||||
section LXMRU022 0==n_mru
|
||||
pop esi ; addvalue
|
||||
mov edx, ebx ; dh= cto8
|
||||
section LXJMPA01 only JMP, and not CALL, is filtered
|
||||
mov dl, 0xE9
|
||||
section LXCALLB1 only CALL, or both CALL and JMP are filtered
|
||||
mov dl, 0xE8
|
||||
|
||||
|
||||
section MRUBITS1
|
||||
inc %$hand ; n_mru1 ==> n_mru
|
||||
section LXMRU030
|
||||
lxunf1: ; allocate and clear mru[]
|
||||
push byte 0
|
||||
|
||||
; one of the next 2, if n_mru
|
||||
section MRUBYTE1
|
||||
dec %$hand_l
|
||||
section MRUARB10
|
||||
dec %$hand
|
||||
|
||||
section LXMRU040 0!=n_mru
|
||||
jnz lxunf1 ; leaves 0=='hand'
|
||||
|
||||
section LXUNF030
|
||||
lxctloop:
|
||||
movzx eax, word [edi] ; 2 bytes, zero extended
|
||||
add edi, byte 1
|
||||
section LXJCC000
|
||||
cmp al, 0x80 ; lo of Jcc <d32>
|
||||
jb lxct1
|
||||
cmp al, 0x8f ; hi of Jcc <d32>
|
||||
jbe lxunf2
|
||||
lxct1:
|
||||
|
||||
section LXCJ0MRU 0==n_mru
|
||||
sub eax, edx
|
||||
section LXCJ1MRU 0!=n_mru
|
||||
sub eax, %$cto8_e8e9
|
||||
|
||||
; both CALL and JMP are filtered
|
||||
section LXCALJMP
|
||||
sub eax, byte 1+ (0xE9 - 0xE8) ; set Carry iff in range (result: -2, -1)
|
||||
|
||||
; only CALL, or only JMP, is filtered
|
||||
section LXCALL00 0==n_mru
|
||||
je lxunf
|
||||
section LXCALL01 0!=n_rmu
|
||||
sub eax, byte 1 ; set Carry iff in range
|
||||
|
||||
section LXCJ2MRU 0==n_mru, or apply mru to all that are filtered here
|
||||
jb lxunf ; only Carry (Borrow) matters
|
||||
section LXCJ4MRU 0!=n_mru, but apply mru only to subset of filtered here
|
||||
jnb unfcount ; was not filtered anyway: do not unfilter
|
||||
|
||||
;we will unfilter, and 0!=n_mru, but should we apply mru?
|
||||
section LXCJ6MRU apply mru to JMP only (0xFF==al)
|
||||
jpe lxct3 ; jump if even number of 1 bits in al
|
||||
section LXCJ7MRU apply mru to CALL only (0xFE==al)
|
||||
jpo lxct3 ; jump if odd number of 1 bits in al
|
||||
section LXCJ8MRU do not apply mru to one or both
|
||||
clc
|
||||
lxct3:
|
||||
jmps lxunf
|
||||
|
||||
section LXUNF034
|
||||
unfcount:
|
||||
sub ecx, byte 1
|
||||
jg lxctloop
|
||||
|
||||
section LXMRU055
|
||||
mov edi, esp ; clear mru[] portion of stack
|
||||
section MRUBYTE2
|
||||
mov ecx, 4+ 256 ; unused, tail, cto8_e8e9, cto8_0f
|
||||
section MRUBITS2
|
||||
mov ecx, %$n_mru1
|
||||
add ecx, byte 1+ 4 ; n_mru1, tail, cto8_e8e9, cto8_0f
|
||||
section MRUARB20
|
||||
mov ecx, %$n_mru
|
||||
add ecx, byte 4 ; n_mru, tail, cto8_e8e9, cto8_0f
|
||||
section LXMRU057
|
||||
xor eax, eax
|
||||
rep
|
||||
stosd
|
||||
mov esp, edi
|
||||
|
||||
section LXMRU058 0==n_mru
|
||||
push esi
|
||||
section LXUNF035
|
||||
popa
|
||||
xchg eax, edi
|
||||
push ecx
|
||||
push eax
|
||||
push edx
|
||||
ret
|
||||
%pop
|
||||
%endmacro
|
||||
#endif
|
||||
|
||||
// vi:ts=8:et:nowrap
|
||||
200
src/stub/src/arch/i386/nrv2e_d32_2.ash
Normal file
200
src/stub/src/arch/i386/nrv2e_d32_2.ash
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
; n2e_d32.ash -- ucl_nrv2e_decompress_le32 in 32-bit assembly
|
||||
;
|
||||
; This file is part of the UCL data compression library.
|
||||
;
|
||||
; Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
; All Rights Reserved.
|
||||
;
|
||||
; The UCL library is free software; you can redistribute it and/or
|
||||
; modify it under the terms of the GNU General Public License as
|
||||
; published by the Free Software Foundation; either version 2 of
|
||||
; the License, or (at your option) any later version.
|
||||
;
|
||||
; The UCL library is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with the UCL library; see the file COPYING.
|
||||
; If not, write to the Free Software Foundation, Inc.,
|
||||
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;
|
||||
; Markus F.X.J. Oberhumer
|
||||
; <markus@oberhumer.com>
|
||||
; http://www.oberhumer.com/opensource/ucl/
|
||||
;
|
||||
|
||||
|
||||
; ------------- DECOMPRESSION -------------
|
||||
|
||||
; Input:
|
||||
; esi - source
|
||||
; edi - dest
|
||||
; ebp - -1
|
||||
; cld
|
||||
|
||||
; Output:
|
||||
; eax - 0
|
||||
; ecx - 0
|
||||
*/
|
||||
|
||||
// CPU 386
|
||||
|
||||
.macro getbit_n2e one
|
||||
.ifc \one, 1
|
||||
add ebx, ebx
|
||||
jnz 1f
|
||||
.endif
|
||||
mov ebx, [esi]
|
||||
sub esi, -4
|
||||
adc ebx, ebx
|
||||
1:
|
||||
.endm
|
||||
|
||||
#undef getbit
|
||||
#define getbit getbit_n2e
|
||||
|
||||
section N2ESMA10
|
||||
jmps dcl1_n2e
|
||||
decompr_literals_n2e:
|
||||
movsb
|
||||
section N2EFAS10
|
||||
jmps dcl1_n2e
|
||||
section N2EFAS11
|
||||
decompr_literalb_n2e:
|
||||
mov al, [esi]
|
||||
inc esi
|
||||
mov [edi], al
|
||||
inc edi
|
||||
section N2EDEC10
|
||||
|
||||
|
||||
decompr_loop_n2e:
|
||||
add ebx, ebx
|
||||
jnz dcl2_n2e
|
||||
dcl1_n2e:
|
||||
getbit 32
|
||||
dcl2_n2e:
|
||||
section N2ESMA20
|
||||
jcs decompr_literals_n2e
|
||||
xor eax, eax
|
||||
inc eax
|
||||
section N2EFAS20
|
||||
#ifndef UPX102
|
||||
mov al, [edi] // force data cache allocate (PentiumPlain or MMX)
|
||||
#endif
|
||||
jcs decompr_literalb_n2e
|
||||
mov eax, 1
|
||||
section N2EDEC20
|
||||
loop1_n2e:
|
||||
getbit 1
|
||||
adc eax, eax
|
||||
section N2ESMA30
|
||||
getbit 1
|
||||
jcs loopend1_n2e
|
||||
section N2EFAS30
|
||||
add ebx, ebx
|
||||
jnc loopcontinue1_n2e
|
||||
jnzs loopend1_n2e
|
||||
getbit 32
|
||||
jcs loopend1_n2e
|
||||
loopcontinue1_n2e:
|
||||
section N2EDEC30
|
||||
dec eax
|
||||
getbit 1
|
||||
adc eax, eax
|
||||
jmps loop1_n2e
|
||||
|
||||
decompr_mlen1_n2e:
|
||||
getbit 1
|
||||
adc ecx, ecx
|
||||
jmps decompr_got_mlen_n2e
|
||||
|
||||
loopend1_n2e:
|
||||
xor ecx, ecx
|
||||
sub eax, 3
|
||||
jb decompr_prev_dist_n2e
|
||||
shl eax, 8
|
||||
mov al, [esi]
|
||||
inc esi
|
||||
xor eax, -1
|
||||
jzs decompr_end_n2e
|
||||
sar eax, 1 // shift low-bit into carry
|
||||
mov ebp, eax
|
||||
jmps decompr_ebpeax_n2e
|
||||
decompr_prev_dist_n2e:
|
||||
getbit 1
|
||||
decompr_ebpeax_n2e:
|
||||
jcs decompr_mlen1_n2e
|
||||
inc ecx
|
||||
getbit 1
|
||||
jcs decompr_mlen1_n2e
|
||||
loop2_n2e:
|
||||
getbit 1
|
||||
adc ecx, ecx
|
||||
section N2ESMA40
|
||||
getbit 1
|
||||
jncs loop2_n2e
|
||||
section N2EFAS40
|
||||
add ebx, ebx
|
||||
jncs loop2_n2e
|
||||
jnz loopend2_n2e
|
||||
getbit 32
|
||||
jncs loop2_n2e
|
||||
loopend2_n2e:
|
||||
section N2ESMA50
|
||||
inc ecx
|
||||
inc ecx
|
||||
section N2EFAS50
|
||||
add ecx, 2
|
||||
section N2EDEC50
|
||||
decompr_got_mlen_n2e:
|
||||
cmp ebp, -0x500
|
||||
adc ecx, 2
|
||||
section N2ESMA60
|
||||
#ifndef UPX102
|
||||
push esi
|
||||
#else
|
||||
mov edx, esi
|
||||
#endif
|
||||
lea esi, [edi+ebp]
|
||||
rep
|
||||
movsb
|
||||
#ifndef UPX102
|
||||
pop esi
|
||||
#else
|
||||
mov esi, edx
|
||||
#endif
|
||||
jmp decompr_loop_n2e
|
||||
section N2EFAS60
|
||||
lea edx, [edi+ebp]
|
||||
cmp ebp, -4
|
||||
#ifndef UPX102
|
||||
mov al, [edi+ecx] // force data cache allocate (PentiumPlain or MMX)
|
||||
#endif
|
||||
jbes decompr_copy4_n2e
|
||||
loop3_n2e:
|
||||
mov al, [edx]
|
||||
inc edx
|
||||
mov [edi], al
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz loop3_n2e
|
||||
jmp decompr_loop_n2e
|
||||
section N2EFAS61
|
||||
decompr_copy4_n2e:
|
||||
mov eax, [edx]
|
||||
add edx, 4
|
||||
mov [edi], eax
|
||||
add edi, 4
|
||||
sub ecx, 4
|
||||
ja decompr_copy4_n2e
|
||||
add edi, ecx
|
||||
jmp decompr_loop_n2e
|
||||
section N2EDEC60
|
||||
decompr_end_n2e:
|
||||
|
||||
// vi:ts=8:et
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/*
|
||||
; l_djgpp2.asm -- loader & decompressor for the djgpp2/coff format
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
@ -24,93 +25,72 @@
|
||||
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
#include "arch/i386/macros2.ash"
|
||||
|
||||
%define jmps jmp short
|
||||
%define jmpn jmp near
|
||||
%include "arch/i386/macros.ash"
|
||||
|
||||
BITS 32
|
||||
SECTION .text
|
||||
ORG 0
|
||||
CPU 386
|
||||
|
||||
; =============
|
||||
; ============= ENTRY POINT
|
||||
; =============
|
||||
|
||||
; __DJ2MAIN1__
|
||||
start:
|
||||
section DJ2MAIN1
|
||||
push ds
|
||||
pop es
|
||||
|
||||
mov esi, 'INPP' ; input pointer
|
||||
mov edi, 'OUTP' ; output pointer
|
||||
%ifdef __DJCALLT1__
|
||||
mov esi, offset start_of_compressed
|
||||
mov edi, offset start_of_uncompressed
|
||||
section DJCALLT1
|
||||
push edi
|
||||
%endif; __DJ2MAIN2__
|
||||
; cld ; the stub sets this
|
||||
or ebp, byte -1
|
||||
section DJ2MAIN2
|
||||
or ebp, -1
|
||||
|
||||
; __LZMA_INIT_STACK__
|
||||
section LZMA_INIT_STACK
|
||||
|
||||
/*
|
||||
; as this stub gets loaded from 0x000000a8, we have some scratch
|
||||
; memory starting from 0x00000000 to store ss:esp
|
||||
; note: NULL page protection is only activated by the
|
||||
; uncompressed application later
|
||||
|
||||
*/
|
||||
xor eax, eax
|
||||
mov [eax], ss
|
||||
mov [eax + 4], esp
|
||||
mov eax, ds
|
||||
mov ss, eax
|
||||
mov esp, 'ESP0'
|
||||
mov esp, offset stack_for_lzma
|
||||
|
||||
/*
|
||||
; =============
|
||||
; ============= DECOMPRESSION
|
||||
; =============
|
||||
*/
|
||||
|
||||
%include "arch/i386/nrv2b_d32.ash"
|
||||
%include "arch/i386/nrv2d_d32.ash"
|
||||
%include "arch/i386/nrv2e_d32.ash"
|
||||
%include "arch/i386/lzma_d.ash"
|
||||
//include "arch/i386/nrv2b_d32.ash"
|
||||
//#include "arch/i386/nrv2d_d32.ash"
|
||||
#include "arch/i386/nrv2e_d32_2.ash"
|
||||
//#include "arch/i386/lzma_d.ash"
|
||||
|
||||
; __LZMA_DONE_STACK__
|
||||
mov ss, [eax] ; eax is always 0 here
|
||||
section LZMA_DONE_STACK
|
||||
mov ss, [eax] // eax is always 0 here
|
||||
mov esp, [eax + 4]
|
||||
|
||||
; =============
|
||||
|
||||
; __DJ2BSS00__
|
||||
mov ecx, 'BSSL'
|
||||
section DJ2BSS00
|
||||
mov ecx, offset length_of_bss
|
||||
rep
|
||||
stosd
|
||||
%ifdef __DJCALLT2__
|
||||
|
||||
; =============
|
||||
; ============= CALLTRICK
|
||||
; =============
|
||||
|
||||
section DJCALLT2
|
||||
pop edi
|
||||
cjt32 0
|
||||
%endif; __DJRETURN__
|
||||
|
||||
; =============
|
||||
|
||||
push dword 'ENTR' ; entry point
|
||||
ret
|
||||
section DJRETURN
|
||||
jmp original_entry
|
||||
|
||||
/*
|
||||
; because of a feature of the djgpp loader, the size of this stub must be
|
||||
; a multiple of 4 and as the upx decompressor depends on the fact that
|
||||
; the compressed data stream begins just after the header, i must
|
||||
; use an alignment here - ML
|
||||
align 4
|
||||
%include "include/header.ash"
|
||||
eof:
|
||||
; __DJTHEEND__
|
||||
section .data
|
||||
dd -1
|
||||
dw eof
|
||||
; the compressed data stream begins just after the header,
|
||||
; so the header section should be 4 byte aligned
|
||||
*/
|
||||
|
||||
#include "include/header2.ash"
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
// vi:ts=8:et:nowrap
|
||||
|
||||
Loading…
Reference in New Issue
Block a user