mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
64 relocation handling added; basic DLL support works
This commit is contained in:
parent
5b8a9c0b47
commit
241834029a
|
@ -562,7 +562,7 @@ void PackW64Pep::processTls(Interval *iv) // pass 1
|
|||
|
||||
// makes sure tls index is zero after decompression
|
||||
if (tlsindex && tlsindex < ih.imagesize)
|
||||
set_le64(ibuf + tlsindex, 0); //changed to LE64 - Stefan Widmann
|
||||
set_le32(ibuf + tlsindex, 0);
|
||||
}
|
||||
|
||||
void PackW64Pep::processTls(Reloc *rel,const Interval *iv,unsigned newaddr) // pass 2
|
||||
|
@ -602,7 +602,7 @@ void PackW64Pep::processTls(Reloc *rel,const Interval *iv,unsigned newaddr) // p
|
|||
if (use_tls_callbacks)
|
||||
{
|
||||
//set handler offset
|
||||
set_le32(otls + sotls - 16, tls_handler_offset + ih.imagebase);
|
||||
set_le64(otls + sotls - 16, tls_handler_offset + ih.imagebase);
|
||||
//add relocation for TLS handler offset
|
||||
rel->add(newaddr + sotls - 16, 10);
|
||||
}
|
||||
|
@ -662,7 +662,7 @@ void PackW64Pep::processLoadConf(Reloc *rel, const Interval *iv,
|
|||
bool PackW64Pep::canPack()
|
||||
{
|
||||
//just check if machine type is 0x8664
|
||||
if (!readFileHeader() || ih.cpu != 0x8664) // CPU magic of AMD64 is 0x8664
|
||||
if (!readFileHeader() || ih.cpu != 0x8664) // CPU magic of AMD64 is 0x8664
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -679,6 +679,9 @@ void PackW64Pep::buildLoader(const Filter *ft)
|
|||
|
||||
// prepare loader
|
||||
initLoader(stub_amd64_win64_pep, sizeof(stub_amd64_win64_pep), 2);
|
||||
addLoader("START");
|
||||
if (ih.entry && isdll)
|
||||
addLoader("PEISDLL0");
|
||||
addLoader(isdll ? "PEISDLL1" : "",
|
||||
"PEMAIN01",
|
||||
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
||||
|
@ -712,17 +715,19 @@ void PackW64Pep::buildLoader(const Filter *ft)
|
|||
if (sorelocs)
|
||||
{
|
||||
addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2",
|
||||
"PERELOC3,RELOC320",
|
||||
big_relocs ? "REL32BIG" : "",
|
||||
"RELOC32J",
|
||||
NULL
|
||||
);
|
||||
//FIXME: the following should be moved out of the above if
|
||||
addLoader(big_relocs&6 ? "PERLOHI0" : "",
|
||||
big_relocs&4 ? "PERELLO0" : "",
|
||||
big_relocs&2 ? "PERELHI0" : "",
|
||||
"PERELOC3",
|
||||
big_relocs ? "REL64BIG" : "",
|
||||
"RELOC64J",
|
||||
NULL
|
||||
);
|
||||
if (0)
|
||||
{
|
||||
addLoader(big_relocs&6 ? "PERLOHI0" : "",
|
||||
big_relocs&4 ? "PERELLO0" : "",
|
||||
big_relocs&2 ? "PERELHI0" : "",
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
if (use_dep_hack)
|
||||
addLoader("PEDEPHAK", NULL);
|
||||
|
@ -736,7 +741,8 @@ void PackW64Pep::buildLoader(const Filter *ft)
|
|||
addLoader("CLEARSTACK", NULL);
|
||||
addLoader("PEMAIN21", NULL);
|
||||
|
||||
//NEW: last loader sections split up to insert TLS callback handler - Stefan Widmann
|
||||
if (ih.entry && isdll)
|
||||
addLoader("PEISDLL9");
|
||||
addLoader(ih.entry ? "PEDOJUMP" : "PERETURN", NULL);
|
||||
|
||||
//NEW: TLS callback support PART 2, the callback handler - Stefan Widmann
|
||||
|
@ -744,7 +750,6 @@ void PackW64Pep::buildLoader(const Filter *ft)
|
|||
addLoader("PETLSC2", NULL);
|
||||
|
||||
addLoader("IDENTSTR,UPX1HEAD", NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -855,7 +860,7 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
throwCantPack(".NET files (win64/.net) are not yet supported");
|
||||
|
||||
//FIXME: Relocation stripping disabled yet - Stefan Widmann
|
||||
opt->win32_pe.strip_relocs = true;//false;
|
||||
opt->win32_pe.strip_relocs = false;
|
||||
#if 0 //removed - Stefan Widmann
|
||||
if (isdll)
|
||||
opt->win32_pe.strip_relocs = false;
|
||||
|
@ -1073,7 +1078,7 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);
|
||||
obuf.clear(ph.c_len, c_len - ph.c_len);
|
||||
|
||||
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls + soloadconf;
|
||||
const unsigned s1size = ALIGN_UP(ic + c_len + codesize,8u) + sotls + soloadconf;
|
||||
const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;
|
||||
|
||||
const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;
|
||||
|
@ -1110,7 +1115,7 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
0x2000 : 0x1000); // 2 pages or 1 page
|
||||
linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask
|
||||
//NEW: offset of import adjusted - Stefan Widmann
|
||||
linker->defineSymbol("VirtualProtect", myimport + get_le32(oimpdlls + 16) + 16);
|
||||
linker->defineSymbol("VirtualProtect", myimport + get_le32(oimpdlls + 16) + 16);
|
||||
}
|
||||
// FIXME linker->defineSymbol("reloc_delt", 0u - (unsigned) (ih.imagebase - rvamin));
|
||||
linker->defineSymbol("start_of_relocs", crelocs);
|
||||
|
@ -1146,16 +1151,16 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
|
||||
const unsigned esi0 = s1addr + ic;
|
||||
linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);
|
||||
linker->defineSymbol("start_of_compressed", esi0 + ih.imagebase);
|
||||
linker->defineSymbol("start_of_compressed", esi0);
|
||||
//NEW: TLS callback support - Stefan Widmann
|
||||
ic = s1addr + s1size - sotls - soloadconf; //moved here, we need the address of the new TLS!
|
||||
if (use_tls_callbacks)
|
||||
{
|
||||
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr);
|
||||
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr - ih.imagebase);
|
||||
linker->defineSymbol("tls_module_base", 0u - rvamin);
|
||||
}
|
||||
|
||||
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
|
||||
linker->defineSymbol("START", upxsection);
|
||||
//linker->dumpSymbols();
|
||||
relocateLoader();
|
||||
|
||||
|
@ -1165,7 +1170,6 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
patchPackHeader(loader, lsize);
|
||||
|
||||
Reloc rel(1024); // new relocations are put here
|
||||
rel.add(linker->getSymbolOffset("PEMAIN01") + 6, 10); // FIXME
|
||||
|
||||
// new PE header
|
||||
memcpy(&oh,&ih,sizeof(oh));
|
||||
|
@ -1187,6 +1191,10 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
//EXCEPTION DIRECTORY HANDLING - Stefan Widmann
|
||||
//APPROACH 1: just keep the exception directory, it's only used during runtime, not during init
|
||||
// -> nothing to do
|
||||
#if 0
|
||||
ODADDR(PEDIR_EXCEPTION) = 0;
|
||||
ODSIZE(PEDIR_EXCEPTION) = 0;
|
||||
#endif
|
||||
#if 0
|
||||
//APPROACH 2: we remove the exception directory from the header, the stub installs the table
|
||||
// after decompression by calling RtlAddFunctionTable (see MSDN for details)
|
||||
|
@ -1202,13 +1210,8 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
// tls & loadconf are put into section 1
|
||||
|
||||
//ic = s1addr + s1size - sotls - soloadconf; //ATTENTION: moved upwards to TLS callback handling - Stefan Widmann
|
||||
//get address of TLS callback handler
|
||||
if (use_tls_callbacks)
|
||||
{
|
||||
tls_handler_offset = linker->getSymbolOffset("PETLSC2");
|
||||
//add relocation entry for TLS callback handler
|
||||
rel.add(tls_handler_offset + 5, 10);
|
||||
}
|
||||
|
||||
processTls(&rel,&tlsiv,ic);
|
||||
ODADDR(PEDIR_TLS) = sotls ? ic : 0;
|
||||
|
@ -1331,8 +1334,8 @@ void PackW64Pep::pack(OutputFile *fo)
|
|||
fo->write(loader,codesize);
|
||||
if (opt->debug.dump_stub_loader)
|
||||
OutputFile::dump(opt->debug.dump_stub_loader, loader, codesize);
|
||||
if ((ic = fo->getBytesWritten() & 3) != 0)
|
||||
fo->write(ibuf,4 - ic);
|
||||
if ((ic = fo->getBytesWritten() & 7) != 0)
|
||||
fo->write(ibuf,8 - ic);
|
||||
fo->write(otls,sotls);
|
||||
fo->write(oloadconf, soloadconf);
|
||||
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)
|
||||
|
|
|
@ -904,9 +904,9 @@ int Packer::patch_le32(void *b, int blen, const void *old, unsigned new_)
|
|||
// relocation util
|
||||
**************************************************************************/
|
||||
|
||||
upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum,
|
||||
upx_byte *out, upx_byte *image,
|
||||
int bswap, int *big)
|
||||
upx_byte *Packer::optimizeReloc(upx_byte *in, unsigned relocnum,
|
||||
upx_byte *out, upx_byte *image,
|
||||
int bswap, int *big, int bits)
|
||||
{
|
||||
if (opt->exact)
|
||||
throwCantPackExact();
|
||||
|
@ -946,15 +946,36 @@ upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum,
|
|||
}
|
||||
pc += oc;
|
||||
if (bswap)
|
||||
acc_ua_swab32s(image + pc);
|
||||
{
|
||||
if (bits == 32)
|
||||
acc_ua_swab32s(image + pc);
|
||||
else if (bits == 64)
|
||||
set_be64(image + pc, get_le64(image + pc));
|
||||
else
|
||||
throwInternalError("optimizeReloc problem");
|
||||
}
|
||||
}
|
||||
*fix++ = 0;
|
||||
return fix;
|
||||
}
|
||||
|
||||
upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum,
|
||||
upx_byte *out, upx_byte *image,
|
||||
int bswap, int *big)
|
||||
{
|
||||
return optimizeReloc(in, relocnum, out, image, bswap, big, 32);
|
||||
}
|
||||
|
||||
unsigned Packer::unoptimizeReloc32(upx_byte **in, upx_byte *image,
|
||||
MemBuffer *out, int bswap)
|
||||
upx_byte *Packer::optimizeReloc64(upx_byte *in, unsigned relocnum,
|
||||
upx_byte *out, upx_byte *image,
|
||||
int bswap, int *big)
|
||||
{
|
||||
return optimizeReloc(in, relocnum, out, image, bswap, big, 64);
|
||||
}
|
||||
|
||||
|
||||
unsigned Packer::unoptimizeReloc(upx_byte **in, upx_byte *image,
|
||||
MemBuffer *out, int bswap, int bits)
|
||||
{
|
||||
upx_byte *p;
|
||||
unsigned relocn = 0;
|
||||
|
@ -987,13 +1008,31 @@ unsigned Packer::unoptimizeReloc32(upx_byte **in, upx_byte *image,
|
|||
}
|
||||
*relocs++ = jc;
|
||||
if (bswap && image)
|
||||
acc_ua_swab32s(image + jc);
|
||||
{
|
||||
if (bits == 32)
|
||||
acc_ua_swab32s(image + jc);
|
||||
else if (bits == 64)
|
||||
set_be64(image + jc, get_le64(image + jc));
|
||||
else
|
||||
throwInternalError("unoptimizeReloc problem");
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"relocnum=%x\n",relocn);
|
||||
*in = p+1;
|
||||
return (unsigned) (relocs - outp);
|
||||
}
|
||||
|
||||
unsigned Packer::unoptimizeReloc32(upx_byte **in, upx_byte *image,
|
||||
MemBuffer *out, int bswap)
|
||||
{
|
||||
return unoptimizeReloc(in, image, out, bswap, 32);
|
||||
}
|
||||
|
||||
unsigned Packer::unoptimizeReloc64(upx_byte **in, upx_byte *image,
|
||||
MemBuffer *out, int bswap)
|
||||
{
|
||||
return unoptimizeReloc(in, image, out, bswap, 64);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// loader util (interface to linker)
|
||||
|
|
|
@ -284,8 +284,12 @@ protected:
|
|||
void checkPatch(void *b, int blen, int boff, int size);
|
||||
|
||||
// relocation util
|
||||
static upx_byte *optimizeReloc(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big, int bits);
|
||||
static unsigned unoptimizeReloc(upx_byte **in,upx_byte *image,MemBuffer *out,int bs, int bits);
|
||||
static upx_byte *optimizeReloc32(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big);
|
||||
static unsigned unoptimizeReloc32(upx_byte **in,upx_byte *image,MemBuffer *out,int bs);
|
||||
static upx_byte *optimizeReloc64(upx_byte *in,unsigned relocnum,upx_byte *out,upx_byte *image,int bs,int *big);
|
||||
static unsigned unoptimizeReloc64(upx_byte **in,upx_byte *image,MemBuffer *out,int bs);
|
||||
|
||||
// target endianness abstraction
|
||||
unsigned get_te16(const void *p) const { return bele->get16(p); }
|
||||
|
|
|
@ -389,7 +389,11 @@ void PepFile::processRelocs() // pass1
|
|||
|
||||
Reloc rel(ibuf + IDADDR(PEDIR_RELOC),IDSIZE(PEDIR_RELOC));
|
||||
const unsigned *counts = rel.getcounts();
|
||||
const unsigned rnum = counts[1] + counts[2] + counts[3];
|
||||
unsigned rnum = 0;
|
||||
|
||||
unsigned ic;
|
||||
for (ic = 1; ic < 16; ic++)
|
||||
rnum += counts[ic];
|
||||
|
||||
if ((opt->win32_pe.strip_relocs && !isdll) || rnum == 0)
|
||||
{
|
||||
|
@ -400,30 +404,32 @@ void PepFile::processRelocs() // pass1
|
|||
return;
|
||||
}
|
||||
|
||||
unsigned ic;
|
||||
for (ic = 15; ic > 3; ic--)
|
||||
if (counts[ic])
|
||||
for (ic = 15; ic; ic--)
|
||||
if (counts[ic] != 10)
|
||||
infoWarning("skipping unsupported relocation type %d (%d)",ic,counts[ic]);
|
||||
|
||||
LE32 *fix[4];
|
||||
for (; ic; ic--)
|
||||
LE32 *fix[16];
|
||||
for (ic = 15; ic; ic--)
|
||||
fix[ic] = new LE32 [counts[ic]];
|
||||
|
||||
unsigned xcounts[4];
|
||||
unsigned xcounts[16];
|
||||
memset(xcounts, 0, sizeof(xcounts));
|
||||
|
||||
// prepare sorting
|
||||
unsigned pos,type;
|
||||
while (rel.next(pos,type))
|
||||
{
|
||||
// FIXME add check for relocations which try to modify the
|
||||
// PE header or other relocation records
|
||||
|
||||
if (pos >= ih.imagesize)
|
||||
continue; // skip out-of-bounds record
|
||||
if (type < 4)
|
||||
if (type < 16)
|
||||
fix[type][xcounts[type]++] = pos - rvamin;
|
||||
}
|
||||
|
||||
// remove duplicated records
|
||||
for (ic = 1; ic <= 3; ic++)
|
||||
for (ic = 1; ic <= 15; ic++)
|
||||
{
|
||||
qsort(fix[ic], xcounts[ic], 4, le32_compare);
|
||||
unsigned prev = ~0;
|
||||
|
@ -436,20 +442,23 @@ void PepFile::processRelocs() // pass1
|
|||
xcounts[ic] = jc;
|
||||
}
|
||||
|
||||
// preprocess "type 3" relocation records
|
||||
for (ic = 0; ic < xcounts[3]; ic++)
|
||||
// preprocess "type 10" relocation records
|
||||
for (ic = 0; ic < xcounts[10]; ic++)
|
||||
{
|
||||
pos = fix[3][ic] + rvamin;
|
||||
set_le32(ibuf + pos, get_le32(ibuf + pos) - ih.imagebase - rvamin);
|
||||
pos = fix[10][ic] + rvamin;
|
||||
set_le64(ibuf + pos, get_le64(ibuf + pos) - ih.imagebase - rvamin);
|
||||
}
|
||||
|
||||
ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL);
|
||||
orelocs = new upx_byte [rnum * 4 + 1024]; // 1024 - safety
|
||||
sorelocs = ptr_diff(optimizeReloc32((upx_byte*) fix[3], xcounts[3],
|
||||
sorelocs = ptr_diff(optimizeReloc64((upx_byte*) fix[10], xcounts[10],
|
||||
orelocs, ibuf + rvamin,1, &big_relocs),
|
||||
orelocs);
|
||||
delete [] fix[3];
|
||||
|
||||
for (ic = 15; ic; ic--)
|
||||
delete [] fix[ic];
|
||||
|
||||
#if 0
|
||||
// Malware that hides behind UPX often has PE header info that is
|
||||
// deliberately corrupt. Sometimes it is even tuned to cause us trouble!
|
||||
// Use an extra check to avoid AccessViolation (SIGSEGV) when appending
|
||||
|
@ -471,6 +480,7 @@ void PepFile::processRelocs() // pass1
|
|||
big_relocs |= 2 * ic;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
info("Relocations: original size: %u bytes, preprocessed size: %u bytes",(unsigned) IDSIZE(PEDIR_RELOC),sorelocs);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -57,12 +57,24 @@
|
|||
|
||||
#define SHORT(label) $ + 1; .reloc $ - 1, R_X86_64_PC8, label
|
||||
|
||||
//; debugging is not too user friendly under wine:
|
||||
//; by adding the "DEBUG" macro into the code
|
||||
//; an exception will be raised, and a register dump is printed
|
||||
//; WINEDEBUG=trace+seh wine x.exe &> x.debug
|
||||
#define DEBUG movb [0], 0
|
||||
|
||||
.intel_syntax noprefix
|
||||
|
||||
// =============
|
||||
// ============= ENTRY POINT
|
||||
// =============
|
||||
|
||||
section START
|
||||
section PEISDLL0
|
||||
mov [rsp + 8], rcx
|
||||
mov [rsp + 0x10], rdx
|
||||
mov [rsp + 0x18], r8
|
||||
|
||||
section PEISDLL1
|
||||
cmp dl, 1
|
||||
jnz reloc_end_jmp
|
||||
|
@ -72,7 +84,7 @@ section PEMAIN01
|
|||
push rsi
|
||||
push rdi
|
||||
push rbp
|
||||
movabs rsi, IMM64(start_of_compressed) //; relocated
|
||||
lea rsi, [rip + start_of_compressed]
|
||||
lea rdi, [rsi + start_of_uncompressed]
|
||||
|
||||
section PEICONS1
|
||||
|
@ -80,6 +92,9 @@ section PEICONS1
|
|||
section PEICONS2
|
||||
add [rdi + icon_offset], IMM16(icon_delta)
|
||||
section PETLSHAK
|
||||
//; mov r14, [rdi + tls_address]
|
||||
//; FIXME the overwritten data should be saved, and restored
|
||||
//; after decompression
|
||||
mov [rdi + tls_address], IMM32(tls_value)
|
||||
|
||||
section PEMAIN02
|
||||
|
@ -179,7 +194,7 @@ eof:
|
|||
pop rsi // load vaddr
|
||||
|
||||
// =============
|
||||
// ============= CALLTRICK
|
||||
// ============= FILTERS
|
||||
// =============
|
||||
|
||||
section PECTTPOS
|
||||
|
@ -202,6 +217,7 @@ section ctok32.00
|
|||
// =============
|
||||
|
||||
section PEIMPORT
|
||||
sub rsp, 0x28
|
||||
lea rdi, [rsi + compressed_imports]
|
||||
next_dll:
|
||||
mov eax, [rdi]
|
||||
|
@ -212,9 +228,7 @@ next_dll:
|
|||
add rbx, rsi
|
||||
add rdi, 8
|
||||
|
||||
sub rsp, 0x28
|
||||
call [rsi + LoadLibraryA]
|
||||
add rsp, 0x28
|
||||
|
||||
xchg rax, rbp
|
||||
next_func:
|
||||
|
@ -246,18 +260,20 @@ section PEIMPOR2
|
|||
first_imp:
|
||||
mov rcx, rbp
|
||||
|
||||
sub rsp, 0x28
|
||||
call [rsi + GetProcAddress]
|
||||
add rsp, 0x28
|
||||
|
||||
#if 1
|
||||
;// FIXME: is this error handling really needed?
|
||||
or rax, rax
|
||||
jz imp_failed
|
||||
#endif
|
||||
next_imp:
|
||||
mov [rbx], rax
|
||||
add rbx, 8
|
||||
jmp SHORT(next_func)
|
||||
imp_failed:
|
||||
section PEIERDLL
|
||||
add rsp, 0x28
|
||||
pop rbp
|
||||
pop rdi
|
||||
pop rsi
|
||||
|
@ -267,57 +283,78 @@ section PEIERDLL
|
|||
|
||||
section PEIEREXE
|
||||
// rcx contains garbage -> garbage return code
|
||||
sub rsp, 0x28
|
||||
call [rsi + ExitProcess]
|
||||
section PEIMDONE
|
||||
imports_done:
|
||||
add rsp, 0x28
|
||||
|
||||
// =============
|
||||
// ============= RELOCATION
|
||||
// =============
|
||||
|
||||
section PERELOC1
|
||||
lea rdi, [rsi + start_of_relocs]
|
||||
lea rdi, [rsi + start_of_relocs]
|
||||
section PERELOC2
|
||||
add rdi, 4
|
||||
add rdi, 4
|
||||
section PERELOC3
|
||||
lea rbx, [rsi - 4]
|
||||
|
||||
#if 0 //; FIXME
|
||||
reloc64 rdi, rbx, rsi
|
||||
#endif
|
||||
lea rbx, [rsi - 4]
|
||||
reloc_main:
|
||||
xor eax, eax
|
||||
mov al, [rdi]
|
||||
inc rdi
|
||||
or eax, eax
|
||||
jz SHORT(reloc_endx)
|
||||
cmp al, 0xEF
|
||||
ja reloc_fx
|
||||
reloc_add:
|
||||
add rbx, rax
|
||||
mov rax, [rbx]
|
||||
bswap rax
|
||||
add rax, rsi
|
||||
mov [rbx], rax
|
||||
jmp reloc_main
|
||||
reloc_fx:
|
||||
and al, 0x0F
|
||||
shl eax, 16
|
||||
mov ax, [rdi]
|
||||
add rdi, 2
|
||||
section REL64BIG
|
||||
or eax, eax
|
||||
jnz SHORT(reloc_add)
|
||||
mov eax, [rdi]
|
||||
add rdi, 4
|
||||
section RELOC64J
|
||||
jmp SHORT(reloc_add)
|
||||
reloc_endx:
|
||||
|
||||
|
||||
// =============
|
||||
|
||||
// FIXME: depends on that in PERELOC1 edi is set!!
|
||||
// FIXME: depends on that in PERELOC1 rdi is set!!
|
||||
section PERLOHI0
|
||||
#if 0
|
||||
xchg edi, esi
|
||||
lea ecx, [rdi + reloc_delt]
|
||||
#endif
|
||||
xchg rdi, rsi
|
||||
lea rcx, [rdi + reloc_delt]
|
||||
|
||||
section PERELLO0
|
||||
#if 0
|
||||
.byte 0xA9 //test eax, XXXXXXXX
|
||||
jmp 1f
|
||||
rello0:
|
||||
add [rdi + rax], cx //why do we just use cx instead of ecx?
|
||||
lodsd
|
||||
or eax, eax
|
||||
jnz rello0
|
||||
#endif
|
||||
add [rdi + rax], cx
|
||||
1:
|
||||
lodsd
|
||||
or eax, eax
|
||||
jnz rello0
|
||||
|
||||
// =============
|
||||
|
||||
section PERELHI0
|
||||
#if 0
|
||||
shr ecx, 16
|
||||
.byte 0xA9 //test eax, XXXXXXXX
|
||||
shr ecx, 16
|
||||
jmp 1f
|
||||
relhi0:
|
||||
add [rdi + rax], cx //why do we just use cx instead of ecx?
|
||||
lodsd
|
||||
or eax, eax
|
||||
jnz relhi0
|
||||
#endif
|
||||
add [rdi + rax], cx
|
||||
1:
|
||||
lodsd
|
||||
or eax, eax
|
||||
jnz relhi0
|
||||
|
||||
// =============
|
||||
section PEDEPHAK
|
||||
|
@ -347,6 +384,9 @@ section PEDEPHAK
|
|||
add rsp, 0x28
|
||||
|
||||
// =============
|
||||
// ============= TLS callback support part 1
|
||||
// =============
|
||||
|
||||
section PETLSC
|
||||
lea rcx, [rsi + tls_module_base] //;load module base to rcx
|
||||
lea rdi, [rcx + tls_handler_start + 1] //;load offset of handler
|
||||
|
@ -355,13 +395,15 @@ section PETLSC
|
|||
stosb
|
||||
//;emulate callbacks like PE loader would have done
|
||||
mov r8, rax //;0 - reserved
|
||||
mov edx, 1 //;DLL_PROCESS_ATTACH
|
||||
push 1 //;DLL_PROCESS_ATTACH
|
||||
pop rdx
|
||||
|
||||
push rax //;align stack
|
||||
call rdi //;contains ptr to callback handler
|
||||
pop rax
|
||||
|
||||
// =============
|
||||
// ============= Cleanup
|
||||
|
||||
section PEMAIN20
|
||||
pop rbp
|
||||
pop rdi
|
||||
|
@ -385,19 +427,28 @@ section CLEARSTACK
|
|||
section PEMAIN21
|
||||
reloc_end_jmp:
|
||||
|
||||
section PEISDLL9
|
||||
mov r8, [rsp + 0x18]
|
||||
mov rdx, [rsp + 0x10]
|
||||
mov rcx, [rsp + 8]
|
||||
|
||||
section PERETURN
|
||||
mov eax, 1
|
||||
push 1
|
||||
pop rax
|
||||
ret
|
||||
section PEDOJUMP
|
||||
jmp original_entry
|
||||
|
||||
// =============
|
||||
// ============= TLS callback support part 2
|
||||
// =============
|
||||
|
||||
section PETLSC2
|
||||
//;TLS_CALLBACK(hModule, reason, reserved)
|
||||
tls_handler_start:
|
||||
jmp end_of_tls_handler //;this jump is patched to EB 00 (jmp $+2) by stub
|
||||
push rsi
|
||||
movabs rsi, IMM64(tls_callbacks_ptr) //;must be relocated
|
||||
lea rsi, [rip + tls_callbacks_ptr]
|
||||
cld //;you never know, this code gets called by the PE loader
|
||||
walk_tlsc_chain2:
|
||||
lodsq
|
||||
|
|
|
@ -2,52 +2,61 @@ file format elf64-x86-64
|
|||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn Flags
|
||||
0 PEISDLL1 00000009 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY
|
||||
1 PEMAIN01 00000015 0000000000000000 0000000000000000 00000049 2**0 CONTENTS, RELOC, READONLY
|
||||
2 PEICONS1 00000007 0000000000000000 0000000000000000 0000005e 2**0 CONTENTS, RELOC, READONLY
|
||||
3 PEICONS2 00000009 0000000000000000 0000000000000000 00000065 2**0 CONTENTS, RELOC, READONLY
|
||||
4 PETLSHAK 0000000a 0000000000000000 0000000000000000 0000006e 2**0 CONTENTS, RELOC, READONLY
|
||||
5 PEMAIN02 00000001 0000000000000000 0000000000000000 00000078 2**0 CONTENTS, READONLY
|
||||
6 PEMAIN03 00000000 0000000000000000 0000000000000000 00000079 2**0 CONTENTS, READONLY
|
||||
7 NRV_HEAD 00000060 0000000000000000 0000000000000000 00000079 2**0 CONTENTS, READONLY
|
||||
8 NRV2E 000000ae 0000000000000000 0000000000000000 000000d9 2**0 CONTENTS, RELOC, READONLY
|
||||
9 PEMAIN10 00000001 0000000000000000 0000000000000000 00000187 2**0 CONTENTS, READONLY
|
||||
10 PECTTPOS 00000007 0000000000000000 0000000000000000 00000188 2**0 CONTENTS, RELOC, READONLY
|
||||
11 PECTTNUL 00000003 0000000000000000 0000000000000000 0000018f 2**0 CONTENTS, READONLY
|
||||
12 ctok32.00 00000005 0000000000000000 0000000000000000 00000192 2**0 CONTENTS, RELOC, READONLY
|
||||
13 PEIMPORT 00000038 0000000000000000 0000000000000000 00000197 2**0 CONTENTS, RELOC, READONLY
|
||||
14 PEIBYORD 00000002 0000000000000000 0000000000000000 000001cf 2**0 CONTENTS, RELOC, READONLY
|
||||
15 PEK32ORD 00000012 0000000000000000 0000000000000000 000001d1 2**0 CONTENTS, RELOC, READONLY
|
||||
16 PEIMORD1 0000000a 0000000000000000 0000000000000000 000001e3 2**0 CONTENTS, RELOC, READONLY
|
||||
17 PEIMPOR2 00000029 0000000000000000 0000000000000000 000001ed 2**0 CONTENTS, RELOC, READONLY
|
||||
18 PEIERDLL 00000007 0000000000000000 0000000000000000 00000216 2**0 CONTENTS, READONLY
|
||||
19 PEIEREXE 0000000a 0000000000000000 0000000000000000 0000021d 2**0 CONTENTS, RELOC, READONLY
|
||||
20 PEIMDONE 00000000 0000000000000000 0000000000000000 00000227 2**0 CONTENTS, READONLY
|
||||
21 PERELOC1 00000007 0000000000000000 0000000000000000 00000227 2**0 CONTENTS, RELOC, READONLY
|
||||
22 PERELOC2 00000004 0000000000000000 0000000000000000 0000022e 2**0 CONTENTS, READONLY
|
||||
23 PERELOC3 00000004 0000000000000000 0000000000000000 00000232 2**0 CONTENTS, READONLY
|
||||
24 PERLOHI0 00000000 0000000000000000 0000000000000000 00000236 2**0 CONTENTS, READONLY
|
||||
25 PERELLO0 00000000 0000000000000000 0000000000000000 00000236 2**0 CONTENTS, READONLY
|
||||
26 PERELHI0 00000000 0000000000000000 0000000000000000 00000236 2**0 CONTENTS, READONLY
|
||||
27 PEDEPHAK 0000004b 0000000000000000 0000000000000000 00000236 2**0 CONTENTS, RELOC, READONLY
|
||||
28 PETLSC 0000001d 0000000000000000 0000000000000000 00000281 2**0 CONTENTS, RELOC, READONLY
|
||||
29 PEMAIN20 00000004 0000000000000000 0000000000000000 0000029e 2**0 CONTENTS, READONLY
|
||||
30 CLEARSTACK 00000010 0000000000000000 0000000000000000 000002a2 2**0 CONTENTS, READONLY
|
||||
31 PEMAIN21 00000000 0000000000000000 0000000000000000 000002b2 2**0 CONTENTS, READONLY
|
||||
32 PERETURN 00000006 0000000000000000 0000000000000000 000002b2 2**0 CONTENTS, READONLY
|
||||
33 PEDOJUMP 00000005 0000000000000000 0000000000000000 000002b8 2**0 CONTENTS, RELOC, READONLY
|
||||
34 PETLSC2 0000002b 0000000000000000 0000000000000000 000002bd 2**0 CONTENTS, RELOC, READONLY
|
||||
35 UPX1HEAD 00000020 0000000000000000 0000000000000000 000002e8 2**0 CONTENTS, READONLY
|
||||
0 START 00000000 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, READONLY
|
||||
1 PEISDLL0 0000000f 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, READONLY
|
||||
2 PEISDLL1 00000009 0000000000000000 0000000000000000 0000004f 2**0 CONTENTS, RELOC, READONLY
|
||||
3 PEMAIN01 00000012 0000000000000000 0000000000000000 00000058 2**0 CONTENTS, RELOC, READONLY
|
||||
4 PEICONS1 00000007 0000000000000000 0000000000000000 0000006a 2**0 CONTENTS, RELOC, READONLY
|
||||
5 PEICONS2 00000009 0000000000000000 0000000000000000 00000071 2**0 CONTENTS, RELOC, READONLY
|
||||
6 PETLSHAK 0000000a 0000000000000000 0000000000000000 0000007a 2**0 CONTENTS, RELOC, READONLY
|
||||
7 PEMAIN02 00000001 0000000000000000 0000000000000000 00000084 2**0 CONTENTS, READONLY
|
||||
8 PEMAIN03 00000000 0000000000000000 0000000000000000 00000085 2**0 CONTENTS, READONLY
|
||||
9 NRV_HEAD 00000060 0000000000000000 0000000000000000 00000085 2**0 CONTENTS, READONLY
|
||||
10 NRV2E 000000ae 0000000000000000 0000000000000000 000000e5 2**0 CONTENTS, RELOC, READONLY
|
||||
11 PEMAIN10 00000001 0000000000000000 0000000000000000 00000193 2**0 CONTENTS, READONLY
|
||||
12 PECTTPOS 00000007 0000000000000000 0000000000000000 00000194 2**0 CONTENTS, RELOC, READONLY
|
||||
13 PECTTNUL 00000003 0000000000000000 0000000000000000 0000019b 2**0 CONTENTS, READONLY
|
||||
14 ctok32.00 00000005 0000000000000000 0000000000000000 0000019e 2**0 CONTENTS, RELOC, READONLY
|
||||
15 PEIMPORT 00000034 0000000000000000 0000000000000000 000001a3 2**0 CONTENTS, RELOC, READONLY
|
||||
16 PEIBYORD 00000002 0000000000000000 0000000000000000 000001d7 2**0 CONTENTS, RELOC, READONLY
|
||||
17 PEK32ORD 00000012 0000000000000000 0000000000000000 000001d9 2**0 CONTENTS, RELOC, READONLY
|
||||
18 PEIMORD1 0000000a 0000000000000000 0000000000000000 000001eb 2**0 CONTENTS, RELOC, READONLY
|
||||
19 PEIMPOR2 00000021 0000000000000000 0000000000000000 000001f5 2**0 CONTENTS, RELOC, READONLY
|
||||
20 PEIERDLL 0000000b 0000000000000000 0000000000000000 00000216 2**0 CONTENTS, READONLY
|
||||
21 PEIEREXE 00000006 0000000000000000 0000000000000000 00000221 2**0 CONTENTS, RELOC, READONLY
|
||||
22 PEIMDONE 00000004 0000000000000000 0000000000000000 00000227 2**0 CONTENTS, READONLY
|
||||
23 PERELOC1 00000007 0000000000000000 0000000000000000 0000022b 2**0 CONTENTS, RELOC, READONLY
|
||||
24 PERELOC2 00000004 0000000000000000 0000000000000000 00000232 2**0 CONTENTS, READONLY
|
||||
25 PERELOC3 00000030 0000000000000000 0000000000000000 00000236 2**0 CONTENTS, RELOC, READONLY
|
||||
26 REL64BIG 0000000a 0000000000000000 0000000000000000 00000266 2**0 CONTENTS, RELOC, READONLY
|
||||
27 RELOC64J 00000002 0000000000000000 0000000000000000 00000270 2**0 CONTENTS, RELOC, READONLY
|
||||
28 PERLOHI0 0000000a 0000000000000000 0000000000000000 00000272 2**0 CONTENTS, RELOC, READONLY
|
||||
29 PERELLO0 0000000b 0000000000000000 0000000000000000 0000027c 2**0 CONTENTS, READONLY
|
||||
30 PERELHI0 0000000e 0000000000000000 0000000000000000 00000287 2**0 CONTENTS, READONLY
|
||||
31 PEDEPHAK 0000004b 0000000000000000 0000000000000000 00000295 2**0 CONTENTS, RELOC, READONLY
|
||||
32 PETLSC 0000001b 0000000000000000 0000000000000000 000002e0 2**0 CONTENTS, RELOC, READONLY
|
||||
33 PEMAIN20 00000004 0000000000000000 0000000000000000 000002fb 2**0 CONTENTS, READONLY
|
||||
34 CLEARSTACK 00000010 0000000000000000 0000000000000000 000002ff 2**0 CONTENTS, READONLY
|
||||
35 PEMAIN21 00000000 0000000000000000 0000000000000000 0000030f 2**0 CONTENTS, READONLY
|
||||
36 PEISDLL9 0000000f 0000000000000000 0000000000000000 0000030f 2**0 CONTENTS, READONLY
|
||||
37 PERETURN 00000004 0000000000000000 0000000000000000 0000031e 2**0 CONTENTS, READONLY
|
||||
38 PEDOJUMP 00000005 0000000000000000 0000000000000000 00000322 2**0 CONTENTS, RELOC, READONLY
|
||||
39 PETLSC2 00000028 0000000000000000 0000000000000000 00000327 2**0 CONTENTS, RELOC, READONLY
|
||||
40 UPX1HEAD 00000020 0000000000000000 0000000000000000 0000034f 2**0 CONTENTS, READONLY
|
||||
SYMBOL TABLE:
|
||||
0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD
|
||||
0000000000000000 l d PEMAIN10 0000000000000000 PEMAIN10
|
||||
0000000000000000 l PEIMDONE 0000000000000000 imports_done
|
||||
000000000000002f l PEIMPORT 0000000000000000 next_func
|
||||
000000000000002b l PEIMPORT 0000000000000000 next_func
|
||||
000000000000000a l PEIMORD1 0000000000000000 byname
|
||||
0000000000000020 l PEIMPOR2 0000000000000000 next_imp
|
||||
0000000000000018 l PEIMPOR2 0000000000000000 next_imp
|
||||
000000000000000a l PEIMPOR2 0000000000000000 first_imp
|
||||
0000000000000002 l RELOC64J 0000000000000000 reloc_endx
|
||||
0000000000000013 l PERELOC3 0000000000000000 reloc_add
|
||||
0000000000000000 l d PEMAIN21 0000000000000000 PEMAIN21
|
||||
0000000000000000 l d PETLSC2 0000000000000000 PETLSC2
|
||||
0000000000000000 l d START 0000000000000000 START
|
||||
0000000000000000 l d PEISDLL0 0000000000000000 PEISDLL0
|
||||
0000000000000000 l d PEISDLL1 0000000000000000 PEISDLL1
|
||||
0000000000000000 l d PEMAIN01 0000000000000000 PEMAIN01
|
||||
0000000000000000 l d PEICONS1 0000000000000000 PEICONS1
|
||||
|
@ -70,6 +79,8 @@ SYMBOL TABLE:
|
|||
0000000000000000 l d PERELOC1 0000000000000000 PERELOC1
|
||||
0000000000000000 l d PERELOC2 0000000000000000 PERELOC2
|
||||
0000000000000000 l d PERELOC3 0000000000000000 PERELOC3
|
||||
0000000000000000 l d REL64BIG 0000000000000000 REL64BIG
|
||||
0000000000000000 l d RELOC64J 0000000000000000 RELOC64J
|
||||
0000000000000000 l d PERLOHI0 0000000000000000 PERLOHI0
|
||||
0000000000000000 l d PERELLO0 0000000000000000 PERELLO0
|
||||
0000000000000000 l d PERELHI0 0000000000000000 PERELHI0
|
||||
|
@ -77,6 +88,7 @@ SYMBOL TABLE:
|
|||
0000000000000000 l d PETLSC 0000000000000000 PETLSC
|
||||
0000000000000000 l d PEMAIN20 0000000000000000 PEMAIN20
|
||||
0000000000000000 l d CLEARSTACK 0000000000000000 CLEARSTACK
|
||||
0000000000000000 l d PEISDLL9 0000000000000000 PEISDLL9
|
||||
0000000000000000 l d PERETURN 0000000000000000 PERETURN
|
||||
0000000000000000 l d PEDOJUMP 0000000000000000 PEDOJUMP
|
||||
0000000000000000 l d UPX1HEAD 0000000000000000 UPX1HEAD
|
||||
|
@ -95,6 +107,7 @@ SYMBOL TABLE:
|
|||
0000000000000000 *UND* 0000000000000000 GetProcAddress
|
||||
0000000000000000 *UND* 0000000000000000 ExitProcess
|
||||
0000000000000000 *UND* 0000000000000000 start_of_relocs
|
||||
0000000000000000 *UND* 0000000000000000 reloc_delt
|
||||
0000000000000000 *UND* 0000000000000000 VirtualProtect
|
||||
0000000000000000 *UND* 0000000000000000 vp_base
|
||||
0000000000000000 *UND* 0000000000000000 vp_size
|
||||
|
@ -109,8 +122,8 @@ OFFSET TYPE VALUE
|
|||
|
||||
RELOCATION RECORDS FOR [PEMAIN01]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000006 R_X86_64_64 start_of_compressed+0x8000000000000000
|
||||
0000000000000011 R_X86_64_32S start_of_uncompressed
|
||||
0000000000000007 R_X86_64_PC32 start_of_compressed+0xfffffffffffffffc
|
||||
000000000000000e R_X86_64_32S start_of_uncompressed
|
||||
|
||||
RELOCATION RECORDS FOR [PEICONS1]:
|
||||
OFFSET TYPE VALUE
|
||||
|
@ -141,9 +154,9 @@ OFFSET TYPE VALUE
|
|||
|
||||
RELOCATION RECORDS FOR [PEIMPORT]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000003 R_X86_64_32S compressed_imports
|
||||
000000000000000c R_X86_64_PC8 imports_done
|
||||
0000000000000014 R_X86_64_32S start_of_imports
|
||||
0000000000000007 R_X86_64_32S compressed_imports
|
||||
0000000000000010 R_X86_64_PC8 imports_done
|
||||
0000000000000018 R_X86_64_32S start_of_imports
|
||||
0000000000000025 R_X86_64_32S LoadLibraryA
|
||||
|
||||
RELOCATION RECORDS FOR [PEIBYORD]:
|
||||
|
@ -161,17 +174,33 @@ OFFSET TYPE VALUE
|
|||
|
||||
RELOCATION RECORDS FOR [PEIMPOR2]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000013 R_X86_64_32S GetProcAddress
|
||||
0000000000000028 R_X86_64_PC8 next_func
|
||||
000000000000000f R_X86_64_32S GetProcAddress
|
||||
0000000000000020 R_X86_64_PC8 next_func
|
||||
|
||||
RELOCATION RECORDS FOR [PEIEREXE]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000006 R_X86_64_32S ExitProcess
|
||||
0000000000000002 R_X86_64_32S ExitProcess
|
||||
|
||||
RELOCATION RECORDS FOR [PERELOC1]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000003 R_X86_64_32S start_of_relocs
|
||||
|
||||
RELOCATION RECORDS FOR [PERELOC3]:
|
||||
OFFSET TYPE VALUE
|
||||
000000000000000e R_X86_64_PC8 reloc_endx
|
||||
|
||||
RELOCATION RECORDS FOR [REL64BIG]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000003 R_X86_64_PC8 reloc_add
|
||||
|
||||
RELOCATION RECORDS FOR [RELOC64J]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000001 R_X86_64_PC8 reloc_add
|
||||
|
||||
RELOCATION RECORDS FOR [PERLOHI0]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000006 R_X86_64_32S reloc_delt
|
||||
|
||||
RELOCATION RECORDS FOR [PEDEPHAK]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000003 R_X86_64_32S VirtualProtect
|
||||
|
@ -190,4 +219,4 @@ OFFSET TYPE VALUE
|
|||
|
||||
RELOCATION RECORDS FOR [PETLSC2]:
|
||||
OFFSET TYPE VALUE
|
||||
0000000000000005 R_X86_64_64 tls_callbacks_ptr+0x8000000000000000
|
||||
0000000000000006 R_X86_64_PC32 tls_callbacks_ptr+0xfffffffffffffffc
|
||||
|
|
Loading…
Reference in New Issue
Block a user