win32/pe using nrv2e converted to ElfLinker
This commit is contained in:
+61
-61
@@ -31,6 +31,7 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_w32pe.h"
|
#include "p_w32pe.h"
|
||||||
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/i386-win32.pe.h"
|
#include "stub/i386-win32.pe.h"
|
||||||
@@ -198,6 +199,12 @@ const int *PackW32Pe::getFilters() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Linker* PackW32Pe::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerX86;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PackW32Pe::testUnpackVersion(int version) const
|
bool PackW32Pe::testUnpackVersion(int version) const
|
||||||
{
|
{
|
||||||
if (version != ph_version && ph_version != -1)
|
if (version != ph_version && ph_version != -1)
|
||||||
@@ -259,6 +266,20 @@ int PackW32Pe::readFileHeader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// interval handling
|
// interval handling
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -1711,7 +1732,7 @@ int PackW32Pe::buildLoader(const Filter *ft)
|
|||||||
addLoader("PEDEPHAK", NULL);
|
addLoader("PEDEPHAK", NULL);
|
||||||
addLoader("PEMAIN20", NULL);
|
addLoader("PEMAIN20", NULL);
|
||||||
if (use_clear_dirty_stack)
|
if (use_clear_dirty_stack)
|
||||||
addLoader(ih.entry ? "PEDOJUMP_CLEARSTACK" : "PERETURN_CLEARSTACK", NULL);
|
addLoader("CLEARSTACK", NULL);
|
||||||
addLoader("PEMAIN21", NULL);
|
addLoader("PEMAIN21", NULL);
|
||||||
addLoader(ih.entry ? "PEDOJUMP" : "PERETURN",
|
addLoader(ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||||
"IDENTSTR,UPX1HEAD",
|
"IDENTSTR,UPX1HEAD",
|
||||||
@@ -1930,11 +1951,6 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||||||
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
|
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
|
||||||
tlsindex = 0;
|
tlsindex = 0;
|
||||||
|
|
||||||
const unsigned lsize = getLoaderSize();
|
|
||||||
MemBuffer loader(lsize);
|
|
||||||
memcpy(loader,getLoader(),lsize);
|
|
||||||
patchPackHeader(loader, lsize);
|
|
||||||
|
|
||||||
int identsize = 0;
|
int identsize = 0;
|
||||||
const unsigned codesize = getLoaderSection("IDENTSTR",&identsize);
|
const unsigned codesize = getLoaderSection("IDENTSTR",&identsize);
|
||||||
assert(identsize > 0);
|
assert(identsize > 0);
|
||||||
@@ -1970,11 +1986,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||||||
const unsigned myimport = ncsection + soresources - rvamin;
|
const unsigned myimport = ncsection + soresources - rvamin;
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
if (ih.entry)
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
{
|
|
||||||
unsigned jmp_pos = find_le32(loader,codesize + 4,get_le32("JMPO"));
|
|
||||||
patch_le32(loader,codesize + 4,"JMPO",ih.entry - upxsection - jmp_pos - 4);
|
|
||||||
}
|
|
||||||
if (use_dep_hack)
|
if (use_dep_hack)
|
||||||
{
|
{
|
||||||
// This works around a "protection" introduced in MSVCRT80, which
|
// This works around a "protection" introduced in MSVCRT80, which
|
||||||
@@ -2003,70 +2015,58 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||||||
#else
|
#else
|
||||||
// make sure we only touch the minimum number of pages
|
// make sure we only touch the minimum number of pages
|
||||||
const unsigned addr = 0u - rvamin + swri;
|
const unsigned addr = 0u - rvamin + swri;
|
||||||
patch_le32(loader, codesize, "SWRI", addr & 0xfff); // page offset
|
linker->defineSymbol("swri", addr & 0xfff); // page offset
|
||||||
// check whether osection[0].flags and osection[1].flags
|
// check whether osection[0].flags and osection[1].flags
|
||||||
// are on the same page
|
// are on the same page
|
||||||
if ((addr & 0xfff) + 0x28 >= 0x1000)
|
linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ?
|
||||||
patch_le32(loader, codesize, "IMGL", 0x2000); // two pages
|
0x2000 : 0x1000); // 2 pages or 1 page
|
||||||
else
|
linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask
|
||||||
patch_le32(loader, codesize, "IMGL", 0x1000); // one page
|
|
||||||
patch_le32(loader, codesize, "IMGB", addr &~ 0xfff); // page mask
|
|
||||||
#endif
|
#endif
|
||||||
patch_le32(loader, codesize, "VPRO", myimport + get_le32(oimpdlls + 16) + 8);
|
linker->defineSymbol("VirtualProtect", myimport + get_le32(oimpdlls + 16) + 8);
|
||||||
}
|
|
||||||
if (big_relocs & 6)
|
|
||||||
patch_le32(loader,codesize,"DELT", 0u - (unsigned) ih.imagebase - rvamin);
|
|
||||||
if (sorelocs && (soimport == 0 || soimport + cimports != crelocs))
|
|
||||||
patch_le32(loader,codesize,"BREL",crelocs);
|
|
||||||
if (soimport)
|
|
||||||
{
|
|
||||||
if (!isdll)
|
|
||||||
patch_le32(loader,codesize,"EXIT",myimport + get_le32(oimpdlls + 16) + 20);
|
|
||||||
patch_le32(loader,codesize,"GETP",myimport + get_le32(oimpdlls + 16) + 4);
|
|
||||||
if (kernel32ordinal)
|
|
||||||
patch_le32(loader,codesize,"K32O",myimport);
|
|
||||||
patch_le32(loader,codesize,"LOAD",myimport + get_le32(oimpdlls + 16));
|
|
||||||
patch_le32(loader,codesize,"IMPS",myimport);
|
|
||||||
patch_le32(loader,codesize,"BIMP",cimports);
|
|
||||||
}
|
}
|
||||||
|
linker->defineSymbol("reloc_delt", 0u - (unsigned) ih.imagebase - rvamin);
|
||||||
|
linker->defineSymbol("start_of_relocs", crelocs);
|
||||||
|
linker->defineSymbol("ExitProcess", myimport + get_le32(oimpdlls + 16) + 20);
|
||||||
|
linker->defineSymbol("GetProcAddress", myimport + get_le32(oimpdlls + 16) + 4);
|
||||||
|
linker->defineSymbol("kernel32_ordinals", myimport);
|
||||||
|
linker->defineSymbol("LoadLibraryA", myimport + get_le32(oimpdlls + 16));
|
||||||
|
linker->defineSymbol("start_of_imports", myimport);
|
||||||
|
linker->defineSymbol("compressed_imports", cimports);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
patch_le32(loader, codesize, "VALL", myimport + get_le32(oimpdlls + 16) + 12);
|
patch_le32(loader, codesize, "VALL", myimport + get_le32(oimpdlls + 16) + 12);
|
||||||
patch_le32(loader, codesize, "VFRE", myimport + get_le32(oimpdlls + 16) + 16);
|
patch_le32(loader, codesize, "VFRE", myimport + get_le32(oimpdlls + 16) + 16);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (patchFilter32(loader, codesize, &ft))
|
defineFilterSymbols(linker, &ft);
|
||||||
{
|
linker->defineSymbol("filter_buffer_start", ih.codebase - rvamin);
|
||||||
const unsigned texv = ih.codebase - rvamin;
|
// FIXME patchDecompressor(loader, codesize);
|
||||||
if (texv)
|
|
||||||
patch_le32(loader, codesize, "TEXV", texv);
|
|
||||||
}
|
// in case of overlapping decompression, this hack is needed,
|
||||||
patchDecompressor(loader, codesize);
|
// because windoze zeroes the word pointed by tlsindex before
|
||||||
if (tlsindex)
|
// it starts programs
|
||||||
{
|
linker->defineSymbol("tls_value", (tlsindex + 4 > s1addr) ?
|
||||||
// in case of overlapping decompression, this hack is needed,
|
get_le32(obuf + tlsindex - s1addr - ic) : 0);
|
||||||
// because windoze zeroes the word pointed by tlsindex before
|
linker->defineSymbol("tls_address", tlsindex - rvamin);
|
||||||
// it starts programs
|
|
||||||
if (tlsindex + 4 > s1addr)
|
linker->defineSymbol("icon_delta", icondir_count - 1);
|
||||||
patch_le32(loader,codesize,"TLSV",get_le32(obuf + tlsindex - s1addr - ic));
|
linker->defineSymbol("icon_offset", ncsection + icondir_offset - rvamin);
|
||||||
else
|
|
||||||
patch_le32(loader,codesize,"TLSV",0); // bad guess
|
|
||||||
patch_le32(loader,codesize,"TLSA",tlsindex - rvamin);
|
|
||||||
}
|
|
||||||
if (icondir_count > 1)
|
|
||||||
{
|
|
||||||
if (icondir_count > 2)
|
|
||||||
patch_le16(loader,codesize,"DR",icondir_count - 1);
|
|
||||||
patch_le32(loader,codesize,"ICON",ncsection + icondir_offset - rvamin);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned esi0 = s1addr + ic;
|
const unsigned esi0 = s1addr + ic;
|
||||||
patch_le32(loader,codesize,"EDI0", 0u - esi0 + rvamin);
|
linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);
|
||||||
patch_le32(loader,codesize,"ESI0", esi0 + ih.imagebase);
|
linker->defineSymbol("start_of_compressed", esi0 + ih.imagebase);
|
||||||
ic = getLoaderSection("PEMAIN01") + 2 + upxsection;
|
|
||||||
|
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
|
||||||
|
linker->relocate();
|
||||||
|
|
||||||
|
const unsigned lsize = getLoaderSize();
|
||||||
|
MemBuffer loader(lsize);
|
||||||
|
memcpy(loader,getLoader(),lsize);
|
||||||
|
patchPackHeader(loader, lsize);
|
||||||
|
|
||||||
Reloc rel(1024); // new relocations are put here
|
Reloc rel(1024); // new relocations are put here
|
||||||
rel.add(ic,3);
|
rel.add(linker->getSymbolOffset("PEMAIN01") + 2, 3);
|
||||||
|
|
||||||
// new PE header
|
// new PE header
|
||||||
memcpy(&oh,&ih,sizeof(oh));
|
memcpy(&oh,&ih,sizeof(oh));
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ protected:
|
|||||||
virtual bool testUnpackVersion(int version) const;
|
virtual bool testUnpackVersion(int version) const;
|
||||||
|
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
|
||||||
unsigned pe_offset;
|
unsigned pe_offset;
|
||||||
bool isrtm;
|
bool isrtm;
|
||||||
|
|||||||
+5
-3
@@ -509,9 +509,11 @@ i386-linux.kernel%.h : $(srcdir)/src/$$T.asm
|
|||||||
i386-win32.pe% : tc_list = arch-i386 default
|
i386-win32.pe% : tc_list = arch-i386 default
|
||||||
|
|
||||||
i386-win32.pe.h : $(srcdir)/src/$$T.asm
|
i386-win32.pe.h : $(srcdir)/src/$$T.asm
|
||||||
$(call tc,pp-nasm) --MMD=$@ $< -o tmp/$T.tmp1
|
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin
|
||||||
$(call tc,app-nasm) tmp/$T.tmp1 tmp/$T.tmp2
|
$(call tc,m-objcopy) --strip-unneeded tmp/$T.bin
|
||||||
$(call tc,nasm) -f bin -l tmp/$T.bin.lst tmp/$T.tmp2 -o 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 $@
|
$(call tc,bin2h) --ident=nrv_loader tmp/$T.bin $@
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1473
-629
File diff suppressed because it is too large
Load Diff
+127
-163
@@ -1,3 +1,4 @@
|
|||||||
|
/*
|
||||||
; l_w32pe.asm -- loader & decompressor for the w32/pe format
|
; l_w32pe.asm -- loader & decompressor for the w32/pe format
|
||||||
;
|
;
|
||||||
; This file is part of the UPX executable compressor.
|
; This file is part of the UPX executable compressor.
|
||||||
@@ -24,267 +25,230 @@
|
|||||||
; Markus F.X.J. Oberhumer Laszlo Molnar
|
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||||
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
;
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UPX102 1
|
||||||
|
#include "arch/i386/macros2.ash"
|
||||||
|
|
||||||
%define UPX102 1
|
|
||||||
%define jmps jmp short
|
|
||||||
%define jmpn jmp near
|
|
||||||
%define jnzn jnz near
|
|
||||||
%define jbn jb near
|
|
||||||
%include "arch/i386/macros.ash"
|
|
||||||
|
|
||||||
BITS 32
|
|
||||||
SECTION .text
|
|
||||||
ORG 0
|
|
||||||
CPU 386
|
CPU 386
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
; ============= ENTRY POINT
|
// ============= ENTRY POINT
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
%ifdef __PEISDLL1__
|
section PEISDLL1
|
||||||
cmp byte [esp + 8], 1
|
cmpb [esp + 8], 1
|
||||||
jnzn reloc_end_jmp
|
jnz reloc_end_jmp
|
||||||
%endif; __PEMAIN01__
|
section PEMAIN01
|
||||||
pushad
|
pusha
|
||||||
mov esi, 'ESI0' ; relocated
|
mov esi, offset start_of_compressed // relocated
|
||||||
lea edi, [esi + 'EDI0']
|
lea edi, [esi + start_of_uncompressed]
|
||||||
%ifdef __PEICONS1__
|
section PEICONS1
|
||||||
inc word [edi + 'ICON']
|
incw [edi + icon_offset]
|
||||||
%else; __PEICONS2__
|
section PEICONS2
|
||||||
add word [edi + 'ICON'],'DR'
|
addw [edi + icon_offset], offset icon_delta
|
||||||
%endif; __PEICONSZ__
|
section PETLSHAK
|
||||||
%ifdef __PETLSHAK__
|
movw [edi + tls_address], offset tls_value
|
||||||
mov dword [edi + 'TLSA'],'TLSV'
|
section PEMAIN02
|
||||||
%endif; __PEMAIN02__
|
|
||||||
push edi
|
push edi
|
||||||
mpass:
|
or ebp, -1
|
||||||
or ebp, byte -1
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
; ============= DECOMPRESSION
|
// ============= DECOMPRESSION
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
%include "arch/i386/nrv2b_d32.ash"
|
//#include "arch/i386/nrv2b_d32.ash"
|
||||||
%include "arch/i386/nrv2d_d32.ash"
|
//#include "arch/i386/nrv2d_d32.ash"
|
||||||
%include "arch/i386/nrv2e_d32.ash"
|
//#include "arch/i386/nrv2e_d32.ash"
|
||||||
%include "arch/i386/lzma_d.ash"
|
#include "arch/i386/nrv2e_d32_2.ash"
|
||||||
|
//#include "arch/i386/lzma_d.ash"
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
|
section PEMAIN10
|
||||||
|
pop esi // load vaddr
|
||||||
|
|
||||||
%ifdef __PEMULTIP__
|
// =============
|
||||||
lodsd
|
// ============= CALLTRICK
|
||||||
add edi, eax
|
// =============
|
||||||
jbn mpass
|
|
||||||
%endif; __PEMAIN10__
|
|
||||||
|
|
||||||
; =============
|
section PECTTPOS
|
||||||
pop esi ; load vaddr
|
lea edi, [esi + filter_buffer_start]
|
||||||
|
section PECTTNUL
|
||||||
; =============
|
|
||||||
; ============= CALLTRICK
|
|
||||||
; =============
|
|
||||||
|
|
||||||
%ifdef __PECALLTR__
|
|
||||||
%ifdef __PECTTPOS__
|
|
||||||
lea edi, [esi + 'TEXV']
|
|
||||||
%else; __PECTTNUL__
|
|
||||||
mov edi, esi
|
mov edi, esi
|
||||||
%endif; __PEDUMMY0__
|
// section PEDUMMY0
|
||||||
cjt32 esi
|
cjt32 esi
|
||||||
%endif; __PEDUMMY1__
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
; ============= IMPORTS
|
// ============= IMPORTS
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
%ifdef __PEIMPORT__
|
section PEIMPORT
|
||||||
lea edi, [esi + 'BIMP']
|
lea edi, [esi + compressed_imports]
|
||||||
next_dll:
|
next_dll:
|
||||||
mov eax, [edi]
|
mov eax, [edi]
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jz imports_done
|
jzs imports_done
|
||||||
mov ebx, [edi+4] ; iat
|
mov ebx, [edi+4] // iat
|
||||||
lea eax, [eax + esi + 'IMPS']
|
lea eax, [eax + esi + start_of_imports]
|
||||||
add ebx, esi
|
add ebx, esi
|
||||||
push eax
|
push eax
|
||||||
add edi, byte 8
|
add edi, 8
|
||||||
call [esi + 'LOAD'] ; LoadLibraryA
|
call [esi + LoadLibraryA]
|
||||||
xchg eax, ebp
|
xchg eax, ebp
|
||||||
next_func:
|
next_func:
|
||||||
mov al, [edi]
|
mov al, [edi]
|
||||||
inc edi
|
inc edi
|
||||||
or al, al
|
or al, al
|
||||||
jz next_dll
|
jz next_dll
|
||||||
mov ecx, edi ; something > 0
|
mov ecx, edi // something > 0
|
||||||
%ifdef __PEIBYORD__
|
section PEIBYORD
|
||||||
jns byname
|
jnss byname
|
||||||
%ifdef __PEK32ORD__
|
section PEK32ORD
|
||||||
jpe not_kernel32
|
jpe not_kernel32
|
||||||
mov eax, [edi]
|
mov eax, [edi]
|
||||||
add edi, byte 4
|
add edi, 4
|
||||||
mov eax, [eax + esi + 'K32O']
|
mov eax, [eax + esi + kernel32_ordinals]
|
||||||
jmps next_imp
|
jmps next_imp
|
||||||
not_kernel32:
|
not_kernel32:
|
||||||
%endif; __PEIMORD1__
|
section PEIMORD1
|
||||||
movzx eax, word [edi]
|
movzxw eax, [edi]
|
||||||
inc edi
|
inc edi
|
||||||
push eax
|
push eax
|
||||||
inc edi
|
inc edi
|
||||||
db 0xb9 ; mov ecx,xxxx
|
.byte 0xb9 // mov ecx,xxxx
|
||||||
byname:
|
byname:
|
||||||
%endif; __PEIMPOR2__
|
section PEIMPOR2
|
||||||
push edi
|
push edi
|
||||||
dec eax
|
dec eax
|
||||||
repne
|
repne
|
||||||
scasb
|
scasb
|
||||||
|
|
||||||
push ebp
|
push ebp
|
||||||
call [esi + 'GETP'] ; GetProcAddr
|
call [esi + GetProcAddress]
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jz imp_failed
|
jz imp_failed
|
||||||
next_imp:
|
next_imp:
|
||||||
mov [ebx], eax
|
mov [ebx], eax
|
||||||
add ebx, byte 4
|
add ebx, 4
|
||||||
jmps next_func
|
jmps next_func
|
||||||
imp_failed:
|
imp_failed:
|
||||||
%ifdef __PEIERDLL__
|
section PEIERDLL
|
||||||
popad
|
popa
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
retn 0x0c
|
ret 0x0c
|
||||||
%else; __PEIEREXE__
|
section PEIEREXE
|
||||||
call [esi + 'EXIT'] ; ExitProcess
|
call [esi + ExitProcess]
|
||||||
%endif; __PEIMDONE__
|
section PEIMDONE
|
||||||
imports_done:
|
imports_done:
|
||||||
%endif; __PEIMPOR9__
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
; ============= RELOCATION
|
// ============= RELOCATION
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
%ifdef __PERELOC1__
|
section PERELOC1
|
||||||
lea edi, [esi + 'BREL']
|
lea edi, [esi + start_of_relocs]
|
||||||
; __PERELOC2__
|
section PERELOC2
|
||||||
add edi, byte 4
|
add edi, 4
|
||||||
; __PERELOC3__
|
section PERELOC3
|
||||||
lea ebx, [esi - 4]
|
lea ebx, [esi - 4]
|
||||||
reloc32 edi, ebx, esi
|
reloc32 edi, ebx, esi
|
||||||
%endif; __PERELOC9__
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
; FIXME: depends on that in PERELOC1 edi is set!!
|
// FIXME: depends on that in PERELOC1 edi is set!!
|
||||||
%ifdef __PERLOHI0__
|
section PERLOHI0
|
||||||
xchg edi, esi
|
xchg edi, esi
|
||||||
lea ecx, [edi + 'DELT']
|
lea ecx, [edi + reloc_delt]
|
||||||
%endif; __PERLOHIZ__
|
|
||||||
|
|
||||||
%ifdef __PERELLO0__
|
section PERELLO0
|
||||||
db 0xA9
|
.byte 0xA9
|
||||||
rello0:
|
rello0:
|
||||||
add [edi + eax], cx
|
add [edi + eax], cx
|
||||||
lodsd
|
lodsd
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jnz rello0
|
jnz rello0
|
||||||
%endif; __PERELLOZ__
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
%ifdef __PERELHI0__
|
section PERELHI0
|
||||||
shr ecx, 16
|
shr ecx, 16
|
||||||
db 0xA9
|
.byte 0xA9
|
||||||
relhi0:
|
relhi0:
|
||||||
add [edi + eax], cx
|
add [edi + eax], cx
|
||||||
lodsd
|
lodsd
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jnz relhi0
|
jnz relhi0
|
||||||
%endif; __PERELHIZ__
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
%ifdef __PEDEPHAK__
|
section PEDEPHAK
|
||||||
mov ebp, [esi + 'VPRO'] ; VirtualProtect
|
mov ebp, [esi + VirtualProtect]
|
||||||
lea edi, [esi + 'IMGB']
|
lea edi, [esi + vp_base]
|
||||||
mov ebx, 'IMGL' ; 0x1000 or 0x2000
|
mov ebx, offset vp_size // 0x1000 or 0x2000
|
||||||
|
|
||||||
push eax ; provide 4 bytes stack
|
push eax // provide 4 bytes stack
|
||||||
|
|
||||||
push esp ; &lpflOldProtect on stack
|
push esp // &lpflOldProtect on stack
|
||||||
push byte 4 ; PAGE_READWRITE
|
push 4 // PAGE_READWRITE
|
||||||
push ebx
|
push ebx
|
||||||
push edi
|
push edi
|
||||||
call ebp
|
call ebp
|
||||||
|
|
||||||
%if 0
|
#if 0
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jz pedep9 ; VirtualProtect failed
|
jz pedep9 // VirtualProtect failed
|
||||||
%endif
|
#endif
|
||||||
|
|
||||||
lea eax, [edi + 'SWRI']
|
lea eax, [edi + swri]
|
||||||
and byte [eax], 0x7f ; marks UPX0 non writeable
|
andb [eax], 0x7f // marks UPX0 non writeable
|
||||||
and byte [eax + 0x28], 0x7f ; marks UPX1 non writeable
|
andb [eax + 0x28], 0x7f // marks UPX1 non writeable
|
||||||
|
|
||||||
%if 0
|
#if 0
|
||||||
push esp
|
push esp
|
||||||
push byte 2 ; PAGE_READONLY
|
push 2 // PAGE_READONLY
|
||||||
%else
|
#else
|
||||||
pop eax
|
pop eax
|
||||||
push eax
|
push eax
|
||||||
push esp
|
push esp
|
||||||
push eax ; restore protection
|
push eax // restore protection
|
||||||
%endif
|
#endif
|
||||||
push ebx
|
push ebx
|
||||||
push edi
|
push edi
|
||||||
call ebp
|
call ebp
|
||||||
|
|
||||||
pedep9:
|
pedep9:
|
||||||
pop eax ; restore stack
|
pop eax // restore stack
|
||||||
%endif; __PEDEPHAX__
|
|
||||||
|
|
||||||
; __PEMAIN20__
|
section PEMAIN20
|
||||||
popad
|
popa
|
||||||
|
|
||||||
|
|
||||||
; clear the dirty stack
|
// clear the dirty stack
|
||||||
%macro clearstack128 1
|
.macro clearstack128 tmp_reg
|
||||||
lea %1, [esp - 128]
|
lea \tmp_reg, [esp - 128]
|
||||||
%%clearst0:
|
c1:
|
||||||
push byte 0
|
push 0
|
||||||
cmp esp, %1
|
cmp esp, \tmp_reg
|
||||||
jnz %%clearst0
|
jnzs c1
|
||||||
sub esp, byte -128
|
sub esp, -128
|
||||||
%endmacro
|
.endm
|
||||||
|
|
||||||
%ifdef __PERETURN_CLEARSTACK__
|
section CLEARSTACK
|
||||||
clearstack128 eax
|
clearstack128 eax
|
||||||
%endif; __PERETURN_CLEARSTACK9__
|
|
||||||
%ifdef __PEDOJUMP_CLEARSTACK__
|
|
||||||
clearstack128 eax
|
|
||||||
%endif; __PEDOJUMP_CLEARSTACK9__
|
|
||||||
|
|
||||||
|
section PEMAIN21
|
||||||
; __PEMAIN21__
|
|
||||||
reloc_end_jmp:
|
reloc_end_jmp:
|
||||||
|
|
||||||
%ifdef __PERETURN__
|
section PERETURN
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
retn 0x0C
|
ret 0x0C
|
||||||
%else; __PEDOJUMP__
|
section PEDOJUMP
|
||||||
jmpn .1+'JMPO'
|
jmp original_entry
|
||||||
.1:
|
|
||||||
%endif; __PEDUMMY3__
|
|
||||||
|
|
||||||
; =============
|
// =============
|
||||||
; ============= CUT HERE
|
// ============= CUT HERE
|
||||||
; =============
|
// =============
|
||||||
|
|
||||||
%include "include/header.ash"
|
#include "include/header2.ash"
|
||||||
|
|
||||||
eof:
|
// vi:ts=8:et:nowrap
|
||||||
; __PETHEEND__
|
|
||||||
section .data
|
|
||||||
dd -1
|
|
||||||
dw eof
|
|
||||||
|
|
||||||
|
|
||||||
; vi:ts=8:et:nowrap
|
|
||||||
|
|||||||
Reference in New Issue
Block a user