64 relocation handling added; basic DLL support works

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