src: clang-format pefile
This commit is contained in:
parent
19147963b9
commit
3fa18c1799
@ -81,7 +81,7 @@ ifeq ($(shell uname),Linux)
|
|||||||
# Markus loves clang-format, but John hates it; find a compromise
|
# Markus loves clang-format, but John hates it; find a compromise
|
||||||
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h help.cpp
|
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h help.cpp
|
||||||
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli%
|
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli%
|
||||||
CLANG_FORMAT_EXCLUDE_FILES += p_w32pe.cpp p_w64pep.cpp packer_c.cpp packer_f.cpp pefile%
|
CLANG_FORMAT_EXCLUDE_FILES += packer_c.cpp packer_f.cpp
|
||||||
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
|
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
|
||||||
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
|
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
|
||||||
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
|
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
|
||||||
|
|||||||
205
src/p_w32pe.cpp
205
src/p_w32pe.cpp
@ -25,7 +25,6 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@ -34,55 +33,40 @@
|
|||||||
#include "p_w32pe.h"
|
#include "p_w32pe.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/i386-win32.pe.h"
|
#include "stub/i386-win32.pe.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackW32Pe::PackW32Pe(InputFile *f) : super(f)
|
PackW32Pe::PackW32Pe(InputFile *f) : super(f) {}
|
||||||
{}
|
|
||||||
|
|
||||||
|
PackW32Pe::~PackW32Pe() {}
|
||||||
|
|
||||||
PackW32Pe::~PackW32Pe()
|
const int *PackW32Pe::getCompressionMethods(int method, int level) const {
|
||||||
{}
|
bool small = ih.codesize + ih.datasize <= 256 * 1024;
|
||||||
|
|
||||||
|
|
||||||
const int *PackW32Pe::getCompressionMethods(int method, int level) const
|
|
||||||
{
|
|
||||||
bool small = ih.codesize + ih.datasize <= 256*1024;
|
|
||||||
return Packer::getDefaultCompressionMethods_le32(method, level, small);
|
return Packer::getDefaultCompressionMethods_le32(method, level, small);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackW32Pe::getFilters() const {
|
||||||
const int *PackW32Pe::getFilters() const
|
static const int filters[] = {0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14,
|
||||||
{
|
0x11, FT_ULTRA_BRUTE, 0x25, 0x15, 0x12, FT_END};
|
||||||
static const int filters[] = {
|
|
||||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
|
||||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
|
||||||
FT_END };
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackW32Pe::newLinker() const { return new ElfLinkerX86; }
|
||||||
Linker* PackW32Pe::newLinker() const
|
|
||||||
{
|
|
||||||
return new ElfLinkerX86;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackW32Pe::readFileHeader()
|
int PackW32Pe::readFileHeader() {
|
||||||
{
|
|
||||||
if (fi->st_size() >= 0x206) {
|
if (fi->st_size() >= 0x206) {
|
||||||
char buf[6];
|
char buf[6];
|
||||||
fi->seek(0x200, SEEK_SET);
|
fi->seek(0x200, SEEK_SET);
|
||||||
fi->readx(buf, 6);
|
fi->readx(buf, 6);
|
||||||
isrtm = memcmp(buf, "32STUB" ,6) == 0;
|
isrtm = memcmp(buf, "32STUB", 6) == 0;
|
||||||
}
|
}
|
||||||
return super::readFileHeader();
|
return super::readFileHeader();
|
||||||
}
|
}
|
||||||
@ -91,118 +75,89 @@ int PackW32Pe::readFileHeader()
|
|||||||
// pack
|
// pack
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackW32Pe::canPack()
|
bool PackW32Pe::canPack() {
|
||||||
{
|
|
||||||
if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150)
|
if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackW32Pe::buildLoader(const Filter *ft) {
|
||||||
void PackW32Pe::buildLoader(const Filter *ft)
|
|
||||||
{
|
|
||||||
// recompute tlsindex (see pack() below)
|
// recompute tlsindex (see pack() below)
|
||||||
unsigned tmp_tlsindex = tlsindex;
|
unsigned tmp_tlsindex = tlsindex;
|
||||||
const unsigned oam1 = ih.objectalign - 1;
|
const unsigned oam1 = ih.objectalign - 1;
|
||||||
const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
|
const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) & ~oam1;
|
||||||
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
|
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) & ~oam1) > tlsindex + 4)
|
||||||
tmp_tlsindex = 0;
|
tmp_tlsindex = 0;
|
||||||
|
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(stub_i386_win32_pe, sizeof(stub_i386_win32_pe), 2);
|
initLoader(stub_i386_win32_pe, sizeof(stub_i386_win32_pe), 2);
|
||||||
if (isdll)
|
if (isdll)
|
||||||
addLoader("PEISDLL1");
|
addLoader("PEISDLL1");
|
||||||
addLoader("PEMAIN01",
|
addLoader("PEMAIN01", use_stub_relocs ? "PESOCREL" : "PESOCPIC", "PESOUNC0",
|
||||||
use_stub_relocs ? "PESOCREL" : "PESOCPIC",
|
|
||||||
"PESOUNC0",
|
|
||||||
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
||||||
tmp_tlsindex ? "PETLSHAK" : "",
|
tmp_tlsindex ? "PETLSHAK" : "", "PEMAIN02",
|
||||||
"PEMAIN02",
|
ph.first_offset_found == 1 ? "PEMAIN03" : "", getDecompressorSections(),
|
||||||
ph.first_offset_found == 1 ? "PEMAIN03" : "",
|
// multipass ? "PEMULTIP" : "",
|
||||||
getDecompressorSections(),
|
"PEMAIN10", nullptr);
|
||||||
//multipass ? "PEMULTIP" : "",
|
|
||||||
"PEMAIN10",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
addLoader(tmp_tlsindex ? "PETLSHAK2" : "");
|
addLoader(tmp_tlsindex ? "PETLSHAK2" : "");
|
||||||
if (ft->id)
|
if (ft->id) {
|
||||||
{
|
|
||||||
const unsigned texv = ih.codebase - rvamin;
|
const unsigned texv = ih.codebase - rvamin;
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addLoader(texv ? "PECTTPOS" : "PECTTNUL",nullptr);
|
addLoader(texv ? "PECTTPOS" : "PECTTNUL", nullptr);
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
if (soimport)
|
if (soimport)
|
||||||
addLoader("PEIMPORT",
|
addLoader("PEIMPORT", importbyordinal ? "PEIBYORD" : "", kernel32ordinal ? "PEK32ORD" : "",
|
||||||
importbyordinal ? "PEIBYORD" : "",
|
importbyordinal ? "PEIMORD1" : "", "PEIMPOR2", isdll ? "PEIERDLL" : "PEIEREXE",
|
||||||
kernel32ordinal ? "PEK32ORD" : "",
|
"PEIMDONE", nullptr);
|
||||||
importbyordinal ? "PEIMORD1" : "",
|
if (sorelocs) {
|
||||||
"PEIMPOR2",
|
|
||||||
isdll ? "PEIERDLL" : "PEIEREXE",
|
|
||||||
"PEIMDONE",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
if (sorelocs)
|
|
||||||
{
|
|
||||||
addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2",
|
addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2",
|
||||||
"PERELOC3,RELOC320",
|
"PERELOC3,RELOC320", big_relocs ? "REL32BIG" : "", "RELOC32J", nullptr);
|
||||||
big_relocs ? "REL32BIG" : "",
|
// FIXME: the following should be moved out of the above if
|
||||||
"RELOC32J",
|
addLoader(big_relocs & 6 ? "PERLOHI0" : "", big_relocs & 4 ? "PERELLO0" : "",
|
||||||
nullptr
|
big_relocs & 2 ? "PERELHI0" : "", nullptr);
|
||||||
);
|
|
||||||
//FIXME: the following should be moved out of the above if
|
|
||||||
addLoader(big_relocs&6 ? "PERLOHI0" : "",
|
|
||||||
big_relocs&4 ? "PERELLO0" : "",
|
|
||||||
big_relocs&2 ? "PERELHI0" : "",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (use_dep_hack)
|
if (use_dep_hack)
|
||||||
addLoader("PEDEPHAK", nullptr);
|
addLoader("PEDEPHAK", nullptr);
|
||||||
|
|
||||||
//NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann
|
// NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann
|
||||||
if(use_tls_callbacks)
|
if (use_tls_callbacks)
|
||||||
addLoader("PETLSC", nullptr);
|
addLoader("PETLSC", nullptr);
|
||||||
|
|
||||||
addLoader("PEMAIN20", nullptr);
|
addLoader("PEMAIN20", nullptr);
|
||||||
if (use_clear_dirty_stack)
|
if (use_clear_dirty_stack)
|
||||||
addLoader("CLEARSTACK", nullptr);
|
addLoader("CLEARSTACK", nullptr);
|
||||||
addLoader("PEMAIN21", nullptr);
|
addLoader("PEMAIN21", nullptr);
|
||||||
//NEW: last loader sections split up to insert TLS callback handler - Stefan Widmann
|
// NEW: last loader sections split up to insert TLS callback handler - Stefan Widmann
|
||||||
addLoader(ih.entry || !ilinker ? "PEDOJUMP" : "PERETURN", nullptr);
|
addLoader(ih.entry || !ilinker ? "PEDOJUMP" : "PERETURN", nullptr);
|
||||||
|
|
||||||
//NEW: TLS callback support PART 2, the callback handler - Stefan Widmann
|
// NEW: TLS callback support PART 2, the callback handler - Stefan Widmann
|
||||||
if(use_tls_callbacks)
|
if (use_tls_callbacks)
|
||||||
addLoader("PETLSC2", nullptr);
|
addLoader("PETLSC2", nullptr);
|
||||||
|
|
||||||
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackW32Pe::handleForceOption()
|
bool PackW32Pe::handleForceOption() {
|
||||||
{
|
return (ih.cpu < 0x14c || ih.cpu > 0x150) || (ih.opthdrsize != 0xe0) ||
|
||||||
return (ih.cpu < 0x14c || ih.cpu > 0x150)
|
((ih.flags & EXECUTABLE) == 0) ||
|
||||||
|| (ih.opthdrsize != 0xe0)
|
((ih.flags & BITS_32_MACHINE) ==
|
||||||
|| ((ih.flags & EXECUTABLE) == 0)
|
0) // NEW: 32 bit machine flag must be set - Stefan Widmann
|
||||||
|| ((ih.flags & BITS_32_MACHINE) == 0) //NEW: 32 bit machine flag must be set - Stefan Widmann
|
|| (ih.coffmagic !=
|
||||||
|| (ih.coffmagic != 0x10B) //COFF magic is 0x10B in PE files, 0x20B in PE32+ files - Stefan Widmann
|
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?
|
// || IDSIZE(PEDIR_COPYRIGHT)
|
||||||
// || IDSIZE(PEDIR_COPYRIGHT)
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection,
|
void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||||
unsigned sizeof_oh, unsigned ic,
|
unsigned ic, unsigned s1addr) {
|
||||||
unsigned s1addr)
|
|
||||||
{
|
|
||||||
const unsigned myimport = ncsection + soresources - rvamin;
|
const unsigned myimport = ncsection + soresources - rvamin;
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
linker->defineSymbol("original_entry", ih.entry);
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
if (use_dep_hack)
|
if (use_dep_hack) {
|
||||||
{
|
|
||||||
// This works around a "protection" introduced in MSVCRT80, which
|
// This works around a "protection" introduced in MSVCRT80, which
|
||||||
// works like this:
|
// works like this:
|
||||||
// When the compiler detects that it would link in some code from its
|
// When the compiler detects that it would link in some code from its
|
||||||
@ -222,27 +177,27 @@ void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
const unsigned swri = pe_offset + sizeof_oh + sizeof(pe_section_t) - 1;
|
const unsigned swri = pe_offset + sizeof_oh + sizeof(pe_section_t) - 1;
|
||||||
// make sure we only touch the minimum number of pages
|
// make sure we only touch the minimum number of pages
|
||||||
const unsigned addr = 0u - rvamin + swri;
|
const unsigned addr = 0u - rvamin + swri;
|
||||||
linker->defineSymbol("swri", addr & 0xfff); // page offset
|
linker->defineSymbol("swri", addr & 0xfff); // page offset
|
||||||
// check whether osection[0].flags and osection[1].flags
|
// check whether osection[0].flags and osection[1].flags
|
||||||
// are on the same page
|
// are on the same page
|
||||||
linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ?
|
linker->defineSymbol(
|
||||||
0x2000 : 0x1000); // 2 pages or 1 page
|
"vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ? 0x2000 : 0x1000); // 2 pages or 1 page
|
||||||
linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask
|
linker->defineSymbol("vp_base", addr & ~0xfff); // page mask
|
||||||
linker->defineSymbol("VirtualProtect", 0u-rvamin +
|
linker->defineSymbol("VirtualProtect",
|
||||||
ilinkerGetAddress("kernel32.dll", "VirtualProtect"));
|
0u - rvamin + ilinkerGetAddress("kernel32.dll", "VirtualProtect"));
|
||||||
}
|
}
|
||||||
linker->defineSymbol("reloc_delt", 0u - (unsigned) ih.imagebase - rvamin);
|
linker->defineSymbol("reloc_delt", 0u - (unsigned) ih.imagebase - rvamin);
|
||||||
linker->defineSymbol("start_of_relocs", crelocs);
|
linker->defineSymbol("start_of_relocs", crelocs);
|
||||||
|
|
||||||
if (ilinker) {
|
if (ilinker) {
|
||||||
if (!isdll)
|
if (!isdll)
|
||||||
linker->defineSymbol("ExitProcess", 0u-rvamin +
|
linker->defineSymbol("ExitProcess",
|
||||||
ilinkerGetAddress("kernel32.dll", "ExitProcess"));
|
0u - rvamin + ilinkerGetAddress("kernel32.dll", "ExitProcess"));
|
||||||
linker->defineSymbol("GetProcAddress", 0u-rvamin +
|
linker->defineSymbol("GetProcAddress",
|
||||||
ilinkerGetAddress("kernel32.dll", "GetProcAddress"));
|
0u - rvamin + ilinkerGetAddress("kernel32.dll", "GetProcAddress"));
|
||||||
linker->defineSymbol("kernel32_ordinals", myimport);
|
linker->defineSymbol("kernel32_ordinals", myimport);
|
||||||
linker->defineSymbol("LoadLibraryA", 0u-rvamin +
|
linker->defineSymbol("LoadLibraryA",
|
||||||
ilinkerGetAddress("kernel32.dll", "LoadLibraryA"));
|
0u - rvamin + ilinkerGetAddress("kernel32.dll", "LoadLibraryA"));
|
||||||
linker->defineSymbol("start_of_imports", myimport);
|
linker->defineSymbol("start_of_imports", myimport);
|
||||||
linker->defineSymbol("compressed_imports", cimports);
|
linker->defineSymbol("compressed_imports", cimports);
|
||||||
}
|
}
|
||||||
@ -253,8 +208,8 @@ void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
// in case of overlapping decompression, this hack is needed,
|
// in case of overlapping decompression, this hack is needed,
|
||||||
// because windoze zeroes the word pointed by tlsindex before
|
// because windoze zeroes the word pointed by tlsindex before
|
||||||
// it starts programs
|
// it starts programs
|
||||||
linker->defineSymbol("tls_value", (tlsindex + 4 > s1addr) ?
|
linker->defineSymbol("tls_value",
|
||||||
get_le32(obuf + tlsindex - s1addr - ic) : 0);
|
(tlsindex + 4 > s1addr) ? get_le32(obuf + tlsindex - s1addr - ic) : 0);
|
||||||
linker->defineSymbol("tls_address", tlsindex - rvamin);
|
linker->defineSymbol("tls_address", tlsindex - rvamin);
|
||||||
|
|
||||||
linker->defineSymbol("icon_delta", icondir_count - 1);
|
linker->defineSymbol("icon_delta", icondir_count - 1);
|
||||||
@ -264,44 +219,34 @@ void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);
|
linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);
|
||||||
linker->defineSymbol("start_of_compressed", use_stub_relocs ? esi0 + ih.imagebase : esi0);
|
linker->defineSymbol("start_of_compressed", use_stub_relocs ? esi0 + ih.imagebase : esi0);
|
||||||
|
|
||||||
if (use_tls_callbacks)
|
if (use_tls_callbacks) {
|
||||||
{
|
// esi is ih.imagebase + rvamin
|
||||||
//esi is ih.imagebase + rvamin
|
|
||||||
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr);
|
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr);
|
||||||
linker->defineSymbol("tls_module_base", 0u - rvamin);
|
linker->defineSymbol("tls_module_base", 0u - rvamin);
|
||||||
}
|
}
|
||||||
|
|
||||||
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
|
linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);
|
||||||
//linker->dumpSymbols();
|
// linker->dumpSymbols();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW32Pe::addNewRelocations(Reloc &rel, unsigned base)
|
void PackW32Pe::addNewRelocations(Reloc &rel, unsigned base) {
|
||||||
{
|
|
||||||
if (use_stub_relocs)
|
if (use_stub_relocs)
|
||||||
rel.add(base + linker->getSymbolOffset("PESOCREL") + 1, 3);
|
rel.add(base + linker->getSymbolOffset("PESOCREL") + 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW32Pe::setOhDataBase(const pe_section_t *osection)
|
void PackW32Pe::setOhDataBase(const pe_section_t *osection) { oh.database = osection[2].vaddr; }
|
||||||
{
|
|
||||||
oh.database = osection[2].vaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackW32Pe::setOhHeaderSize(const pe_section_t *osection)
|
void PackW32Pe::setOhHeaderSize(const pe_section_t *osection) {
|
||||||
{
|
|
||||||
oh.headersize = ALIGN_UP(pe_offset + sizeof(oh) + sizeof(*osection) * oh.objects, oh.filealign);
|
oh.headersize = ALIGN_UP(pe_offset + sizeof(oh) + sizeof(*osection) * oh.objects, oh.filealign);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW32Pe::pack(OutputFile *fo)
|
void PackW32Pe::pack(OutputFile *fo) {
|
||||||
{
|
super::pack0(fo,
|
||||||
super::pack0(fo
|
(1u << IMAGE_SUBSYSTEM_WINDOWS_GUI) | (1u << IMAGE_SUBSYSTEM_WINDOWS_CUI) |
|
||||||
, (1u<<IMAGE_SUBSYSTEM_WINDOWS_GUI)
|
(1u << IMAGE_SUBSYSTEM_EFI_APPLICATION) |
|
||||||
| (1u<<IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
(1u << IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) |
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_APPLICATION)
|
(1u << IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) | (1u << IMAGE_SUBSYSTEM_EFI_ROM),
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
|
0x400000, false);
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
|
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_ROM)
|
|
||||||
, 0x400000
|
|
||||||
, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
193
src/p_w64pep.cpp
193
src/p_w64pep.cpp
@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@ -39,63 +38,46 @@
|
|||||||
#include "p_w64pep.h"
|
#include "p_w64pep.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/amd64-win64.pep.h"
|
#include "stub/amd64-win64.pep.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackW64Pep::PackW64Pep(InputFile *f) : super(f)
|
PackW64Pep::PackW64Pep(InputFile *f) : super(f) { use_stub_relocs = false; }
|
||||||
{
|
|
||||||
use_stub_relocs = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
PackW64Pep::~PackW64Pep() {}
|
||||||
|
|
||||||
PackW64Pep::~PackW64Pep()
|
const int *PackW64Pep::getCompressionMethods(int method, int level) const {
|
||||||
{}
|
bool small = ih.codesize + ih.datasize <= 256 * 1024;
|
||||||
|
|
||||||
|
|
||||||
const int *PackW64Pep::getCompressionMethods(int method, int level) const
|
|
||||||
{
|
|
||||||
bool small = ih.codesize + ih.datasize <= 256*1024;
|
|
||||||
return Packer::getDefaultCompressionMethods_le32(method, level, small);
|
return Packer::getDefaultCompressionMethods_le32(method, level, small);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackW64Pep::getFilters() const {
|
||||||
const int *PackW64Pep::getFilters() const
|
static const int filters[] = {0x49, FT_END};
|
||||||
{
|
|
||||||
static const int filters[] = { 0x49, FT_END };
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackW64Pep::newLinker() const { return new ElfLinkerAMD64; }
|
||||||
Linker* PackW64Pep::newLinker() const
|
|
||||||
{
|
|
||||||
return new ElfLinkerAMD64;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// pack
|
// pack
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackW64Pep::canPack()
|
bool PackW64Pep::canPack() {
|
||||||
{
|
// just check if machine type is 0x8664
|
||||||
//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 false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackW64Pep::buildLoader(const Filter *ft) {
|
||||||
void PackW64Pep::buildLoader(const Filter *ft)
|
|
||||||
{
|
|
||||||
// recompute tlsindex (see pack() below)
|
// recompute tlsindex (see pack() below)
|
||||||
unsigned tmp_tlsindex = tlsindex;
|
unsigned tmp_tlsindex = tlsindex;
|
||||||
const unsigned oam1 = ih.objectalign - 1;
|
const unsigned oam1 = ih.objectalign - 1;
|
||||||
const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
|
const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) & ~oam1;
|
||||||
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
|
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) & ~oam1) > tlsindex + 4)
|
||||||
tmp_tlsindex = 0;
|
tmp_tlsindex = 0;
|
||||||
|
|
||||||
// prepare loader
|
// prepare loader
|
||||||
@ -105,61 +87,41 @@ void PackW64Pep::buildLoader(const Filter *ft)
|
|||||||
addLoader("PEISDLL0");
|
addLoader("PEISDLL0");
|
||||||
if (isefi)
|
if (isefi)
|
||||||
addLoader("PEISEFI0");
|
addLoader("PEISEFI0");
|
||||||
addLoader(isdll ? "PEISDLL1" : "",
|
addLoader(isdll ? "PEISDLL1" : "", "PEMAIN01",
|
||||||
"PEMAIN01",
|
|
||||||
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "",
|
||||||
tmp_tlsindex ? "PETLSHAK" : "",
|
tmp_tlsindex ? "PETLSHAK" : "", "PEMAIN02",
|
||||||
"PEMAIN02",
|
// ph.first_offset_found == 1 ? "PEMAIN03" : "",
|
||||||
//ph.first_offset_found == 1 ? "PEMAIN03" : "",
|
M_IS_LZMA(ph.method) ? "LZMA_HEAD,LZMA_ELF00,LZMA_DEC20,LZMA_TAIL"
|
||||||
M_IS_LZMA(ph.method) ? "LZMA_HEAD,LZMA_ELF00,LZMA_DEC20,LZMA_TAIL" :
|
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B"
|
||||||
M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B" :
|
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D"
|
||||||
M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D" :
|
: M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E"
|
||||||
M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E" : "UNKNOWN_COMPRESSION_METHOD",
|
: "UNKNOWN_COMPRESSION_METHOD",
|
||||||
//getDecompressorSections(),
|
// getDecompressorSections(),
|
||||||
/*multipass ? "PEMULTIP" : */ "",
|
/*multipass ? "PEMULTIP" : */ "", "PEMAIN10", nullptr);
|
||||||
"PEMAIN10",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
addLoader(tmp_tlsindex ? "PETLSHAK2" : "");
|
addLoader(tmp_tlsindex ? "PETLSHAK2" : "");
|
||||||
if (ft->id)
|
if (ft->id) {
|
||||||
{
|
|
||||||
const unsigned texv = ih.codebase - rvamin;
|
const unsigned texv = ih.codebase - rvamin;
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addLoader(texv ? "PECTTPOS" : "PECTTNUL",nullptr);
|
addLoader(texv ? "PECTTPOS" : "PECTTNUL", nullptr);
|
||||||
addLoader("PEFILTER49");
|
addLoader("PEFILTER49");
|
||||||
}
|
}
|
||||||
if (soimport)
|
if (soimport)
|
||||||
addLoader("PEIMPORT",
|
addLoader("PEIMPORT", importbyordinal ? "PEIBYORD" : "", kernel32ordinal ? "PEK32ORD" : "",
|
||||||
importbyordinal ? "PEIBYORD" : "",
|
importbyordinal ? "PEIMORD1" : "", "PEIMPOR2", isdll ? "PEIERDLL" : "PEIEREXE",
|
||||||
kernel32ordinal ? "PEK32ORD" : "",
|
"PEIMDONE", nullptr);
|
||||||
importbyordinal ? "PEIMORD1" : "",
|
if (sorelocs) {
|
||||||
"PEIMPOR2",
|
|
||||||
isdll ? "PEIERDLL" : "PEIEREXE",
|
|
||||||
"PEIMDONE",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
if (sorelocs)
|
|
||||||
{
|
|
||||||
addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2",
|
addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2",
|
||||||
"PERELOC3",
|
"PERELOC3", big_relocs ? "REL64BIG" : "", "RELOC64J", nullptr);
|
||||||
big_relocs ? "REL64BIG" : "",
|
if __acc_cte (0) {
|
||||||
"RELOC64J",
|
addLoader(big_relocs & 6 ? "PERLOHI0" : "", big_relocs & 4 ? "PERELLO0" : "",
|
||||||
nullptr
|
big_relocs & 2 ? "PERELHI0" : "", nullptr);
|
||||||
);
|
|
||||||
if __acc_cte(0)
|
|
||||||
{
|
|
||||||
addLoader(big_relocs&6 ? "PERLOHI0" : "",
|
|
||||||
big_relocs&4 ? "PERELLO0" : "",
|
|
||||||
big_relocs&2 ? "PERELHI0" : "",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (use_dep_hack)
|
if (use_dep_hack)
|
||||||
addLoader("PEDEPHAK", nullptr);
|
addLoader("PEDEPHAK", nullptr);
|
||||||
|
|
||||||
//NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann
|
// NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann
|
||||||
if(use_tls_callbacks)
|
if (use_tls_callbacks)
|
||||||
addLoader("PETLSC", nullptr);
|
addLoader("PETLSC", nullptr);
|
||||||
|
|
||||||
addLoader("PEMAIN20", nullptr);
|
addLoader("PEMAIN20", nullptr);
|
||||||
@ -173,35 +135,32 @@ void PackW64Pep::buildLoader(const Filter *ft)
|
|||||||
addLoader("PEISEFI9");
|
addLoader("PEISEFI9");
|
||||||
addLoader(ih.entry || !ilinker ? "PEDOJUMP" : "PERETURN", nullptr);
|
addLoader(ih.entry || !ilinker ? "PEDOJUMP" : "PERETURN", nullptr);
|
||||||
|
|
||||||
//NEW: TLS callback support PART 2, the callback handler - Stefan Widmann
|
// NEW: TLS callback support PART 2, the callback handler - Stefan Widmann
|
||||||
if(use_tls_callbacks)
|
if (use_tls_callbacks)
|
||||||
addLoader("PETLSC2", nullptr);
|
addLoader("PETLSC2", nullptr);
|
||||||
|
|
||||||
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackW64Pep::handleForceOption()
|
bool PackW64Pep::handleForceOption() {
|
||||||
{
|
return (ih.cpu != 0x8664) // CPU magic of AMD64 is 0x8664
|
||||||
return (ih.cpu != 0x8664) //CPU magic of AMD64 is 0x8664
|
||
|
||||||
|| (ih.opthdrsize != 0xF0) //optional header size is 0xF0 in PE32+ files - Stefan Widmann
|
(ih.opthdrsize != 0xF0) // optional header size is 0xF0 in PE32+ files - Stefan Widmann
|
||||||
|| (ih.coffmagic != 0x20B) //COFF magic is 0x20B in PE+ files, 0x10B in "normal" 32 bit PE files - Stefan Widmann
|
|| (ih.coffmagic != 0x20B) // COFF magic is 0x20B in PE+ files, 0x10B in "normal" 32 bit
|
||||||
|| ((ih.flags & EXECUTABLE) == 0)
|
// PE files - Stefan Widmann
|
||||||
|| ((ih.flags & BITS_32_MACHINE) != 0) //NEW: 32 bit machine flag may not be set - Stefan Widmann
|
|| ((ih.flags & EXECUTABLE) == 0) ||
|
||||||
|| (ih.entry == 0 && !isdll)
|
((ih.flags & BITS_32_MACHINE) !=
|
||||||
|| (ih.ddirsentries != 16)
|
0) // NEW: 32 bit machine flag may not be set - Stefan Widmann
|
||||||
;
|
|| (ih.entry == 0 && !isdll) || (ih.ddirsentries != 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
|
void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||||
unsigned sizeof_oh, unsigned ic,
|
unsigned ic, unsigned s1addr) {
|
||||||
unsigned s1addr)
|
|
||||||
{
|
|
||||||
const unsigned myimport = ncsection + soresources - rvamin;
|
const unsigned myimport = ncsection + soresources - rvamin;
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
linker->defineSymbol("original_entry", ih.entry);
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
if (use_dep_hack)
|
if (use_dep_hack) {
|
||||||
{
|
|
||||||
// This works around a "protection" introduced in MSVCRT80, which
|
// This works around a "protection" introduced in MSVCRT80, which
|
||||||
// works like this:
|
// works like this:
|
||||||
// When the compiler detects that it would link in some code from its
|
// When the compiler detects that it would link in some code from its
|
||||||
@ -221,32 +180,27 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
const unsigned swri = pe_offset + sizeof_oh + sizeof(pe_section_t) - 1;
|
const unsigned swri = pe_offset + sizeof_oh + sizeof(pe_section_t) - 1;
|
||||||
// make sure we only touch the minimum number of pages
|
// make sure we only touch the minimum number of pages
|
||||||
const unsigned addr = 0u - rvamin + swri;
|
const unsigned addr = 0u - rvamin + swri;
|
||||||
linker->defineSymbol("swri", addr & 0xfff); // page offset
|
linker->defineSymbol("swri", addr & 0xfff); // page offset
|
||||||
// check whether osection[0].flags and osection[1].flags
|
// check whether osection[0].flags and osection[1].flags
|
||||||
// are on the same page
|
// are on the same page
|
||||||
linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ?
|
linker->defineSymbol(
|
||||||
0x2000 : 0x1000); // 2 pages or 1 page
|
"vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ? 0x2000 : 0x1000); // 2 pages or 1 page
|
||||||
linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask
|
linker->defineSymbol("vp_base", addr & ~0xfff); // page mask
|
||||||
linker->defineSymbol("VirtualProtect",
|
linker->defineSymbol("VirtualProtect", ilinkerGetAddress("kernel32.dll", "VirtualProtect"));
|
||||||
ilinkerGetAddress("kernel32.dll", "VirtualProtect"));
|
|
||||||
}
|
}
|
||||||
linker->defineSymbol("start_of_relocs", crelocs);
|
linker->defineSymbol("start_of_relocs", crelocs);
|
||||||
|
|
||||||
if (ilinker) {
|
if (ilinker) {
|
||||||
if (!isdll)
|
if (!isdll)
|
||||||
linker->defineSymbol("ExitProcess",
|
linker->defineSymbol("ExitProcess", ilinkerGetAddress("kernel32.dll", "ExitProcess"));
|
||||||
ilinkerGetAddress("kernel32.dll", "ExitProcess"));
|
linker->defineSymbol("GetProcAddress", ilinkerGetAddress("kernel32.dll", "GetProcAddress"));
|
||||||
linker->defineSymbol("GetProcAddress",
|
|
||||||
ilinkerGetAddress("kernel32.dll", "GetProcAddress"));
|
|
||||||
linker->defineSymbol("kernel32_ordinals", myimport);
|
linker->defineSymbol("kernel32_ordinals", myimport);
|
||||||
linker->defineSymbol("LoadLibraryA",
|
linker->defineSymbol("LoadLibraryA", ilinkerGetAddress("kernel32.dll", "LoadLibraryA"));
|
||||||
ilinkerGetAddress("kernel32.dll", "LoadLibraryA"));
|
|
||||||
linker->defineSymbol("start_of_imports", myimport);
|
linker->defineSymbol("start_of_imports", myimport);
|
||||||
linker->defineSymbol("compressed_imports", cimports);
|
linker->defineSymbol("compressed_imports", cimports);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (M_IS_LZMA(ph.method))
|
if (M_IS_LZMA(ph.method)) {
|
||||||
{
|
|
||||||
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||||
linker->defineSymbol("lzma_u_len", ph.u_len);
|
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||||
}
|
}
|
||||||
@ -255,8 +209,8 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
// in case of overlapping decompression, this hack is needed,
|
// in case of overlapping decompression, this hack is needed,
|
||||||
// because windoze zeroes the word pointed by tlsindex before
|
// because windoze zeroes the word pointed by tlsindex before
|
||||||
// it starts programs
|
// it starts programs
|
||||||
linker->defineSymbol("tls_value", (tlsindex + 4 > s1addr) ?
|
linker->defineSymbol("tls_value",
|
||||||
get_le32(obuf + tlsindex - s1addr - ic) : 0);
|
(tlsindex + 4 > s1addr) ? get_le32(obuf + tlsindex - s1addr - ic) : 0);
|
||||||
linker->defineSymbol("tls_address", tlsindex - rvamin);
|
linker->defineSymbol("tls_address", tlsindex - rvamin);
|
||||||
|
|
||||||
linker->defineSymbol("icon_delta", icondir_count - 1);
|
linker->defineSymbol("icon_delta", icondir_count - 1);
|
||||||
@ -266,8 +220,7 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);
|
linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);
|
||||||
linker->defineSymbol("start_of_compressed", esi0);
|
linker->defineSymbol("start_of_compressed", esi0);
|
||||||
|
|
||||||
if (use_tls_callbacks)
|
if (use_tls_callbacks) {
|
||||||
{
|
|
||||||
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr - ih.imagebase);
|
linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr - ih.imagebase);
|
||||||
linker->defineSymbol("tls_module_base", 0u - rvamin);
|
linker->defineSymbol("tls_module_base", 0u - rvamin);
|
||||||
}
|
}
|
||||||
@ -275,21 +228,17 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
|
|||||||
linker->defineSymbol("START", upxsection);
|
linker->defineSymbol("START", upxsection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW64Pep::setOhHeaderSize(const pe_section_t *osection)
|
void PackW64Pep::setOhHeaderSize(const pe_section_t *osection) {
|
||||||
{
|
|
||||||
oh.headersize = ALIGN_UP(pe_offset + sizeof(oh) + sizeof(*osection) * oh.objects, oh.filealign);
|
oh.headersize = ALIGN_UP(pe_offset + sizeof(oh) + sizeof(*osection) * oh.objects, oh.filealign);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackW64Pep::pack(OutputFile *fo)
|
void PackW64Pep::pack(OutputFile *fo) {
|
||||||
{
|
super::pack0(fo,
|
||||||
super::pack0(fo
|
(1u << IMAGE_SUBSYSTEM_WINDOWS_GUI) | (1u << IMAGE_SUBSYSTEM_WINDOWS_CUI) |
|
||||||
, (1u<<IMAGE_SUBSYSTEM_WINDOWS_GUI)
|
(1u << IMAGE_SUBSYSTEM_EFI_APPLICATION) |
|
||||||
| (1u<<IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
(1u << IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) |
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_APPLICATION)
|
(1u << IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) | (1u << IMAGE_SUBSYSTEM_EFI_ROM),
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
|
0x0000000140000000ULL);
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
|
|
||||||
| (1u<<IMAGE_SUBSYSTEM_EFI_ROM)
|
|
||||||
, 0x0000000140000000ULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
1891
src/pefile.cpp
1891
src/pefile.cpp
File diff suppressed because it is too large
Load Diff
440
src/pefile.h
440
src/pefile.h
@ -25,19 +25,17 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_PEFILE_H
|
#ifndef UPX_PEFILE_H__
|
||||||
#define __UPX_PEFILE_H 1
|
#define UPX_PEFILE_H__ 1
|
||||||
|
|
||||||
#include "util/membuffer.h"
|
#include "util/membuffer.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// general/pe handling
|
// general/pe handling
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PeFile : public Packer
|
class PeFile : public Packer {
|
||||||
{
|
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
public:
|
public:
|
||||||
virtual int getVersion() const override { return 13; }
|
virtual int getVersion() const override { return 13; }
|
||||||
@ -53,20 +51,17 @@ protected:
|
|||||||
virtual ~PeFile();
|
virtual ~PeFile();
|
||||||
|
|
||||||
void readSectionHeaders(unsigned objs, unsigned sizeof_ih);
|
void readSectionHeaders(unsigned objs, unsigned sizeof_ih);
|
||||||
unsigned readSections(unsigned objs, unsigned usize,
|
unsigned readSections(unsigned objs, unsigned usize, unsigned ih_filealign,
|
||||||
unsigned ih_filealign, unsigned ih_datasize);
|
unsigned ih_datasize);
|
||||||
void checkHeaderValues(unsigned subsystem, unsigned mask,
|
void checkHeaderValues(unsigned subsystem, unsigned mask, unsigned ih_entry,
|
||||||
unsigned ih_entry, unsigned ih_filealign);
|
unsigned ih_filealign);
|
||||||
unsigned handleStripRelocs(upx_uint64_t ih_imagebase,
|
unsigned handleStripRelocs(upx_uint64_t ih_imagebase, upx_uint64_t default_imagebase,
|
||||||
upx_uint64_t default_imagebase,
|
|
||||||
LE16 &dllflags);
|
LE16 &dllflags);
|
||||||
|
|
||||||
virtual bool handleForceOption() = 0;
|
virtual bool handleForceOption() = 0;
|
||||||
virtual void callCompressWithFilters(Filter &, int filter_strategy,
|
virtual void callCompressWithFilters(Filter &, int filter_strategy, unsigned ih_codebase);
|
||||||
unsigned ih_codebase);
|
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
|
unsigned isize_isplit, unsigned s1addr) = 0;
|
||||||
unsigned sizeof_oh, unsigned isize_isplit,
|
|
||||||
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);
|
||||||
@ -75,20 +70,18 @@ protected:
|
|||||||
virtual void setOhHeaderSize(const pe_section_t *osection) = 0;
|
virtual void setOhHeaderSize(const pe_section_t *osection) = 0;
|
||||||
|
|
||||||
template <typename LEXX, typename ht>
|
template <typename LEXX, typename ht>
|
||||||
void pack0(OutputFile *fo, ht &ih, ht &oh,
|
void pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
|
||||||
unsigned subsystem_mask, upx_uint64_t default_imagebase,
|
upx_uint64_t default_imagebase, bool last_section_rsrc_only);
|
||||||
bool last_section_rsrc_only);
|
|
||||||
|
|
||||||
template <typename ht, typename LEXX, typename ord_mask_t>
|
template <typename ht, typename LEXX, typename ord_mask_t>
|
||||||
void unpack0(OutputFile *fo, const ht &ih, ht &oh,
|
void unpack0(OutputFile *fo, const ht &ih, ht &oh, ord_mask_t ord_mask, bool set_oft);
|
||||||
ord_mask_t ord_mask, bool set_oft);
|
|
||||||
|
|
||||||
// unpacker capabilities
|
// unpacker capabilities
|
||||||
virtual bool canUnpackVersion(int version) const override
|
virtual bool canUnpackVersion(int version) const override {
|
||||||
{ return (version >= 12 && version <= 13); }
|
return (version >= 12 && version <= 13);
|
||||||
|
}
|
||||||
|
|
||||||
int canUnpack0(unsigned max_sections, unsigned objs,
|
int canUnpack0(unsigned max_sections, unsigned objs, unsigned ih_entry, unsigned ih_size);
|
||||||
unsigned ih_entry, unsigned ih_size);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
@ -101,8 +94,7 @@ protected:
|
|||||||
unsigned processImports0(ord_mask_t ord_mask);
|
unsigned processImports0(ord_mask_t ord_mask);
|
||||||
|
|
||||||
template <typename LEXX, typename ord_mask_t>
|
template <typename LEXX, typename ord_mask_t>
|
||||||
void rebuildImports(SPAN_S(upx_byte) & extrainfo,
|
void rebuildImports(SPAN_S(upx_byte) & extrainfo, ord_mask_t ord_mask, bool set_oft);
|
||||||
ord_mask_t ord_mask, bool set_oft);
|
|
||||||
virtual unsigned processImports() = 0;
|
virtual unsigned processImports() = 0;
|
||||||
virtual void processImports2(unsigned, unsigned);
|
virtual void processImports2(unsigned, unsigned);
|
||||||
MemBuffer mb_oimport;
|
MemBuffer mb_oimport;
|
||||||
@ -118,8 +110,7 @@ protected:
|
|||||||
|
|
||||||
virtual void processRelocs() = 0;
|
virtual void processRelocs() = 0;
|
||||||
void processRelocs(Reloc *);
|
void processRelocs(Reloc *);
|
||||||
void rebuildRelocs(SPAN_S(upx_byte) &, unsigned bits,
|
void rebuildRelocs(SPAN_S(upx_byte) &, unsigned bits, unsigned flags, upx_uint64_t imagebase);
|
||||||
unsigned flags, upx_uint64_t imagebase);
|
|
||||||
MemBuffer mb_orelocs;
|
MemBuffer mb_orelocs;
|
||||||
SPAN_0(upx_byte) orelocs = nullptr;
|
SPAN_0(upx_byte) orelocs = nullptr;
|
||||||
unsigned sorelocs;
|
unsigned sorelocs;
|
||||||
@ -127,7 +118,7 @@ protected:
|
|||||||
unsigned soxrelocs;
|
unsigned soxrelocs;
|
||||||
|
|
||||||
void processExports(Export *);
|
void processExports(Export *);
|
||||||
void processExports(Export *,unsigned);
|
void processExports(Export *, unsigned);
|
||||||
void rebuildExports();
|
void rebuildExports();
|
||||||
MemBuffer mb_oexport;
|
MemBuffer mb_oexport;
|
||||||
SPAN_0(upx_byte) oexport = nullptr;
|
SPAN_0(upx_byte) oexport = nullptr;
|
||||||
@ -143,11 +134,10 @@ protected:
|
|||||||
template <typename>
|
template <typename>
|
||||||
struct tls_traits;
|
struct tls_traits;
|
||||||
template <typename LEXX>
|
template <typename LEXX>
|
||||||
void processTls1(Interval *iv,
|
void processTls1(Interval *iv, typename tls_traits<LEXX>::cb_value_t imagebase,
|
||||||
typename tls_traits<LEXX>::cb_value_t imagebase,
|
|
||||||
unsigned imagesize); // pass 1
|
unsigned imagesize); // pass 1
|
||||||
template <typename LEXX>
|
template <typename LEXX>
|
||||||
void processTls2(Reloc *rel,const Interval *iv,unsigned newaddr,
|
void processTls2(Reloc *rel, const Interval *iv, unsigned newaddr,
|
||||||
typename tls_traits<LEXX>::cb_value_t imagebase); // pass 2
|
typename tls_traits<LEXX>::cb_value_t imagebase); // pass 2
|
||||||
virtual void processTls(Interval *iv) = 0;
|
virtual void processTls(Interval *iv) = 0;
|
||||||
virtual void processTls(Reloc *r, const Interval *iv, unsigned a) = 0;
|
virtual void processTls(Reloc *r, const Interval *iv, unsigned a) = 0;
|
||||||
@ -175,22 +165,22 @@ protected:
|
|||||||
bool importbyordinal;
|
bool importbyordinal;
|
||||||
bool kernel32ordinal;
|
bool kernel32ordinal;
|
||||||
unsigned rvamin;
|
unsigned rvamin;
|
||||||
unsigned cimports; // rva of preprocessed imports
|
unsigned cimports; // rva of preprocessed imports
|
||||||
unsigned crelocs; // rva of preprocessed fixups
|
unsigned crelocs; // rva of preprocessed fixups
|
||||||
int big_relocs;
|
int big_relocs;
|
||||||
|
|
||||||
struct alignas(1) ddirs_t {
|
struct alignas(1) ddirs_t {
|
||||||
LE32 vaddr;
|
LE32 vaddr;
|
||||||
LE32 size;
|
LE32 size;
|
||||||
};
|
};
|
||||||
ddirs_t *iddirs;
|
ddirs_t *iddirs;
|
||||||
ddirs_t *oddirs;
|
ddirs_t *oddirs;
|
||||||
|
|
||||||
struct alignas(1) import_desc {
|
struct alignas(1) import_desc {
|
||||||
LE32 oft; // orig first thunk
|
LE32 oft; // orig first thunk
|
||||||
char _[8];
|
char _[8];
|
||||||
LE32 dllname;
|
LE32 dllname;
|
||||||
LE32 iat; // import address table
|
LE32 iat; // import address table
|
||||||
};
|
};
|
||||||
|
|
||||||
LE32 &IDSIZE(unsigned x);
|
LE32 &IDSIZE(unsigned x);
|
||||||
@ -199,13 +189,13 @@ protected:
|
|||||||
LE32 &ODADDR(unsigned x);
|
LE32 &ODADDR(unsigned x);
|
||||||
|
|
||||||
struct alignas(1) pe_section_t {
|
struct alignas(1) pe_section_t {
|
||||||
char name[8];
|
char name[8];
|
||||||
LE32 vsize;
|
LE32 vsize;
|
||||||
LE32 vaddr;
|
LE32 vaddr;
|
||||||
LE32 size;
|
LE32 size;
|
||||||
LE32 rawdataptr;
|
LE32 rawdataptr;
|
||||||
char _[12];
|
char _[12];
|
||||||
LE32 flags;
|
LE32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
MemBuffer mb_isection;
|
MemBuffer mb_isection;
|
||||||
@ -217,105 +207,119 @@ protected:
|
|||||||
bool use_clear_dirty_stack;
|
bool use_clear_dirty_stack;
|
||||||
bool use_stub_relocs;
|
bool use_stub_relocs;
|
||||||
|
|
||||||
|
static unsigned virta2objnum(unsigned, SPAN_0(pe_section_t), unsigned);
|
||||||
static unsigned virta2objnum (unsigned, SPAN_0(pe_section_t), unsigned);
|
unsigned tryremove(unsigned, unsigned);
|
||||||
unsigned tryremove (unsigned, unsigned);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PEDIR_EXPORT = 0,
|
PEDIR_EXPORT = 0,
|
||||||
PEDIR_IMPORT = 1,
|
PEDIR_IMPORT = 1,
|
||||||
PEDIR_RESOURCE = 2,
|
PEDIR_RESOURCE = 2,
|
||||||
PEDIR_EXCEPTION = 3, // Exception table
|
PEDIR_EXCEPTION = 3, // Exception table
|
||||||
PEDIR_SEC = 4, // Certificate table (file pointer)
|
PEDIR_SEC = 4, // Certificate table (file pointer)
|
||||||
PEDIR_RELOC = 5,
|
PEDIR_RELOC = 5,
|
||||||
PEDIR_DEBUG = 6,
|
PEDIR_DEBUG = 6,
|
||||||
PEDIR_COPYRIGHT = 7, // Architecture-specific data
|
PEDIR_COPYRIGHT = 7, // Architecture-specific data
|
||||||
PEDIR_GLOBALPTR = 8, // Global pointer
|
PEDIR_GLOBALPTR = 8, // Global pointer
|
||||||
PEDIR_TLS = 9,
|
PEDIR_TLS = 9,
|
||||||
PEDIR_LOADCONF = 10, // Load Config Table
|
PEDIR_LOADCONF = 10, // Load Config Table
|
||||||
PEDIR_BOUNDIM = 11,
|
PEDIR_BOUNDIM = 11,
|
||||||
PEDIR_IAT = 12,
|
PEDIR_IAT = 12,
|
||||||
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
|
PEDIR_DELAYIMP = 13, // Delay Import Descriptor
|
||||||
PEDIR_COMRT = 14, // Com+ Runtime Header
|
PEDIR_COMRT = 14, // Com+ Runtime Header
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PEFL_CODE = 0x20,
|
PEFL_CODE = 0x20,
|
||||||
PEFL_DATA = 0x40,
|
PEFL_DATA = 0x40,
|
||||||
PEFL_BSS = 0x80,
|
PEFL_BSS = 0x80,
|
||||||
PEFL_INFO = 0x200,
|
PEFL_INFO = 0x200,
|
||||||
PEFL_EXTRELS = 0x01000000, // extended relocations
|
PEFL_EXTRELS = 0x01000000, // extended relocations
|
||||||
PEFL_DISCARD = 0x02000000,
|
PEFL_DISCARD = 0x02000000,
|
||||||
PEFL_NOCACHE = 0x04000000,
|
PEFL_NOCACHE = 0x04000000,
|
||||||
PEFL_NOPAGE = 0x08000000,
|
PEFL_NOPAGE = 0x08000000,
|
||||||
PEFL_SHARED = 0x10000000,
|
PEFL_SHARED = 0x10000000,
|
||||||
PEFL_EXEC = 0x20000000,
|
PEFL_EXEC = 0x20000000,
|
||||||
PEFL_READ = 0x40000000,
|
PEFL_READ = 0x40000000,
|
||||||
PEFL_WRITE = 0x80000000,
|
PEFL_WRITE = 0x80000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RELOCS_STRIPPED = 0x0001,
|
RELOCS_STRIPPED = 0x0001,
|
||||||
EXECUTABLE = 0x0002,
|
EXECUTABLE = 0x0002,
|
||||||
LNUM_STRIPPED = 0x0004,
|
LNUM_STRIPPED = 0x0004,
|
||||||
LSYMS_STRIPPED = 0x0008,
|
LSYMS_STRIPPED = 0x0008,
|
||||||
AGGRESSIVE_TRIM = 0x0010,
|
AGGRESSIVE_TRIM = 0x0010,
|
||||||
TWO_GIGS_AWARE = 0x0020,
|
TWO_GIGS_AWARE = 0x0020,
|
||||||
FLITTLE_ENDIAN = 0x0080,
|
FLITTLE_ENDIAN = 0x0080,
|
||||||
BITS_32_MACHINE = 0x0100,
|
BITS_32_MACHINE = 0x0100,
|
||||||
DEBUG_STRIPPED = 0x0200,
|
DEBUG_STRIPPED = 0x0200,
|
||||||
REMOVABLE_SWAP = 0x0400,
|
REMOVABLE_SWAP = 0x0400,
|
||||||
SYSTEM_PROGRAM = 0x1000,
|
SYSTEM_PROGRAM = 0x1000,
|
||||||
DLL_FLAG = 0x2000,
|
DLL_FLAG = 0x2000,
|
||||||
FBIG_ENDIAN = 0x8000,
|
FBIG_ENDIAN = 0x8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
//NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann
|
// NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann
|
||||||
enum {
|
enum {
|
||||||
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
|
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
|
||||||
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040,
|
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040,
|
||||||
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
|
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
|
||||||
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100,
|
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100,
|
||||||
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
|
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
|
||||||
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
|
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
|
||||||
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
|
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
|
||||||
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
|
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
|
||||||
IMAGE_DLLCHARACTERISTICS_CONTROL_FLOW_GUARD = 0x4000,
|
IMAGE_DLLCHARACTERISTICS_CONTROL_FLOW_GUARD = 0x4000,
|
||||||
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000,
|
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IMAGE_SUBSYSTEM_UNKNOWN = 0,
|
IMAGE_SUBSYSTEM_UNKNOWN = 0,
|
||||||
IMAGE_SUBSYSTEM_NATIVE = 1,
|
IMAGE_SUBSYSTEM_NATIVE = 1,
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, // Grapical
|
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, // Grapical
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, // Character-mode
|
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, // Character-mode
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_OS2_CUI = 5,
|
IMAGE_SUBSYSTEM_WINDOWS_OS2_CUI = 5,
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_POSIX_CUI = 7,
|
IMAGE_SUBSYSTEM_WINDOWS_POSIX_CUI = 7,
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
|
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
|
||||||
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
|
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
|
||||||
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
|
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
|
||||||
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
|
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
|
||||||
IMAGE_SUBSYSTEM_EFI_ROM = 13,
|
IMAGE_SUBSYSTEM_EFI_ROM = 13,
|
||||||
IMAGE_SUBSYSTEM_XBOX = 14,
|
IMAGE_SUBSYSTEM_XBOX = 14,
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16,
|
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
// predefined resource types
|
// predefined resource types
|
||||||
enum {
|
enum {
|
||||||
RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, RT_DIALOG, RT_STRING,
|
RT_CURSOR = 1,
|
||||||
RT_FONTDIR, RT_FONT, RT_ACCELERATOR, RT_RCDATA, RT_MESSAGETABLE,
|
RT_BITMAP,
|
||||||
RT_GROUP_CURSOR, RT_GROUP_ICON = 14, RT_VERSION = 16, RT_DLGINCLUDE,
|
RT_ICON,
|
||||||
RT_PLUGPLAY = 19, RT_VXD, RT_ANICURSOR, RT_ANIICON, RT_HTML,
|
RT_MENU,
|
||||||
RT_MANIFEST, RT_LAST
|
RT_DIALOG,
|
||||||
|
RT_STRING,
|
||||||
|
RT_FONTDIR,
|
||||||
|
RT_FONT,
|
||||||
|
RT_ACCELERATOR,
|
||||||
|
RT_RCDATA,
|
||||||
|
RT_MESSAGETABLE,
|
||||||
|
RT_GROUP_CURSOR,
|
||||||
|
RT_GROUP_ICON = 14,
|
||||||
|
RT_VERSION = 16,
|
||||||
|
RT_DLGINCLUDE,
|
||||||
|
RT_PLUGPLAY = 19,
|
||||||
|
RT_VXD,
|
||||||
|
RT_ANICURSOR,
|
||||||
|
RT_ANIICON,
|
||||||
|
RT_HTML,
|
||||||
|
RT_MANIFEST,
|
||||||
|
RT_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
class Interval : private noncopyable
|
class Interval : private noncopyable {
|
||||||
{
|
|
||||||
unsigned capacity;
|
unsigned capacity;
|
||||||
void *base;
|
void *base;
|
||||||
public:
|
public:
|
||||||
struct interval
|
struct interval {
|
||||||
{
|
|
||||||
unsigned start, len;
|
unsigned start, len;
|
||||||
} *ivarr;
|
} *ivarr;
|
||||||
|
|
||||||
@ -324,9 +328,9 @@ protected:
|
|||||||
Interval(void *b);
|
Interval(void *b);
|
||||||
~Interval();
|
~Interval();
|
||||||
|
|
||||||
void add(unsigned start,unsigned len);
|
void add(unsigned start, unsigned len);
|
||||||
void add(const void *start,unsigned len);
|
void add(const void *start, unsigned len);
|
||||||
void add(const void *start,const void *end);
|
void add(const void *start, const void *end);
|
||||||
void add(const Interval *iv);
|
void add(const Interval *iv);
|
||||||
void flatten();
|
void flatten();
|
||||||
|
|
||||||
@ -334,11 +338,10 @@ protected:
|
|||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int __acc_cdecl_qsort compare(const void *p1,const void *p2);
|
static int __acc_cdecl_qsort compare(const void *p1, const void *p2);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Reloc : private noncopyable
|
class Reloc : private noncopyable {
|
||||||
{
|
|
||||||
upx_byte *start;
|
upx_byte *start;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
|
||||||
@ -350,18 +353,17 @@ protected:
|
|||||||
unsigned counts[16];
|
unsigned counts[16];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Reloc(upx_byte *,unsigned);
|
Reloc(upx_byte *, unsigned);
|
||||||
Reloc(unsigned rnum);
|
Reloc(unsigned rnum);
|
||||||
//
|
//
|
||||||
bool next(unsigned &pos,unsigned &type);
|
bool next(unsigned &pos, unsigned &type);
|
||||||
const unsigned *getcounts() const { return counts; }
|
const unsigned *getcounts() const { return counts; }
|
||||||
//
|
//
|
||||||
void add(unsigned pos,unsigned type);
|
void add(unsigned pos, unsigned type);
|
||||||
void finish(upx_byte* &p,unsigned &size);
|
void finish(upx_byte *&p, unsigned &size);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Resource : private noncopyable
|
class Resource : private noncopyable {
|
||||||
{
|
|
||||||
struct res_dir_entry;
|
struct res_dir_entry;
|
||||||
struct res_dir;
|
struct res_dir;
|
||||||
struct res_data;
|
struct res_data;
|
||||||
@ -371,29 +373,28 @@ protected:
|
|||||||
|
|
||||||
MemBuffer mb_start;
|
MemBuffer mb_start;
|
||||||
const upx_byte *start;
|
const upx_byte *start;
|
||||||
upx_byte *newstart;
|
upx_byte *newstart;
|
||||||
upx_rnode *root;
|
upx_rnode *root;
|
||||||
upx_rleaf *head;
|
upx_rleaf *head;
|
||||||
upx_rleaf *current;
|
upx_rleaf *current;
|
||||||
unsigned dsize;
|
unsigned dsize;
|
||||||
unsigned ssize;
|
unsigned ssize;
|
||||||
|
|
||||||
const upx_byte *ibufstart;
|
const upx_byte *ibufstart;
|
||||||
const upx_byte *ibufend;
|
const upx_byte *ibufend;
|
||||||
|
|
||||||
void check(const res_dir*,unsigned);
|
void check(const res_dir *, unsigned);
|
||||||
upx_rnode *convert(const void *,upx_rnode *,unsigned);
|
upx_rnode *convert(const void *, upx_rnode *, unsigned);
|
||||||
void build(const upx_rnode *,unsigned &,unsigned &,unsigned);
|
void build(const upx_rnode *, unsigned &, unsigned &, unsigned);
|
||||||
void clear(upx_byte *,unsigned,Interval *);
|
void clear(upx_byte *, unsigned, Interval *);
|
||||||
void dump(const upx_rnode *,unsigned) const;
|
void dump(const upx_rnode *, unsigned) const;
|
||||||
void destroy(upx_rnode *urd,unsigned level);
|
void destroy(upx_rnode *urd, unsigned level);
|
||||||
|
|
||||||
void ibufcheck(const void *m, unsigned size);
|
void ibufcheck(const void *m, unsigned size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Resource(const upx_byte *ibufstart, const upx_byte *ibufen);
|
Resource(const upx_byte *ibufstart, const upx_byte *ibufen);
|
||||||
Resource(const upx_byte *p, const upx_byte *ibufstart,
|
Resource(const upx_byte *p, const upx_byte *ibufstart, const upx_byte *ibufend);
|
||||||
const upx_byte *ibufend);
|
|
||||||
~Resource();
|
~Resource();
|
||||||
void init(const upx_byte *);
|
void init(const upx_byte *);
|
||||||
|
|
||||||
@ -418,26 +419,25 @@ protected:
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
class Export : private noncopyable
|
class Export : private noncopyable {
|
||||||
{
|
|
||||||
struct alignas(1) export_dir_t {
|
struct alignas(1) export_dir_t {
|
||||||
char _[12]; // flags, timedate, version
|
char _[12]; // flags, timedate, version
|
||||||
LE32 name;
|
LE32 name;
|
||||||
char __[4]; // ordinal base
|
char __[4]; // ordinal base
|
||||||
LE32 functions;
|
LE32 functions;
|
||||||
LE32 names;
|
LE32 names;
|
||||||
LE32 addrtable;
|
LE32 addrtable;
|
||||||
LE32 nameptrtable;
|
LE32 nameptrtable;
|
||||||
LE32 ordinaltable;
|
LE32 ordinaltable;
|
||||||
};
|
};
|
||||||
|
|
||||||
export_dir_t edir;
|
export_dir_t edir;
|
||||||
char *ename;
|
char *ename;
|
||||||
char *functionptrs;
|
char *functionptrs;
|
||||||
char *ordinals;
|
char *ordinals;
|
||||||
char **names;
|
char **names;
|
||||||
|
|
||||||
char *base;
|
char *base;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
Interval iv;
|
Interval iv;
|
||||||
|
|
||||||
@ -445,21 +445,19 @@ protected:
|
|||||||
Export(char *_base);
|
Export(char *_base);
|
||||||
~Export();
|
~Export();
|
||||||
|
|
||||||
void convert(unsigned eoffs,unsigned esize);
|
void convert(unsigned eoffs, unsigned esize);
|
||||||
void build(char *base,unsigned newoffs);
|
void build(char *base, unsigned newoffs);
|
||||||
unsigned getsize() const { return size; }
|
unsigned getsize() const { return size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PeFile32 : public PeFile
|
class PeFile32 : public PeFile {
|
||||||
{
|
|
||||||
typedef PeFile super;
|
typedef PeFile super;
|
||||||
protected:
|
protected:
|
||||||
PeFile32(InputFile *f);
|
PeFile32(InputFile *f);
|
||||||
virtual ~PeFile32();
|
virtual ~PeFile32();
|
||||||
void pack0(OutputFile *fo, unsigned subsystem_mask,
|
void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase,
|
||||||
upx_uint64_t default_imagebase, bool last_section_rsrc_only);
|
bool last_section_rsrc_only);
|
||||||
virtual void unpack(OutputFile *fo) override;
|
virtual void unpack(OutputFile *fo) override;
|
||||||
virtual int canUnpack() override;
|
virtual int canUnpack() override;
|
||||||
|
|
||||||
@ -472,39 +470,39 @@ protected:
|
|||||||
|
|
||||||
struct alignas(1) pe_header_t {
|
struct alignas(1) pe_header_t {
|
||||||
// 0x0
|
// 0x0
|
||||||
char _[4]; // pemagic
|
char _[4]; // pemagic
|
||||||
LE16 cpu;
|
LE16 cpu;
|
||||||
LE16 objects;
|
LE16 objects;
|
||||||
char __[12]; // timestamp + reserved
|
char __[12]; // timestamp + reserved
|
||||||
LE16 opthdrsize;
|
LE16 opthdrsize;
|
||||||
LE16 flags;
|
LE16 flags;
|
||||||
// optional header
|
// optional header
|
||||||
LE16 coffmagic; // NEW: Stefan Widmann
|
LE16 coffmagic; // NEW: Stefan Widmann
|
||||||
char ___[2]; // linkerversion
|
char ___[2]; // linkerversion
|
||||||
LE32 codesize;
|
LE32 codesize;
|
||||||
// 0x20
|
// 0x20
|
||||||
LE32 datasize;
|
LE32 datasize;
|
||||||
LE32 bsssize;
|
LE32 bsssize;
|
||||||
LE32 entry;
|
LE32 entry;
|
||||||
LE32 codebase;
|
LE32 codebase;
|
||||||
// 0x30
|
// 0x30
|
||||||
LE32 database;
|
LE32 database;
|
||||||
// nt specific fields
|
// nt specific fields
|
||||||
LE32 imagebase;
|
LE32 imagebase;
|
||||||
LE32 objectalign;
|
LE32 objectalign;
|
||||||
LE32 filealign; // should set to 0x200 ?
|
LE32 filealign; // should set to 0x200 ?
|
||||||
// 0x40
|
// 0x40
|
||||||
char ____[16]; // versions
|
char ____[16]; // versions
|
||||||
// 0x50
|
// 0x50
|
||||||
LE32 imagesize;
|
LE32 imagesize;
|
||||||
LE32 headersize;
|
LE32 headersize;
|
||||||
LE32 chksum; // should set to 0
|
LE32 chksum; // should set to 0
|
||||||
LE16 subsystem;
|
LE16 subsystem;
|
||||||
LE16 dllflags;
|
LE16 dllflags;
|
||||||
// 0x60
|
// 0x60
|
||||||
char _____[20]; // stack + heap sizes
|
char _____[20]; // stack + heap sizes
|
||||||
// 0x74
|
// 0x74
|
||||||
LE32 ddirsentries; // usually 16
|
LE32 ddirsentries; // usually 16
|
||||||
|
|
||||||
ddirs_t ddirs[16];
|
ddirs_t ddirs[16];
|
||||||
};
|
};
|
||||||
@ -512,15 +510,13 @@ protected:
|
|||||||
pe_header_t ih, oh;
|
pe_header_t ih, oh;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PeFile64 : public PeFile
|
class PeFile64 : public PeFile {
|
||||||
{
|
|
||||||
typedef PeFile super;
|
typedef PeFile super;
|
||||||
protected:
|
protected:
|
||||||
PeFile64(InputFile *f);
|
PeFile64(InputFile *f);
|
||||||
virtual ~PeFile64();
|
virtual ~PeFile64();
|
||||||
|
|
||||||
void pack0(OutputFile *fo, unsigned subsystem_mask,
|
void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase);
|
||||||
upx_uint64_t default_imagebase);
|
|
||||||
|
|
||||||
virtual void unpack(OutputFile *fo) override;
|
virtual void unpack(OutputFile *fo) override;
|
||||||
virtual int canUnpack() override;
|
virtual int canUnpack() override;
|
||||||
@ -534,39 +530,39 @@ protected:
|
|||||||
|
|
||||||
struct alignas(1) pe_header_t {
|
struct alignas(1) pe_header_t {
|
||||||
// 0x0
|
// 0x0
|
||||||
char _[4]; // pemagic
|
char _[4]; // pemagic
|
||||||
LE16 cpu;
|
LE16 cpu;
|
||||||
LE16 objects; // number of sections
|
LE16 objects; // number of sections
|
||||||
char __[12]; // timestamp + reserved
|
char __[12]; // timestamp + reserved
|
||||||
LE16 opthdrsize;
|
LE16 opthdrsize;
|
||||||
LE16 flags; // characteristics
|
LE16 flags; // characteristics
|
||||||
// optional header
|
// optional header
|
||||||
LE16 coffmagic; // NEW: Stefan Widmann
|
LE16 coffmagic; // NEW: Stefan Widmann
|
||||||
char ___[2]; // linkerversion
|
char ___[2]; // linkerversion
|
||||||
LE32 codesize;
|
LE32 codesize;
|
||||||
// 0x20
|
// 0x20
|
||||||
LE32 datasize;
|
LE32 datasize;
|
||||||
LE32 bsssize;
|
LE32 bsssize;
|
||||||
LE32 entry; // still a 32 bit RVA
|
LE32 entry; // still a 32 bit RVA
|
||||||
LE32 codebase;
|
LE32 codebase;
|
||||||
// 0x30
|
// 0x30
|
||||||
//LE32 database; // field does not exist in PE+!
|
// LE32 database; // field does not exist in PE+!
|
||||||
// nt specific fields
|
// nt specific fields
|
||||||
LE64 imagebase; // LE32 -> LE64 - Stefan Widmann standard is 0x0000000140000000
|
LE64 imagebase; // LE32 -> LE64 - Stefan Widmann standard is 0x0000000140000000
|
||||||
LE32 objectalign;
|
LE32 objectalign;
|
||||||
LE32 filealign; // should set to 0x200 ?
|
LE32 filealign; // should set to 0x200 ?
|
||||||
// 0x40
|
// 0x40
|
||||||
char ____[16]; // versions
|
char ____[16]; // versions
|
||||||
// 0x50
|
// 0x50
|
||||||
LE32 imagesize;
|
LE32 imagesize;
|
||||||
LE32 headersize;
|
LE32 headersize;
|
||||||
LE32 chksum; // should set to 0
|
LE32 chksum; // should set to 0
|
||||||
LE16 subsystem;
|
LE16 subsystem;
|
||||||
LE16 dllflags;
|
LE16 dllflags;
|
||||||
// 0x60
|
// 0x60
|
||||||
char _____[36]; // stack + heap sizes + loader flag
|
char _____[36]; // stack + heap sizes + loader flag
|
||||||
// 0x84
|
// 0x84
|
||||||
LE32 ddirsentries; // usually 16
|
LE32 ddirsentries; // usually 16
|
||||||
|
|
||||||
ddirs_t ddirs[16];
|
ddirs_t ddirs[16];
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user