mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
win32/pe TLS handling added
This commit is contained in:
parent
9e3e80261b
commit
25902005f6
254
src/p_w32pe.cpp
254
src/p_w32pe.cpp
|
@ -168,6 +168,138 @@ int PackW32Pe::readFileHeader()
|
||||||
return super::readFileHeader();
|
return super::readFileHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//new: processTLS moved to p_w32pe.cpp for TLS callback support
|
||||||
|
/*************************************************************************
|
||||||
|
// TLS handling
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// thanks for theowl for providing me some docs, so that now I understand
|
||||||
|
// what I'm doing here :)
|
||||||
|
|
||||||
|
// 1999-10-17: this was tricky to find:
|
||||||
|
// when the fixup records and the tls area are on the same page, then
|
||||||
|
// the tls area is not relocated, because the relocation is done by
|
||||||
|
// the virtual memory manager only for pages which are not yet loaded.
|
||||||
|
// of course it was impossible to debug this ;-)
|
||||||
|
|
||||||
|
__packed_struct(tls)
|
||||||
|
LE32 datastart; // VA tls init data start
|
||||||
|
LE32 dataend; // VA tls init data end
|
||||||
|
LE32 tlsindex; // VA tls index
|
||||||
|
LE32 callbacks; // VA tls callbacks
|
||||||
|
char _[8]; // zero init, characteristics
|
||||||
|
__packed_struct_end()
|
||||||
|
|
||||||
|
void PackW32Pe::processTls(Interval *iv) // pass 1
|
||||||
|
{
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(tls) == 24)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(tls)
|
||||||
|
|
||||||
|
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4)) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const tls * const tlsp = (const tls*) (ibuf + IDADDR(PEDIR_TLS));
|
||||||
|
|
||||||
|
use_tls_callbacks = false; //NEW - Stefan Widmann
|
||||||
|
|
||||||
|
// note: TLS callbacks are not implemented in Windows 95/98/ME
|
||||||
|
if (tlsp->callbacks)
|
||||||
|
{
|
||||||
|
if (tlsp->callbacks < ih.imagebase)
|
||||||
|
throwCantPack("invalid TLS callback");
|
||||||
|
else if (tlsp->callbacks - ih.imagebase + 4 >= ih.imagesize)
|
||||||
|
throwCantPack("invalid TLS callback");
|
||||||
|
unsigned v = get_le32(ibuf + tlsp->callbacks - ih.imagebase);
|
||||||
|
|
||||||
|
//NEW: TLS callback support - Stefan Widmann
|
||||||
|
#if 0
|
||||||
|
if (v != 0)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "TLS callbacks: 0x%0x -> 0x%0x\n", (int)tlsp->callbacks, v);
|
||||||
|
throwCantPack("TLS callbacks are not supported");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(v != 0)
|
||||||
|
{
|
||||||
|
//count number of callbacks, just for information string - Stefan Widmann
|
||||||
|
unsigned num_callbacks = 0;
|
||||||
|
unsigned callback_offset = 0;
|
||||||
|
while(get_le32(ibuf + tlsp->callbacks - ih.imagebase + callback_offset))
|
||||||
|
{
|
||||||
|
//increment number of callbacks
|
||||||
|
num_callbacks++;
|
||||||
|
//increment pointer by 4
|
||||||
|
callback_offset += 4;
|
||||||
|
}
|
||||||
|
info("TLS: %u callback(s) found, adding TLS callback handler", num_callbacks);
|
||||||
|
//set flag to include necessary sections in loader
|
||||||
|
use_tls_callbacks = true;
|
||||||
|
//define linker symbols
|
||||||
|
tlscb_ptr = tlsp->callbacks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned tlsdatastart = tlsp->datastart - ih.imagebase;
|
||||||
|
const unsigned tlsdataend = tlsp->dataend - ih.imagebase;
|
||||||
|
|
||||||
|
// now some ugly stuff: find the relocation entries in the tls data area
|
||||||
|
unsigned pos,type;
|
||||||
|
Reloc rel(ibuf + IDADDR(PEDIR_RELOC),IDSIZE(PEDIR_RELOC));
|
||||||
|
while (rel.next(pos,type))
|
||||||
|
if (pos >= tlsdatastart && pos < tlsdataend)
|
||||||
|
iv->add(pos,type);
|
||||||
|
|
||||||
|
//NEW: if TLS callbacks are used, we need two more DWORDS at the end of the TLS
|
||||||
|
sotls = sizeof(tls) + tlsdataend - tlsdatastart + (use_tls_callbacks ? 8 : 0);
|
||||||
|
|
||||||
|
// the PE loader wants this stuff uncompressed
|
||||||
|
otls = new upx_byte[sotls];
|
||||||
|
memset(otls,0,sotls);
|
||||||
|
memcpy(otls,ibuf + IDADDR(PEDIR_TLS),0x18);
|
||||||
|
// WARNING: this can acces data in BSS
|
||||||
|
memcpy(otls + sizeof(tls),ibuf + tlsdatastart,sotls - sizeof(tls));
|
||||||
|
tlsindex = tlsp->tlsindex - ih.imagebase;
|
||||||
|
//NEW: subtract two dwords if TLS callbacks are used - Stefan Widmann
|
||||||
|
info("TLS: %u bytes tls data and %u relocations added",sotls - (unsigned) sizeof(tls) - (use_tls_callbacks ? 8 : 0),iv->ivnum);
|
||||||
|
|
||||||
|
// makes sure tls index is zero after decompression
|
||||||
|
if (tlsindex && tlsindex < ih.imagesize)
|
||||||
|
set_le32(ibuf + tlsindex, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackW32Pe::processTls(Reloc *rel,const Interval *iv,unsigned newaddr) // pass 2
|
||||||
|
{
|
||||||
|
if (sotls == 0)
|
||||||
|
return;
|
||||||
|
// add new relocation entries
|
||||||
|
unsigned ic;
|
||||||
|
//NEW: if TLS callbacks are used, relocate the VA of the callback chain, too - Stefan Widmann
|
||||||
|
for (ic = 0; ic < (use_tls_callbacks ? 16 : 12); ic += 4)
|
||||||
|
rel->add(newaddr + ic,3);
|
||||||
|
|
||||||
|
tls * const tlsp = (tls*) otls;
|
||||||
|
// now the relocation entries in the tls data area
|
||||||
|
for (ic = 0; ic < iv->ivnum; ic += 4)
|
||||||
|
{
|
||||||
|
void *p = otls + iv->ivarr[ic].start - (tlsp->datastart - ih.imagebase) + sizeof(tls);
|
||||||
|
unsigned kc = get_le32(p);
|
||||||
|
if (kc < tlsp->dataend && kc >= tlsp->datastart)
|
||||||
|
{
|
||||||
|
kc += newaddr + sizeof(tls) - tlsp->datastart;
|
||||||
|
set_le32(p,kc + ih.imagebase);
|
||||||
|
rel->add(kc,iv->ivarr[ic].len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rel->add(kc - ih.imagebase,iv->ivarr[ic].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsp->datastart = newaddr + sizeof(tls) + ih.imagebase;
|
||||||
|
//NEW: subtract the size of the callback chain from dataend - Stefan Widmann
|
||||||
|
tlsp->dataend = newaddr + sotls + ih.imagebase - (use_tls_callbacks ? 8 : 0);
|
||||||
|
|
||||||
|
//NEW: if we have TLS callbacks to handle, we create a pointer to the new callback chain - Stefan Widmann
|
||||||
|
tlsp->callbacks = (use_tls_callbacks ? newaddr + sotls + ih.imagebase - 8 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// import handling
|
// import handling
|
||||||
|
@ -577,14 +709,30 @@ void PackW32Pe::buildLoader(const Filter *ft)
|
||||||
}
|
}
|
||||||
if (use_dep_hack)
|
if (use_dep_hack)
|
||||||
addLoader("PEDEPHAK", NULL);
|
addLoader("PEDEPHAK", NULL);
|
||||||
|
|
||||||
|
//NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann
|
||||||
|
if(use_tls_callbacks)
|
||||||
|
addLoader("PETLSC", NULL);
|
||||||
|
|
||||||
addLoader("PEMAIN20", NULL);
|
addLoader("PEMAIN20", NULL);
|
||||||
if (use_clear_dirty_stack)
|
if (use_clear_dirty_stack)
|
||||||
addLoader("CLEARSTACK", NULL);
|
addLoader("CLEARSTACK", NULL);
|
||||||
addLoader("PEMAIN21", NULL);
|
addLoader("PEMAIN21", NULL);
|
||||||
|
#if 0
|
||||||
addLoader(ih.entry ? "PEDOJUMP" : "PERETURN",
|
addLoader(ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||||
"IDENTSTR,UPX1HEAD",
|
"IDENTSTR,UPX1HEAD",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
|
//NEW: last loader sections split up to insert TLS callback handler - Stefan Widmann
|
||||||
|
addLoader(ih.entry ? "PEDOJUMP" : "PERETURN", NULL);
|
||||||
|
|
||||||
|
//NEW: TLS callback support PART 2, the callback handler - Stefan Widmann
|
||||||
|
if(use_tls_callbacks)
|
||||||
|
addLoader("PETLSC2", NULL);
|
||||||
|
|
||||||
|
addLoader("IDENTSTR,UPX1HEAD", NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -605,12 +753,13 @@ void PackW32Pe::pack(OutputFile *fo)
|
||||||
|
|
||||||
// check the PE header
|
// check the PE header
|
||||||
// FIXME: add more checks
|
// FIXME: add more checks
|
||||||
|
//NEW: subsystem check moved to switch ... case below, check of COFF magic, 32 bit machine flag check - Stefan Widmann
|
||||||
if (!opt->force && (
|
if (!opt->force && (
|
||||||
(ih.cpu < 0x14c || ih.cpu > 0x150)
|
(ih.cpu < 0x14c || ih.cpu > 0x150)
|
||||||
|| (ih.opthdrsize != 0xe0)
|
|| (ih.opthdrsize != 0xe0)
|
||||||
|| ((ih.flags & EXECUTABLE) == 0)
|
|| ((ih.flags & EXECUTABLE) == 0)
|
||||||
|| (ih.subsystem != 2 && ih.subsystem != 3
|
|| ((ih.flags & BITS_32_MACHINE) == 0) //NEW: 32 bit machine flag must be set - Stefan Widmann
|
||||||
&& ih.subsystem != 1 && ih.subsystem != 9)
|
|| (ih.coffmagic != 0x10B) //COFF magic is 0x10B in PE files, 0x20B in PE32+ files - Stefan Widmann
|
||||||
|| (ih.entry == 0 && !isdll)
|
|| (ih.entry == 0 && !isdll)
|
||||||
|| (ih.ddirsentries != 16)
|
|| (ih.ddirsentries != 16)
|
||||||
|| IDSIZE(PEDIR_EXCEPTION) // is this used on i386?
|
|| IDSIZE(PEDIR_EXCEPTION) // is this used on i386?
|
||||||
|
@ -618,15 +767,90 @@ void PackW32Pe::pack(OutputFile *fo)
|
||||||
))
|
))
|
||||||
throwCantPack("unexpected value in PE header (try --force)");
|
throwCantPack("unexpected value in PE header (try --force)");
|
||||||
|
|
||||||
if (ih.subsystem == 9)
|
switch(ih.subsystem) //let's take a closer look at the subsystem
|
||||||
throwCantPack("x86/wince files are not yet supported");
|
{
|
||||||
|
case 1: //NATIVE
|
||||||
|
{
|
||||||
|
if(!opt->force)
|
||||||
|
{
|
||||||
|
throwCantPack("win32/native applications are not yet supported");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: //GUI
|
||||||
|
{
|
||||||
|
//fine, continue
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: //CONSOLE
|
||||||
|
{
|
||||||
|
//fine, continue
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: //OS2
|
||||||
|
{
|
||||||
|
throwCantPack("win32/os2 files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7: //POSIX - do x32/posix files exist?
|
||||||
|
{
|
||||||
|
throwCantPack("win32/posix files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 9: //WINCE x86 files
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/wince files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 10: //EFI APPLICATION
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/EFIapplication files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 11: //EFI BOOT SERVICE DRIVER
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/EFIbootservicedriver files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 12: //EFI RUNTIME DRIVER
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/EFIruntimedriver files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 13: //EFI ROM
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/EFIROM files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 14: //XBOX - will we ever see an XBOX file?
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/xbox files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16: //WINDOWS BOOT APPLICATION
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/windowsbootapplication files are not yet supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: //UNKNOWN SUBSYSTEM
|
||||||
|
{
|
||||||
|
throwCantPack("PE32/? unknown subsystem");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove certificate directory entry
|
||||||
if (IDSIZE(PEDIR_SEC))
|
if (IDSIZE(PEDIR_SEC))
|
||||||
IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;
|
IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;
|
||||||
if (IDSIZE(PEDIR_COMRT))
|
|
||||||
throwCantPack(".NET files (win32/net) are not yet supported");
|
|
||||||
|
|
||||||
if (isdll)
|
//check CLR Runtime Header directory entry
|
||||||
|
if (IDSIZE(PEDIR_COMRT))
|
||||||
|
throwCantPack(".NET files (win32/.net) are not yet supported");
|
||||||
|
|
||||||
|
//NEW: disable reloc stripping if ASLR is enabled
|
||||||
|
if(ih.dllflags & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)
|
||||||
|
opt->win32_pe.strip_relocs = false;
|
||||||
|
else if (isdll) //do never strip relocations from DLLs
|
||||||
opt->win32_pe.strip_relocs = false;
|
opt->win32_pe.strip_relocs = false;
|
||||||
else if (opt->win32_pe.strip_relocs < 0)
|
else if (opt->win32_pe.strip_relocs < 0)
|
||||||
opt->win32_pe.strip_relocs = (ih.imagebase >= 0x400000);
|
opt->win32_pe.strip_relocs = (ih.imagebase >= 0x400000);
|
||||||
|
@ -644,8 +868,10 @@ void PackW32Pe::pack(OutputFile *fo)
|
||||||
throwCantPack("file is possibly packed/protected (try --force)");
|
throwCantPack("file is possibly packed/protected (try --force)");
|
||||||
if (ih.entry && ih.entry < rvamin)
|
if (ih.entry && ih.entry < rvamin)
|
||||||
throwCantPack("run a virus scanner on this file!");
|
throwCantPack("run a virus scanner on this file!");
|
||||||
if (!opt->force && ih.subsystem == 1)
|
#if 0 //subsystem check moved to switch ... case above - Stefan Widmann
|
||||||
|
if (!opt->force && ih.subsystem == 1)
|
||||||
throwCantPack("subsystem 'native' is not supported (try --force)");
|
throwCantPack("subsystem 'native' is not supported (try --force)");
|
||||||
|
#endif
|
||||||
if (ih.filealign < 0x200)
|
if (ih.filealign < 0x200)
|
||||||
throwCantPack("filealign < 0x200 is not yet supported");
|
throwCantPack("filealign < 0x200 is not yet supported");
|
||||||
|
|
||||||
|
@ -904,6 +1130,16 @@ void PackW32Pe::pack(OutputFile *fo)
|
||||||
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 + ih.imagebase);
|
||||||
|
|
||||||
|
//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)
|
||||||
|
{
|
||||||
|
//esi is ih.imagebase + rvamin
|
||||||
|
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr - (ih.imagebase + rvamin));
|
||||||
|
linker->defineSymbol("tls_callbacks_off", ic + sotls - 8 - rvamin);
|
||||||
|
linker->defineSymbol("tls_module_base", 0u - rvamin);
|
||||||
|
}
|
||||||
|
|
||||||
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
|
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
|
||||||
//linker->dumpSymbols();
|
//linker->dumpSymbols();
|
||||||
relocateLoader();
|
relocateLoader();
|
||||||
|
@ -935,7 +1171,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
||||||
|
|
||||||
// tls & loadconf are put into section 1
|
// tls & loadconf are put into section 1
|
||||||
|
|
||||||
ic = s1addr + s1size - sotls - soloadconf;
|
//ic = s1addr + s1size - sotls - soloadconf; //ATTENTION: moved upwards to TLS callback handling - Stefan Widmann
|
||||||
processTls(&rel,&tlsiv,ic);
|
processTls(&rel,&tlsiv,ic);
|
||||||
ODADDR(PEDIR_TLS) = sotls ? ic : 0;
|
ODADDR(PEDIR_TLS) = sotls ? ic : 0;
|
||||||
ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;
|
ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;
|
||||||
|
|
|
@ -61,14 +61,21 @@ protected:
|
||||||
virtual void processImports(unsigned, unsigned);
|
virtual void processImports(unsigned, unsigned);
|
||||||
virtual void rebuildImports(upx_byte *&);
|
virtual void rebuildImports(upx_byte *&);
|
||||||
|
|
||||||
|
virtual void processTls(Interval *); //NEW: TLS callback handling - Stefan Widmann
|
||||||
|
void processTls(Reloc *, const Interval *, unsigned); //NEW: TLS callback handling - Stefan Widmann
|
||||||
|
|
||||||
void processLoadConf(Reloc *, const Interval *, unsigned);
|
void processLoadConf(Reloc *, const Interval *, unsigned);
|
||||||
void processLoadConf(Interval *);
|
void processLoadConf(Interval *);
|
||||||
upx_byte *oloadconf;
|
upx_byte *oloadconf;
|
||||||
unsigned soloadconf;
|
unsigned soloadconf;
|
||||||
|
|
||||||
|
unsigned tlscb_ptr; //NEW: TLS callback handling - Stefan Widmann
|
||||||
|
//unsigned tlscb_off; //NEW: TLS callback handling - Stefan Widmann
|
||||||
|
|
||||||
bool isrtm;
|
bool isrtm;
|
||||||
bool use_dep_hack;
|
bool use_dep_hack;
|
||||||
bool use_clear_dirty_stack;
|
bool use_clear_dirty_stack;
|
||||||
|
bool use_tls_callbacks; //NEW: TLS callback handling - Stefan Widmann
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
15
src/pefile.h
15
src/pefile.h
|
@ -115,7 +115,8 @@ protected:
|
||||||
LE16 opthdrsize;
|
LE16 opthdrsize;
|
||||||
LE16 flags;
|
LE16 flags;
|
||||||
// optional header
|
// optional header
|
||||||
char ___[4]; // coffmagic + linkerversion
|
LE16 coffmagic; // NEW: Stefan Widmann
|
||||||
|
char ___[2]; // linkerversion
|
||||||
LE32 codesize;
|
LE32 codesize;
|
||||||
// 0x20
|
// 0x20
|
||||||
LE32 datasize;
|
LE32 datasize;
|
||||||
|
@ -213,6 +214,18 @@ protected:
|
||||||
DLL_FLAG = 0x2000,
|
DLL_FLAG = 0x2000,
|
||||||
FBIG_ENDIAN = 0x8000
|
FBIG_ENDIAN = 0x8000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann
|
||||||
|
enum {
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
|
||||||
|
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
|
||||||
|
};
|
||||||
|
|
||||||
// predefined resource types
|
// predefined resource types
|
||||||
enum {
|
enum {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -114,7 +114,7 @@ section PEK32ORD
|
||||||
jmps next_imp
|
jmps next_imp
|
||||||
not_kernel32:
|
not_kernel32:
|
||||||
section PEIMORD1
|
section PEIMORD1
|
||||||
movzxw eax, [edi]
|
movzxw eax, word ptr [edi] //new: "word ptr" - Stefan Widmann
|
||||||
inc edi
|
inc edi
|
||||||
push eax
|
push eax
|
||||||
inc edi
|
inc edi
|
||||||
|
@ -135,6 +135,7 @@ next_imp:
|
||||||
add ebx, 4
|
add ebx, 4
|
||||||
jmps next_func
|
jmps next_func
|
||||||
imp_failed:
|
imp_failed:
|
||||||
|
|
||||||
section PEIERDLL
|
section PEIERDLL
|
||||||
popa
|
popa
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
|
@ -194,7 +195,7 @@ section PEDEPHAK
|
||||||
push 4 // PAGE_READWRITE
|
push 4 // PAGE_READWRITE
|
||||||
push ebx
|
push ebx
|
||||||
push edi
|
push edi
|
||||||
call ebp
|
call ebp //VirtualProtect
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
or eax, eax
|
or eax, eax
|
||||||
|
@ -216,15 +217,32 @@ section PEDEPHAK
|
||||||
#endif
|
#endif
|
||||||
push ebx
|
push ebx
|
||||||
push edi
|
push edi
|
||||||
call ebp
|
call ebp //;VirtualProtect
|
||||||
|
|
||||||
pedep9:
|
pedep9:
|
||||||
pop eax // restore stack
|
pop eax //;restore stack
|
||||||
|
|
||||||
|
//;NEW: TLS callback support - Stefan Widmann
|
||||||
|
section PETLSC
|
||||||
|
lea ebx, [esi + tls_module_base] //;load module base to ebx
|
||||||
|
lea eax, [esi + tls_callbacks_ptr] //;load pointer to original callback chain
|
||||||
|
lea edi, [ebx + tls_handler_start] //;load offset of handler
|
||||||
|
push edi
|
||||||
|
inc edi //;pointer to original TLS callback chain is to be saved to handler + 2
|
||||||
|
inc edi
|
||||||
|
stosd
|
||||||
|
pop eax
|
||||||
|
lea edi, [esi + tls_callbacks_off] //;get ptr to first TLS callback entry
|
||||||
|
stosd //;save the handler ptr to the TLS callback chain
|
||||||
|
//;emulate callbacks like PE loader would have done
|
||||||
|
push 0 //;reserved
|
||||||
|
push 1 //;DLL_PROCESS_ATTACH
|
||||||
|
push ebx //;module base alias module handle alias hInstance alias ...
|
||||||
|
call eax //;contains ptr to callback handler
|
||||||
|
|
||||||
section PEMAIN20
|
section PEMAIN20
|
||||||
popa
|
popa
|
||||||
|
|
||||||
|
|
||||||
// clear the dirty stack
|
// clear the dirty stack
|
||||||
.macro clearstack128 tmp_reg
|
.macro clearstack128 tmp_reg
|
||||||
local loop
|
local loop
|
||||||
|
@ -249,6 +267,30 @@ section PERETURN
|
||||||
section PEDOJUMP
|
section PEDOJUMP
|
||||||
jmp original_entry
|
jmp original_entry
|
||||||
|
|
||||||
|
section PETLSC2
|
||||||
|
//;TLS_CALLBACK(hModule, reason, reserved)
|
||||||
|
tls_handler_start:
|
||||||
|
push esi
|
||||||
|
.byte 0xBE //mov esi, XXXXXXXX
|
||||||
|
tlsc_chain_ptr:
|
||||||
|
.byte 0, 0, 0, 0
|
||||||
|
cld //;you never know, this code gets called by the PE loader
|
||||||
|
walk_tlsc_chain2:
|
||||||
|
lodsd
|
||||||
|
test eax, eax
|
||||||
|
jz done_callbacks
|
||||||
|
//;copy the stack frame, 3 arguments
|
||||||
|
push 3
|
||||||
|
pop ecx
|
||||||
|
push_loop:
|
||||||
|
push dword ptr [esp + 0x10] //;4 bytes
|
||||||
|
loop push_loop
|
||||||
|
call eax
|
||||||
|
jmp walk_tlsc_chain2
|
||||||
|
done_callbacks:
|
||||||
|
pop esi
|
||||||
|
ret 0x0C
|
||||||
|
|
||||||
// =============
|
// =============
|
||||||
// ============= CUT HERE
|
// ============= CUT HERE
|
||||||
// =============
|
// =============
|
||||||
|
|
Loading…
Reference in New Issue
Block a user