1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

fixed TLS callback handling for PE64

This commit is contained in:
László Molnár 2016-12-18 23:34:27 +01:00
parent a1cabd5a68
commit c51864ca39
8 changed files with 19 additions and 14 deletions

View File

@ -228,7 +228,7 @@ unsigned PackArmPe::getProcessImportParam(unsigned upxsection)
} }
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned, void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
unsigned ic, Reloc &, unsigned s1addr) unsigned ic, unsigned s1addr)
{ {
const unsigned onam = ncsection + soxrelocs + ih.imagebase; const unsigned onam = ncsection + soxrelocs + ih.imagebase;
linker->defineSymbol("start_of_dll_names", onam); linker->defineSymbol("start_of_dll_names", onam);

View File

@ -53,7 +53,7 @@ public:
unsigned ih_codebase); unsigned ih_codebase);
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
unsigned sizeof_oh, unsigned isize_isplit, unsigned sizeof_oh, unsigned isize_isplit,
Reloc &rel, unsigned s1addr); unsigned s1addr);
virtual void addNewRelocations(Reloc &, unsigned upxsection); virtual void addNewRelocations(Reloc &, unsigned upxsection);
virtual unsigned getProcessImportParam(unsigned upxsection); virtual unsigned getProcessImportParam(unsigned upxsection);
virtual void setOhDataBase(const pe_section_t *osection); virtual void setOhDataBase(const pe_section_t *osection);

View File

@ -189,7 +189,7 @@ bool PackW32Pe::handleForceOption()
void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection, void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection,
unsigned sizeof_oh, unsigned ic, unsigned sizeof_oh, unsigned ic,
Reloc &, unsigned s1addr) unsigned s1addr)
{ {
const unsigned myimport = ncsection + soresources - rvamin; const unsigned myimport = ncsection + soresources - rvamin;
@ -269,12 +269,6 @@ void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection,
void PackW32Pe::addNewRelocations(Reloc &rel, unsigned) void PackW32Pe::addNewRelocations(Reloc &rel, unsigned)
{ {
rel.add(linker->getSymbolOffset("PEMAIN01") + 2, 3); rel.add(linker->getSymbolOffset("PEMAIN01") + 2, 3);
if (use_tls_callbacks)
{
tls_handler_offset = linker->getSymbolOffset("PETLSC2");
//add relocation entry for TLS callback handler
rel.add(tls_handler_offset + 4, 3);
}
} }
void PackW32Pe::setOhDataBase(const pe_section_t *osection) void PackW32Pe::setOhDataBase(const pe_section_t *osection)

View File

@ -50,7 +50,7 @@ public:
virtual bool handleForceOption(); virtual bool handleForceOption();
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
unsigned sizeof_oh, unsigned isize_isplit, unsigned sizeof_oh, unsigned isize_isplit,
Reloc &rel, unsigned s1addr); unsigned s1addr);
virtual void addNewRelocations(Reloc &, unsigned upxsection); virtual void addNewRelocations(Reloc &, unsigned upxsection);
virtual void setOhDataBase(const pe_section_t *osection); virtual void setOhDataBase(const pe_section_t *osection);
virtual void setOhHeaderSize(const pe_section_t *osection); virtual void setOhHeaderSize(const pe_section_t *osection);

View File

@ -188,7 +188,7 @@ bool PackW64Pep::handleForceOption()
void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection, void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
unsigned sizeof_oh, unsigned ic, unsigned sizeof_oh, unsigned ic,
Reloc &, unsigned s1addr) unsigned s1addr)
{ {
const unsigned myimport = ncsection + soresources - rvamin; const unsigned myimport = ncsection + soresources - rvamin;

View File

@ -49,7 +49,7 @@ public:
virtual bool handleForceOption(); virtual bool handleForceOption();
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
unsigned sizeof_oh, unsigned isize_isplit, unsigned sizeof_oh, unsigned isize_isplit,
Reloc &rel, unsigned s1addr); unsigned s1addr);
virtual void setOhDataBase(const pe_section_t *) {} virtual void setOhDataBase(const pe_section_t *) {}
virtual void setOhHeaderSize(const pe_section_t *osection); virtual void setOhHeaderSize(const pe_section_t *osection);
virtual void pack(OutputFile *fo); virtual void pack(OutputFile *fo);

View File

@ -1229,6 +1229,7 @@ struct PeFile::tls_traits<LE32>
static const unsigned cb_size = 4; static const unsigned cb_size = 4;
typedef unsigned cb_value_t; typedef unsigned cb_value_t;
static const unsigned reloc_type = 3; static const unsigned reloc_type = 3;
static const int tls_handler_offset_reloc = 4;
}; };
template <> template <>
@ -1246,6 +1247,7 @@ struct PeFile::tls_traits<LE64>
static const unsigned cb_size = 8; static const unsigned cb_size = 8;
typedef upx_uint64_t cb_value_t; typedef upx_uint64_t cb_value_t;
static const unsigned reloc_type = 10; static const unsigned reloc_type = 10;
static const int tls_handler_offset_reloc = -1; // no need to relocate
}; };
template <typename LEXX> template <typename LEXX>
@ -1333,10 +1335,15 @@ void PeFile::processTls2(Reloc *rel,const Interval *iv,unsigned newaddr,
typedef typename tls_traits<LEXX>::cb_value_t cb_value_t; typedef typename tls_traits<LEXX>::cb_value_t cb_value_t;
const unsigned cb_size = tls_traits<LEXX>::cb_size; const unsigned cb_size = tls_traits<LEXX>::cb_size;
const unsigned reloc_type = tls_traits<LEXX>::reloc_type; const unsigned reloc_type = tls_traits<LEXX>::reloc_type;
const int tls_handler_offset_reloc = tls_traits<LEXX>::tls_handler_offset_reloc;
if (sotls == 0) if (sotls == 0)
return; return;
// add new relocation entries // add new relocation entries
if (tls_handler_offset_reloc > 0)
rel->add(tls_handler_offset + tls_handler_offset_reloc, reloc_type);
unsigned ic; unsigned ic;
//NEW: if TLS callbacks are used, relocate the VA of the callback chain, too - Stefan Widmann //NEW: if TLS callbacks are used, relocate the VA of the callback chain, too - Stefan Widmann
for (ic = 0; ic < (use_tls_callbacks ? 4 * cb_size : 3 * cb_size); ic += cb_size) for (ic = 0; ic < (use_tls_callbacks ? 4 * cb_size : 3 * cb_size); ic += cb_size)
@ -2328,6 +2335,10 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh,
// tls & loadconf are put into section 1 // tls & loadconf are put into section 1
ic = s1addr + s1size - sotls - soloadconf; ic = s1addr + s1size - sotls - soloadconf;
if (use_tls_callbacks)
tls_handler_offset = linker->getSymbolOffset("PETLSC2") + upxsection;
processTls(&rel,&tlsiv,ic); processTls(&rel,&tlsiv,ic);
ODADDR(PEDIR_TLS) = sotls ? ic : 0; ODADDR(PEDIR_TLS) = sotls ? ic : 0;
ODSIZE(PEDIR_TLS) = sotls ? (sizeof(LEXX) == 4 ? 0x18 : 0x28) : 0; ODSIZE(PEDIR_TLS) = sotls ? (sizeof(LEXX) == 4 ? 0x18 : 0x28) : 0;
@ -2370,7 +2381,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh,
callProcessResources(res, ic = res_start); callProcessResources(res, ic = res_start);
defineSymbols(ncsection, upxsection, sizeof(oh), defineSymbols(ncsection, upxsection, sizeof(oh),
identsize - identsplit, rel, s1addr); identsize - identsplit, s1addr);
defineFilterSymbols(&ft); defineFilterSymbols(&ft);
relocateLoader(); relocateLoader();
const unsigned lsize = getLoaderSize(); const unsigned lsize = getLoaderSize();

View File

@ -63,7 +63,7 @@ protected:
unsigned ih_codebase); unsigned ih_codebase);
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
unsigned sizeof_oh, unsigned isize_isplit, unsigned sizeof_oh, unsigned isize_isplit,
Reloc &rel, unsigned s1addr) = 0; unsigned s1addr) = 0;
virtual void addNewRelocations(Reloc &, unsigned) {} virtual void addNewRelocations(Reloc &, unsigned) {}
void callProcessRelocs(Reloc &rel, unsigned &ic); void callProcessRelocs(Reloc &rel, unsigned &ic);
void callProcessResources(Resource &res, unsigned &ic); void callProcessResources(Resource &res, unsigned &ic);