diff --git a/src/Makefile b/src/Makefile index d0e1001f..3ec380fa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -81,7 +81,7 @@ ifeq ($(shell uname),Linux) # 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 += 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_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*)) CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)) diff --git a/src/p_w32pe.cpp b/src/p_w32pe.cpp index 4b7eb29d..e5dd5f70 100644 --- a/src/p_w32pe.cpp +++ b/src/p_w32pe.cpp @@ -25,7 +25,6 @@ */ - #include "conf.h" #include "file.h" #include "filter.h" @@ -34,55 +33,40 @@ #include "p_w32pe.h" #include "linker.h" -static const +static const CLANG_FORMAT_DUMMY_STATEMENT #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); } - -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 }; +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}; return filters; } - -Linker* PackW32Pe::newLinker() const -{ - return new ElfLinkerX86; -} - +Linker *PackW32Pe::newLinker() const { return new ElfLinkerX86; } /************************************************************************* // util **************************************************************************/ -int PackW32Pe::readFileHeader() -{ +int PackW32Pe::readFileHeader() { if (fi->st_size() >= 0x206) { char buf[6]; fi->seek(0x200, SEEK_SET); fi->readx(buf, 6); - isrtm = memcmp(buf, "32STUB" ,6) == 0; + isrtm = memcmp(buf, "32STUB", 6) == 0; } return super::readFileHeader(); } @@ -91,118 +75,89 @@ int PackW32Pe::readFileHeader() // pack **************************************************************************/ -bool PackW32Pe::canPack() -{ +bool PackW32Pe::canPack() { if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150) return false; return true; } - -void PackW32Pe::buildLoader(const Filter *ft) -{ +void PackW32Pe::buildLoader(const Filter *ft) { // recompute tlsindex (see pack() below) unsigned tmp_tlsindex = tlsindex; const unsigned oam1 = ih.objectalign - 1; - const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; - if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4) + const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) & ~oam1; + if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) & ~oam1) > tlsindex + 4) tmp_tlsindex = 0; // prepare loader initLoader(stub_i386_win32_pe, sizeof(stub_i386_win32_pe), 2); if (isdll) addLoader("PEISDLL1"); - addLoader("PEMAIN01", - use_stub_relocs ? "PESOCREL" : "PESOCPIC", - "PESOUNC0", + addLoader("PEMAIN01", use_stub_relocs ? "PESOCREL" : "PESOCPIC", "PESOUNC0", icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "", - tmp_tlsindex ? "PETLSHAK" : "", - "PEMAIN02", - ph.first_offset_found == 1 ? "PEMAIN03" : "", - getDecompressorSections(), - //multipass ? "PEMULTIP" : "", - "PEMAIN10", - nullptr - ); + tmp_tlsindex ? "PETLSHAK" : "", "PEMAIN02", + ph.first_offset_found == 1 ? "PEMAIN03" : "", getDecompressorSections(), + // multipass ? "PEMULTIP" : "", + "PEMAIN10", nullptr); addLoader(tmp_tlsindex ? "PETLSHAK2" : ""); - if (ft->id) - { + if (ft->id) { const unsigned texv = ih.codebase - rvamin; assert(ft->calls > 0); - addLoader(texv ? "PECTTPOS" : "PECTTNUL",nullptr); + addLoader(texv ? "PECTTPOS" : "PECTTNUL", nullptr); addFilter32(ft->id); } if (soimport) - addLoader("PEIMPORT", - importbyordinal ? "PEIBYORD" : "", - kernel32ordinal ? "PEK32ORD" : "", - importbyordinal ? "PEIMORD1" : "", - "PEIMPOR2", - isdll ? "PEIERDLL" : "PEIEREXE", - "PEIMDONE", - nullptr - ); - if (sorelocs) - { + addLoader("PEIMPORT", importbyordinal ? "PEIBYORD" : "", kernel32ordinal ? "PEK32ORD" : "", + importbyordinal ? "PEIMORD1" : "", "PEIMPOR2", isdll ? "PEIERDLL" : "PEIEREXE", + "PEIMDONE", nullptr); + if (sorelocs) { addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2", - "PERELOC3,RELOC320", - big_relocs ? "REL32BIG" : "", - "RELOC32J", - 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 - ); + "PERELOC3,RELOC320", big_relocs ? "REL32BIG" : "", "RELOC32J", 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) addLoader("PEDEPHAK", nullptr); - //NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann - if(use_tls_callbacks) + // NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann + if (use_tls_callbacks) addLoader("PETLSC", nullptr); addLoader("PEMAIN20", nullptr); if (use_clear_dirty_stack) addLoader("CLEARSTACK", 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); - //NEW: TLS callback support PART 2, the callback handler - Stefan Widmann - if(use_tls_callbacks) + // NEW: TLS callback support PART 2, the callback handler - Stefan Widmann + if (use_tls_callbacks) addLoader("PETLSC2", nullptr); addLoader("IDENTSTR,UPX1HEAD", nullptr); - } -bool PackW32Pe::handleForceOption() -{ - return (ih.cpu < 0x14c || ih.cpu > 0x150) - || (ih.opthdrsize != 0xe0) - || ((ih.flags & EXECUTABLE) == 0) - || ((ih.flags & BITS_32_MACHINE) == 0) //NEW: 32 bit machine flag must be set - Stefan Widmann - || (ih.coffmagic != 0x10B) //COFF magic is 0x10B in PE files, 0x20B in PE32+ files - Stefan Widmann - || (ih.entry == 0 && !isdll) - || (ih.ddirsentries != 16) - || IDSIZE(PEDIR_EXCEPTION) // is this used on i386? -// || IDSIZE(PEDIR_COPYRIGHT) +bool PackW32Pe::handleForceOption() { + return (ih.cpu < 0x14c || ih.cpu > 0x150) || (ih.opthdrsize != 0xe0) || + ((ih.flags & EXECUTABLE) == 0) || + ((ih.flags & BITS_32_MACHINE) == + 0) // NEW: 32 bit machine flag must be set - Stefan Widmann + || (ih.coffmagic != + 0x10B) // COFF magic is 0x10B in PE files, 0x20B in PE32+ files - Stefan Widmann + || (ih.entry == 0 && !isdll) || (ih.ddirsentries != 16) || + IDSIZE(PEDIR_EXCEPTION) // is this used on i386? + // || IDSIZE(PEDIR_COPYRIGHT) ; } -void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection, - unsigned sizeof_oh, unsigned ic, - unsigned s1addr) -{ +void PackW32Pe::defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh, + unsigned ic, unsigned s1addr) { const unsigned myimport = ncsection + soresources - rvamin; // patch loader linker->defineSymbol("original_entry", ih.entry); - if (use_dep_hack) - { + if (use_dep_hack) { // This works around a "protection" introduced in MSVCRT80, which // works like this: // 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; // make sure we only touch the minimum number of pages 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 // are on the same page - linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ? - 0x2000 : 0x1000); // 2 pages or 1 page - linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask - linker->defineSymbol("VirtualProtect", 0u-rvamin + - ilinkerGetAddress("kernel32.dll", "VirtualProtect")); + linker->defineSymbol( + "vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ? 0x2000 : 0x1000); // 2 pages or 1 page + linker->defineSymbol("vp_base", addr & ~0xfff); // page mask + linker->defineSymbol("VirtualProtect", + 0u - rvamin + ilinkerGetAddress("kernel32.dll", "VirtualProtect")); } linker->defineSymbol("reloc_delt", 0u - (unsigned) ih.imagebase - rvamin); linker->defineSymbol("start_of_relocs", crelocs); if (ilinker) { if (!isdll) - linker->defineSymbol("ExitProcess", 0u-rvamin + - ilinkerGetAddress("kernel32.dll", "ExitProcess")); - linker->defineSymbol("GetProcAddress", 0u-rvamin + - ilinkerGetAddress("kernel32.dll", "GetProcAddress")); + linker->defineSymbol("ExitProcess", + 0u - rvamin + ilinkerGetAddress("kernel32.dll", "ExitProcess")); + linker->defineSymbol("GetProcAddress", + 0u - rvamin + ilinkerGetAddress("kernel32.dll", "GetProcAddress")); linker->defineSymbol("kernel32_ordinals", myimport); - linker->defineSymbol("LoadLibraryA", 0u-rvamin + - ilinkerGetAddress("kernel32.dll", "LoadLibraryA")); + linker->defineSymbol("LoadLibraryA", + 0u - rvamin + ilinkerGetAddress("kernel32.dll", "LoadLibraryA")); linker->defineSymbol("start_of_imports", myimport); 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, // because windoze zeroes the word pointed by tlsindex before // it starts programs - linker->defineSymbol("tls_value", (tlsindex + 4 > s1addr) ? - get_le32(obuf + tlsindex - s1addr - ic) : 0); + linker->defineSymbol("tls_value", + (tlsindex + 4 > s1addr) ? get_le32(obuf + tlsindex - s1addr - ic) : 0); linker->defineSymbol("tls_address", tlsindex - rvamin); 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_compressed", use_stub_relocs ? esi0 + ih.imagebase : esi0); - if (use_tls_callbacks) - { - //esi is ih.imagebase + rvamin + if (use_tls_callbacks) { + // esi is ih.imagebase + rvamin linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr); linker->defineSymbol("tls_module_base", 0u - rvamin); } 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) rel.add(base + linker->getSymbolOffset("PESOCREL") + 1, 3); } -void PackW32Pe::setOhDataBase(const pe_section_t *osection) -{ - oh.database = osection[2].vaddr; -} +void PackW32Pe::setOhDataBase(const pe_section_t *osection) { 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); } -void PackW32Pe::pack(OutputFile *fo) -{ - super::pack0(fo - , (1u< tlsindex + 4) + const unsigned newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) & ~oam1; + if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) & ~oam1) > tlsindex + 4) tmp_tlsindex = 0; // prepare loader @@ -105,61 +87,41 @@ void PackW64Pep::buildLoader(const Filter *ft) addLoader("PEISDLL0"); if (isefi) addLoader("PEISEFI0"); - addLoader(isdll ? "PEISDLL1" : "", - "PEMAIN01", + addLoader(isdll ? "PEISDLL1" : "", "PEMAIN01", icondir_count > 1 ? (icondir_count == 2 ? "PEICONS1" : "PEICONS2") : "", - tmp_tlsindex ? "PETLSHAK" : "", - "PEMAIN02", - //ph.first_offset_found == 1 ? "PEMAIN03" : "", - M_IS_LZMA(ph.method) ? "LZMA_HEAD,LZMA_ELF00,LZMA_DEC20,LZMA_TAIL" : - M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B" : - M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D" : - M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E" : "UNKNOWN_COMPRESSION_METHOD", - //getDecompressorSections(), - /*multipass ? "PEMULTIP" : */ "", - "PEMAIN10", - nullptr - ); + tmp_tlsindex ? "PETLSHAK" : "", "PEMAIN02", + // ph.first_offset_found == 1 ? "PEMAIN03" : "", + M_IS_LZMA(ph.method) ? "LZMA_HEAD,LZMA_ELF00,LZMA_DEC20,LZMA_TAIL" + : M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B" + : M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D" + : M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E" + : "UNKNOWN_COMPRESSION_METHOD", + // getDecompressorSections(), + /*multipass ? "PEMULTIP" : */ "", "PEMAIN10", nullptr); addLoader(tmp_tlsindex ? "PETLSHAK2" : ""); - if (ft->id) - { + if (ft->id) { const unsigned texv = ih.codebase - rvamin; assert(ft->calls > 0); - addLoader(texv ? "PECTTPOS" : "PECTTNUL",nullptr); + addLoader(texv ? "PECTTPOS" : "PECTTNUL", nullptr); addLoader("PEFILTER49"); } if (soimport) - addLoader("PEIMPORT", - importbyordinal ? "PEIBYORD" : "", - kernel32ordinal ? "PEK32ORD" : "", - importbyordinal ? "PEIMORD1" : "", - "PEIMPOR2", - isdll ? "PEIERDLL" : "PEIEREXE", - "PEIMDONE", - nullptr - ); - if (sorelocs) - { + addLoader("PEIMPORT", importbyordinal ? "PEIBYORD" : "", kernel32ordinal ? "PEK32ORD" : "", + importbyordinal ? "PEIMORD1" : "", "PEIMPOR2", isdll ? "PEIERDLL" : "PEIEREXE", + "PEIMDONE", nullptr); + if (sorelocs) { addLoader(soimport == 0 || soimport + cimports != crelocs ? "PERELOC1" : "PERELOC2", - "PERELOC3", - big_relocs ? "REL64BIG" : "", - "RELOC64J", - nullptr - ); - if __acc_cte(0) - { - addLoader(big_relocs&6 ? "PERLOHI0" : "", - big_relocs&4 ? "PERELLO0" : "", - big_relocs&2 ? "PERELHI0" : "", - nullptr - ); + "PERELOC3", big_relocs ? "REL64BIG" : "", "RELOC64J", nullptr); + if __acc_cte (0) { + addLoader(big_relocs & 6 ? "PERLOHI0" : "", big_relocs & 4 ? "PERELLO0" : "", + big_relocs & 2 ? "PERELHI0" : "", nullptr); } } if (use_dep_hack) addLoader("PEDEPHAK", nullptr); - //NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann - if(use_tls_callbacks) + // NEW: TLS callback support PART 1, the callback handler installation - Stefan Widmann + if (use_tls_callbacks) addLoader("PETLSC", nullptr); addLoader("PEMAIN20", nullptr); @@ -173,35 +135,32 @@ void PackW64Pep::buildLoader(const Filter *ft) addLoader("PEISEFI9"); addLoader(ih.entry || !ilinker ? "PEDOJUMP" : "PERETURN", nullptr); - //NEW: TLS callback support PART 2, the callback handler - Stefan Widmann - if(use_tls_callbacks) + // NEW: TLS callback support PART 2, the callback handler - Stefan Widmann + if (use_tls_callbacks) addLoader("PETLSC2", nullptr); addLoader("IDENTSTR,UPX1HEAD", nullptr); } -bool PackW64Pep::handleForceOption() -{ - return (ih.cpu != 0x8664) //CPU magic of AMD64 is 0x8664 - || (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.flags & EXECUTABLE) == 0) - || ((ih.flags & BITS_32_MACHINE) != 0) //NEW: 32 bit machine flag may not be set - Stefan Widmann - || (ih.entry == 0 && !isdll) - || (ih.ddirsentries != 16) - ; +bool PackW64Pep::handleForceOption() { + return (ih.cpu != 0x8664) // CPU magic of AMD64 is 0x8664 + || + (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.flags & EXECUTABLE) == 0) || + ((ih.flags & BITS_32_MACHINE) != + 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, - unsigned sizeof_oh, unsigned ic, - unsigned s1addr) -{ +void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh, + unsigned ic, unsigned s1addr) { const unsigned myimport = ncsection + soresources - rvamin; // patch loader linker->defineSymbol("original_entry", ih.entry); - if (use_dep_hack) - { + if (use_dep_hack) { // This works around a "protection" introduced in MSVCRT80, which // works like this: // 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; // make sure we only touch the minimum number of pages 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 // are on the same page - linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ? - 0x2000 : 0x1000); // 2 pages or 1 page - linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask - linker->defineSymbol("VirtualProtect", - ilinkerGetAddress("kernel32.dll", "VirtualProtect")); + linker->defineSymbol( + "vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ? 0x2000 : 0x1000); // 2 pages or 1 page + linker->defineSymbol("vp_base", addr & ~0xfff); // page mask + linker->defineSymbol("VirtualProtect", ilinkerGetAddress("kernel32.dll", "VirtualProtect")); } linker->defineSymbol("start_of_relocs", crelocs); if (ilinker) { if (!isdll) - linker->defineSymbol("ExitProcess", - ilinkerGetAddress("kernel32.dll", "ExitProcess")); - linker->defineSymbol("GetProcAddress", - ilinkerGetAddress("kernel32.dll", "GetProcAddress")); + linker->defineSymbol("ExitProcess", ilinkerGetAddress("kernel32.dll", "ExitProcess")); + linker->defineSymbol("GetProcAddress", ilinkerGetAddress("kernel32.dll", "GetProcAddress")); linker->defineSymbol("kernel32_ordinals", myimport); - linker->defineSymbol("LoadLibraryA", - ilinkerGetAddress("kernel32.dll", "LoadLibraryA")); + linker->defineSymbol("LoadLibraryA", ilinkerGetAddress("kernel32.dll", "LoadLibraryA")); linker->defineSymbol("start_of_imports", myimport); 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_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, // because windoze zeroes the word pointed by tlsindex before // it starts programs - linker->defineSymbol("tls_value", (tlsindex + 4 > s1addr) ? - get_le32(obuf + tlsindex - s1addr - ic) : 0); + linker->defineSymbol("tls_value", + (tlsindex + 4 > s1addr) ? get_le32(obuf + tlsindex - s1addr - ic) : 0); linker->defineSymbol("tls_address", tlsindex - rvamin); 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_compressed", esi0); - if (use_tls_callbacks) - { + if (use_tls_callbacks) { linker->defineSymbol("tls_callbacks_ptr", tlscb_ptr - ih.imagebase); linker->defineSymbol("tls_module_base", 0u - rvamin); } @@ -275,21 +228,17 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned 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); } -void PackW64Pep::pack(OutputFile *fo) -{ - super::pack0(fo - , (1u< */ - #include "conf.h" #include "file.h" #include "filter.h" @@ -33,38 +32,38 @@ #include "pefile.h" #include "linker.h" -#define FILLVAL 0 +#define FILLVAL 0 /************************************************************************* // **************************************************************************/ #if (WITH_XSPAN >= 2) && 1 -//#define IPTR(type, var) Span var(ibuf, ibuf.getSize(), ibuf) -//#define OPTR(type, var) Span var(obuf, obuf.getSize(), obuf) -#define IPTR_I_D(type, var, disp) Span var(ibuf + (disp), ibuf.getSize() - (disp), ibuf + (disp)) -#define IPTR_I(type, var, first) Span var(first, ibuf) -#define OPTR_I(type, var, first) Span var(first, obuf) -#define IPTR_C(type, var, first) const Span var(first, ibuf) -#define OPTR_C(type, var, first) const Span var(first, obuf) +// #define IPTR(type, var) Span var(ibuf, ibuf.getSize(), ibuf) +// #define OPTR(type, var) Span var(obuf, obuf.getSize(), obuf) +#define IPTR_I_D(type, var, disp) \ + Span var(ibuf + (disp), ibuf.getSize() - (disp), ibuf + (disp)) +#define IPTR_I(type, var, first) Span var(first, ibuf) +#define OPTR_I(type, var, first) Span var(first, obuf) +#define IPTR_C(type, var, first) const Span var(first, ibuf) +#define OPTR_C(type, var, first) const Span var(first, obuf) #else #include "util/bptr.h" -//#define IPTR(type, var) BoundedPtr var(ibuf, ibuf.getSize()) -//#define OPTR(type, var) BoundedPtr var(obuf, obuf.getSize()) -#define IPTR_I_D(type, var, disp) BoundedPtr var(ibuf + (disp), ibuf.getSize() - (disp), ibuf + (disp)) -#define IPTR_I(type, var, first) BoundedPtr var(ibuf, ibuf.getSize(), first) -#define OPTR_I(type, var, first) BoundedPtr var(obuf, obuf.getSize(), first) -#define IPTR_C(type, var, first) const BoundedPtr var(ibuf, ibuf.getSize(), first) -#define OPTR_C(type, var, first) const BoundedPtr var(obuf, obuf.getSize(), first) +// #define IPTR(type, var) BoundedPtr var(ibuf, ibuf.getSize()) +// #define OPTR(type, var) BoundedPtr var(obuf, obuf.getSize()) +#define IPTR_I_D(type, var, disp) \ + BoundedPtr var(ibuf + (disp), ibuf.getSize() - (disp), ibuf + (disp)) +#define IPTR_I(type, var, first) BoundedPtr var(ibuf, ibuf.getSize(), first) +#define OPTR_I(type, var, first) BoundedPtr var(obuf, obuf.getSize(), first) +#define IPTR_C(type, var, first) const BoundedPtr var(ibuf, ibuf.getSize(), first) +#define OPTR_C(type, var, first) const BoundedPtr var(obuf, obuf.getSize(), first) #endif -static void xcheck(const void *p) -{ +static void xcheck(const void *p) { if (!p) throwCantUnpack("xcheck unexpected nullptr pointer; take care!"); } -static void xcheck(const void *p, size_t plen, const void *b, size_t blen) -{ +static void xcheck(const void *p, size_t plen, const void *b, size_t blen) { const char *pp = (const char *) p; const char *bb = (const char *) b; if (pp < bb || pp > bb + blen || pp + plen > bb + blen) @@ -78,22 +77,20 @@ static void xcheck(size_t poff, size_t plen, const void *b, size_t blen) throwCantUnpack("xcheck pointer out of range; take care!"); } #endif -#define ICHECK(x, size) xcheck(raw_bytes(x, 0), size, ibuf, ibuf.getSize()) -#define OCHECK(x, size) xcheck(raw_bytes(x, 0), size, obuf, obuf.getSize()) - -//#define imemset(a,b,c) ICHECK(a,c), memset(a,b,c) -//#define omemset(a,b,c) OCHECK(a,c), memset(a,b,c) -//#define imemcpy(a,b,c) ICHECK(a,c), memcpy(a,b,c) -#define omemcpy(a,b,c) OCHECK(a,c), memcpy(a,b,c) -#define omemmove(a,b,c) OCHECK(a,c), memmove(a,b,c) +#define ICHECK(x, size) xcheck(raw_bytes(x, 0), size, ibuf, ibuf.getSize()) +#define OCHECK(x, size) xcheck(raw_bytes(x, 0), size, obuf, obuf.getSize()) +// #define imemset(a,b,c) ICHECK(a,c), memset(a,b,c) +// #define omemset(a,b,c) OCHECK(a,c), memset(a,b,c) +// #define imemcpy(a,b,c) ICHECK(a,c), memcpy(a,b,c) +#define omemcpy(a, b, c) OCHECK(a, c), memcpy(a, b, c) +#define omemmove(a, b, c) OCHECK(a, c), memmove(a, b, c) /************************************************************************* // **************************************************************************/ -PeFile::PeFile(InputFile *f) : super(f) -{ +PeFile::PeFile(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; COMPILE_TIME_ASSERT(sizeof(ddirs_t) == 8) COMPILE_TIME_ASSERT(sizeof(pe_section_t) == 40) @@ -131,9 +128,7 @@ PeFile::PeFile(InputFile *f) : super(f) isefi = false; } - -bool PeFile::testUnpackVersion(int version) const -{ +bool PeFile::testUnpackVersion(int version) const { if (version != ph_version && ph_version != -1) throwCantUnpack("program has been modified; run a virus checker!"); if (!canUnpackVersion(version)) @@ -141,13 +136,11 @@ bool PeFile::testUnpackVersion(int version) const return true; } - /************************************************************************* // util **************************************************************************/ -int PeFile::readFileHeader() -{ +int PeFile::readFileHeader() { struct alignas(1) exe_header_t { LE16 mz; LE16 m512; @@ -160,167 +153,147 @@ int PeFile::readFileHeader() COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 64) COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t) - COMPILE_TIME_ASSERT(sizeof(((exe_header_t*)nullptr)->_) == 18) - COMPILE_TIME_ASSERT(sizeof(((exe_header_t*)nullptr)->__) == 34) + COMPILE_TIME_ASSERT(sizeof(((exe_header_t *) nullptr)->_) == 18) + COMPILE_TIME_ASSERT(sizeof(((exe_header_t *) nullptr)->__) == 34) exe_header_t h; int ic; pe_offset = 0; - for (ic = 0; ic < 20; ic++) - { - fi->seek(pe_offset,SEEK_SET); - fi->readx(&h,sizeof(h)); + for (ic = 0; ic < 20; ic++) { + fi->seek(pe_offset, SEEK_SET); + fi->readx(&h, sizeof(h)); - if (h.mz == 'M' + 'Z'*256) // dos exe + if (h.mz == 'M' + 'Z' * 256) // dos exe { if (h.nexepos && h.nexepos < sizeof(exe_header_t)) { // Overlapping MZ and PE headers by 'leanify', etc. - char buf[64]; snprintf(buf, sizeof(buf), - "PE and MZ header overlap: %#x < %#x", - (unsigned)h.nexepos, (unsigned)sizeof(exe_header_t)); + char buf[64]; + snprintf(buf, sizeof(buf), "PE and MZ header overlap: %#x < %#x", + (unsigned) h.nexepos, (unsigned) sizeof(exe_header_t)); throwCantPack(buf); } unsigned const delta = (h.relocoffs >= 0x40) - ? h.nexepos // new format exe - : (h.p512*512+h.m512 - h.m512 ? 512 : h.nexepos); + ? h.nexepos // new format exe + : (h.p512 * 512 + h.m512 - h.m512 ? 512 : h.nexepos); - if ((pe_offset + delta) < delta // wrap-around - || (pe_offset + delta) > (unsigned)file_size) { - char buf[64]; snprintf(buf, sizeof(buf), - "bad PE delta %#x at offset %#x", delta, pe_offset); + if ((pe_offset + delta) < delta // wrap-around + || (pe_offset + delta) > (unsigned) file_size) { + char buf[64]; + snprintf(buf, sizeof(buf), "bad PE delta %#x at offset %#x", delta, pe_offset); throwCantPack(buf); } pe_offset += delta; - } - else if (get_le32(&h) == 'P' + 'E'*256) + } else if (get_le32(&h) == 'P' + 'E' * 256) break; else return 0; } if (ic == 20) return 0; - fi->seek(pe_offset,SEEK_SET); + fi->seek(pe_offset, SEEK_SET); readPeHeader(); return getFormat(); } - /************************************************************************* // interval handling **************************************************************************/ -PeFile::Interval::Interval(void *b) : capacity(0),base(b),ivarr(nullptr),ivnum(0) -{} +PeFile::Interval::Interval(void *b) : capacity(0), base(b), ivarr(nullptr), ivnum(0) {} -PeFile::Interval::~Interval() -{ - free(ivarr); +PeFile::Interval::~Interval() { free(ivarr); } + +void PeFile::Interval::add(const void *start, unsigned len) { + add(ptr_diff_bytes(start, base), len); } -void PeFile::Interval::add(const void *start,unsigned len) -{ - add(ptr_diff_bytes(start,base),len); +void PeFile::Interval::add(const void *start, const void *end) { + add(ptr_diff_bytes(start, base), ptr_diff_bytes(end, start)); } -void PeFile::Interval::add(const void *start,const void *end) -{ - add(ptr_diff_bytes(start,base),ptr_diff_bytes(end,start)); -} - -int __acc_cdecl_qsort PeFile::Interval::compare(const void *p1,const void *p2) -{ - const interval *i1 = (const interval*) p1; - const interval *i2 = (const interval*) p2; - if (i1->start < i2->start) return -1; - if (i1->start > i2->start) return 1; - if (i1->len < i2->len) return 1; - if (i1->len > i2->len) return -1; +int __acc_cdecl_qsort PeFile::Interval::compare(const void *p1, const void *p2) { + const interval *i1 = (const interval *) p1; + const interval *i2 = (const interval *) p2; + if (i1->start < i2->start) + return -1; + if (i1->start > i2->start) + return 1; + if (i1->len < i2->len) + return 1; + if (i1->len > i2->len) + return -1; return 0; } -void PeFile::Interval::add(unsigned start,unsigned len) -{ +void PeFile::Interval::add(unsigned start, unsigned len) { if (ivnum == capacity) - ivarr = (interval*) realloc(ivarr,(capacity += 15) * sizeof (interval)); + ivarr = (interval *) realloc(ivarr, (capacity += 15) * sizeof(interval)); ivarr[ivnum].start = start; ivarr[ivnum++].len = len; } -void PeFile::Interval::add(const Interval *iv) -{ +void PeFile::Interval::add(const Interval *iv) { for (unsigned ic = 0; ic < iv->ivnum; ic++) - add(iv->ivarr[ic].start,iv->ivarr[ic].len); + add(iv->ivarr[ic].start, iv->ivarr[ic].len); } -void PeFile::Interval::flatten() -{ +void PeFile::Interval::flatten() { if (!ivnum) return; - qsort(ivarr,ivnum,sizeof (interval),Interval::compare); - for (unsigned ic = 0; ic < ivnum - 1; ic++) - { + qsort(ivarr, ivnum, sizeof(interval), Interval::compare); + for (unsigned ic = 0; ic < ivnum - 1; ic++) { unsigned jc; for (jc = ic + 1; jc < ivnum && ivarr[ic].start + ivarr[ic].len >= ivarr[jc].start; jc++) if (ivarr[ic].start + ivarr[ic].len < ivarr[jc].start + ivarr[jc].len) ivarr[ic].len = ivarr[jc].start + ivarr[jc].len - ivarr[ic].start; - if (jc > ic + 1) - { - memmove(ivarr + ic + 1, ivarr + jc,sizeof(interval) * (ivnum - jc)); + if (jc > ic + 1) { + memmove(ivarr + ic + 1, ivarr + jc, sizeof(interval) * (ivnum - jc)); ivnum -= jc - ic - 1; } } } -void PeFile::Interval::clear() -{ +void PeFile::Interval::clear() { for (unsigned ic = 0; ic < ivnum; ic++) - memset((char*) base + ivarr[ic].start,0,ivarr[ic].len); + memset((char *) base + ivarr[ic].start, 0, ivarr[ic].len); } -void PeFile::Interval::dump() const -{ - printf("%d intervals:\n",ivnum); +void PeFile::Interval::dump() const { + printf("%d intervals:\n", ivnum); for (unsigned ic = 0; ic < ivnum; ic++) - printf("%x %x\n",ivarr[ic].start,ivarr[ic].len); + printf("%x %x\n", ivarr[ic].start, ivarr[ic].len); } - /************************************************************************* // relocation handling **************************************************************************/ struct alignas(1) PeFile::Reloc::reloc { - LE32 pagestart; - LE32 size; + LE32 pagestart; + LE32 size; }; -void PeFile::Reloc::newRelocPos(void *p) -{ - rel = (reloc*) p; - rel1 = (LE16*) ((char*) p + sizeof (reloc)); +void PeFile::Reloc::newRelocPos(void *p) { + rel = (reloc *) p; + rel1 = (LE16 *) ((char *) p + sizeof(reloc)); } -PeFile::Reloc::Reloc(upx_byte *s,unsigned si) : - start(s), size(si), rel(nullptr), rel1(nullptr) -{ +PeFile::Reloc::Reloc(upx_byte *s, unsigned si) : start(s), size(si), rel(nullptr), rel1(nullptr) { COMPILE_TIME_ASSERT(sizeof(reloc) == 8) COMPILE_TIME_ASSERT_ALIGNED1(reloc) - memset(counts,0,sizeof(counts)); - unsigned pos,type; - while (next(pos,type)) + memset(counts, 0, sizeof(counts)); + unsigned pos, type; + while (next(pos, type)) counts[type]++; } -PeFile::Reloc::Reloc(unsigned rnum) : - start(nullptr), size(0), rel(nullptr), rel1(nullptr) -{ +PeFile::Reloc::Reloc(unsigned rnum) : start(nullptr), size(0), rel(nullptr), rel1(nullptr) { start = new upx_byte[mem_size(4, rnum, 8192)]; // => oxrelocs counts[0] = 0; } -bool PeFile::Reloc::next(unsigned &pos,unsigned &type) -{ +bool PeFile::Reloc::next(unsigned &pos, unsigned &type) { if (!rel) newRelocPos(start); if (ptr_diff_bytes(rel, start) >= (int) size) { @@ -330,40 +303,36 @@ bool PeFile::Reloc::next(unsigned &pos,unsigned &type) pos = rel->pagestart + (*rel1 & 0xfff); type = *rel1++ >> 12; - NO_printf("%x %d\n",pos,type); - if (ptr_diff_bytes(rel1,rel) >= (int) rel->size) + NO_printf("%x %d\n", pos, type); + if (ptr_diff_bytes(rel1, rel) >= (int) rel->size) newRelocPos(rel1); - return type == 0 ? next(pos,type) : true; + return type == 0 ? next(pos, type) : true; } -void PeFile::Reloc::add(unsigned pos,unsigned type) -{ - set_le32(start + 1024 + 4 * counts[0]++,(pos << 4) + type); +void PeFile::Reloc::add(unsigned pos, unsigned type) { + set_le32(start + 1024 + 4 * counts[0]++, (pos << 4) + type); } -void PeFile::Reloc::finish(upx_byte *&p,unsigned &siz) -{ +void PeFile::Reloc::finish(upx_byte *&p, unsigned &siz) { unsigned prev = 0xffffffff; - set_le32(start + 1024 + 4 * counts[0]++,0xf0000000); - qsort(start + 1024,counts[0],4,le32_compare); + set_le32(start + 1024 + 4 * counts[0]++, 0xf0000000); + qsort(start + 1024, counts[0], 4, le32_compare); - rel = (reloc*) start; - rel1 = (LE16*) start; - for (unsigned ic = 0; ic < counts[0]; ic++) - { + rel = (reloc *) start; + rel1 = (LE16 *) start; + for (unsigned ic = 0; ic < counts[0]; ic++) { unsigned pos = get_le32(start + 1024 + 4 * ic); - if ((pos ^ prev) >= 0x10000) - { + if ((pos ^ prev) >= 0x10000) { prev = pos; *rel1 = 0; - rel->size = ALIGN_UP(ptr_diff_bytes(rel1,rel), 4); - newRelocPos((char *)rel + rel->size); - rel->pagestart = (pos >> 4) &~ 0xfff; + rel->size = ALIGN_UP(ptr_diff_bytes(rel1, rel), 4); + newRelocPos((char *) rel + rel->size); + rel->pagestart = (pos >> 4) & ~0xfff; } *rel1++ = (pos << 12) + ((pos >> 4) & 0xfff); } p = start; - siz = ptr_udiff_bytes(rel1,start) &~ 3; + siz = ptr_udiff_bytes(rel1, start) & ~3; siz -= 8; // siz can be 0 in 64-bit mode // assert(siz > 0); start = nullptr; // safety @@ -371,7 +340,7 @@ void PeFile::Reloc::finish(upx_byte *&p,unsigned &siz) void PeFile::processRelocs(Reloc *rel) // pass2 { - rel->finish(oxrelocs,soxrelocs); + rel->finish(oxrelocs, soxrelocs); if (opt->win32_pe.strip_relocs) soxrelocs = 0; } @@ -390,10 +359,8 @@ void PeFile32::processRelocs() // pass1 for (ic = 1; ic < 16; ic++) rnum += counts[ic]; - if (opt->win32_pe.strip_relocs || rnum == 0) - { - if (IDSIZE(PEDIR_RELOC)) - { + if (opt->win32_pe.strip_relocs || rnum == 0) { + if (IDSIZE(PEDIR_RELOC)) { ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); ih.objects = tryremove(IDADDR(PEDIR_RELOC), ih.objects); } @@ -405,7 +372,7 @@ void PeFile32::processRelocs() // pass1 for (ic = 15; ic > 3; ic--) 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]; for (; ic; ic--) @@ -415,18 +382,16 @@ void PeFile32::processRelocs() // pass1 memset(xcounts, 0, sizeof(xcounts)); // prepare sorting - unsigned pos,type; - while (rel.next(pos,type)) - { + unsigned pos, type; + while (rel.next(pos, type)) { if (pos >= ih.imagesize) - continue; // skip out-of-bounds record + continue; // skip out-of-bounds record if (type < 4) fix[type][xcounts[type]++] = pos - rvamin; } // remove duplicated records - for (ic = 1; ic <= 3; ic++) - { + for (ic = 1; ic <= 3; ic++) { qsort(fix[ic], xcounts[ic], 4, le32_compare); unsigned prev = ~0u; unsigned jc = 0; @@ -439,42 +404,40 @@ void PeFile32::processRelocs() // pass1 } // preprocess "type 3" relocation records - for (ic = 0; ic < xcounts[3]; ic++) - { + for (ic = 0; ic < xcounts[3]; ic++) { pos = fix[3][ic] + rvamin; unsigned w = get_le32(ibuf.subref("bad reloc type 3 %#x", pos, sizeof(LE32))); set_le32(ibuf + pos, w - ih.imagebase - rvamin); } ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); - mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety + mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety orelocs = mb_orelocs; - sorelocs = optimizeReloc32((upx_byte*) fix[3], xcounts[3], - orelocs, ibuf + rvamin, ibufgood - rvamin, true, &big_relocs); - delete [] fix[3]; + sorelocs = optimizeReloc32((upx_byte *) fix[3], xcounts[3], orelocs, ibuf + rvamin, + ibufgood - rvamin, true, &big_relocs); + delete[] fix[3]; // Malware that hides behind UPX often has PE header info that is // deliberately corrupt. Sometimes it is even tuned to cause us trouble! // Use an extra check to avoid AccessViolation (SIGSEGV) when appending // the relocs into one array. - if ((rnum * 4 + 1024) < (sorelocs + 4*(2 + xcounts[2] + xcounts[1]))) + if ((rnum * 4 + 1024) < (sorelocs + 4 * (2 + xcounts[2] + xcounts[1]))) throwCantUnpack("Invalid relocs"); // append relocs type "LOW" then "HIGH" - for (ic = 2; ic ; ic--) - { - memcpy(orelocs + sorelocs,fix[ic],4 * xcounts[ic]); + for (ic = 2; ic; ic--) { + memcpy(orelocs + sorelocs, fix[ic], 4 * xcounts[ic]); sorelocs += 4 * xcounts[ic]; - delete [] fix[ic]; + delete[] fix[ic]; - set_le32(orelocs + sorelocs,0); - if (xcounts[ic]) - { + set_le32(orelocs + sorelocs, 0); + if (xcounts[ic]) { sorelocs += 4; big_relocs |= 2 * ic; } } - 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); } // FIXME - this is too similar to PeFile32::processRelocs @@ -492,10 +455,8 @@ void PeFile64::processRelocs() // pass1 for (ic = 1; ic < 16; ic++) rnum += counts[ic]; - if (opt->win32_pe.strip_relocs || rnum == 0) - { - if (IDSIZE(PEDIR_RELOC)) - { + if (opt->win32_pe.strip_relocs || rnum == 0) { + if (IDSIZE(PEDIR_RELOC)) { ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); ih.objects = tryremove(IDADDR(PEDIR_RELOC), ih.objects); } @@ -507,7 +468,7 @@ void PeFile64::processRelocs() // pass1 for (ic = 15; ic; ic--) if (ic != 10 && counts[ic]) - infoWarning("skipping unsupported relocation type %d (%d)",ic,counts[ic]); + infoWarning("skipping unsupported relocation type %d (%d)", ic, counts[ic]); LE32 *fix[16]; for (ic = 15; ic; ic--) @@ -517,21 +478,19 @@ void PeFile64::processRelocs() // pass1 memset(xcounts, 0, sizeof(xcounts)); // prepare sorting - unsigned pos,type; - while (rel.next(pos,type)) - { + unsigned pos, type; + while (rel.next(pos, type)) { // FIXME add check for relocations which try to modify the // PE header or other relocation records if (pos >= ih.imagesize) - continue; // skip out-of-bounds record + continue; // skip out-of-bounds record if (type < 16) fix[type][xcounts[type]++] = pos - rvamin; } // remove duplicated records - for (ic = 1; ic <= 15; ic++) - { + for (ic = 1; ic <= 15; ic++) { qsort(fix[ic], xcounts[ic], 4, le32_compare); unsigned prev = ~0u; unsigned jc = 0; @@ -544,21 +503,20 @@ void PeFile64::processRelocs() // pass1 } // preprocess "type 10" relocation records - for (ic = 0; ic < xcounts[10]; ic++) - { + for (ic = 0; ic < xcounts[10]; ic++) { pos = fix[10][ic] + rvamin; upx_uint64_t w = get_le64(ibuf.subref("bad reloc 10 %#x", pos, sizeof(LE64))); set_le64(ibuf + pos, w - ih.imagebase - rvamin); } ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); - mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety + mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety orelocs = mb_orelocs; - sorelocs = optimizeReloc64((upx_byte*) fix[10], xcounts[10], - orelocs, ibuf + rvamin, ibufgood - rvamin, true, &big_relocs); + sorelocs = optimizeReloc64((upx_byte *) fix[10], xcounts[10], orelocs, ibuf + rvamin, + ibufgood - rvamin, true, &big_relocs); for (ic = 15; ic; ic--) - delete [] fix[ic]; + delete[] fix[ic]; #if 0 // Malware that hides behind UPX often has PE header info that is @@ -583,17 +541,18 @@ void PeFile64::processRelocs() // pass1 } } #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); } /************************************************************************* // import handling **************************************************************************/ -LE32& PeFile::IDSIZE(unsigned x) { return iddirs[x].size; } -LE32& PeFile::IDADDR(unsigned x) { return iddirs[x].vaddr; } -LE32& PeFile::ODSIZE(unsigned x) { return oddirs[x].size; } -LE32& PeFile::ODADDR(unsigned x) { return oddirs[x].vaddr; } +LE32 &PeFile::IDSIZE(unsigned x) { return iddirs[x].size; } +LE32 &PeFile::IDADDR(unsigned x) { return iddirs[x].vaddr; } +LE32 &PeFile::ODSIZE(unsigned x) { return oddirs[x].size; } +LE32 &PeFile::ODADDR(unsigned x) { return oddirs[x].vaddr; } /* ImportLinker: 32 and 64 bit import table building. @@ -608,33 +567,28 @@ LE32& PeFile::ODADDR(unsigned x) { return oddirs[x].vaddr; } in the sorted order. */ -class PeFile::ImportLinker : public ElfLinkerAMD64 -{ - struct tstr : private ::noncopyable - { +class PeFile::ImportLinker : public ElfLinkerAMD64 { + struct tstr : private ::noncopyable { char *s = nullptr; explicit tstr(char *str) : s(str) {} - ~tstr() { delete [] s; } + ~tstr() { delete[] s; } operator char *() const { return s; } }; // encoding of dll and proc names are required, so that our special // control characters in the name of sections can work as intended - static char *encode_name(const char *name, char *buf) - { + static char *encode_name(const char *name, char *buf) { char *b = buf; - while (*name) - { + while (*name) { *b++ = 'a' + ((*name >> 4) & 0xf); - *b++ = 'a' + (*name & 0xf); + *b++ = 'a' + (*name & 0xf); name++; } *b = 0; return buf; } - static char *name_for_dll(const char *dll, char first_char) - { + static char *name_for_dll(const char *dll, char first_char) { assert(dll); unsigned l = strlen(dll); assert(l > 0); @@ -645,17 +599,15 @@ class PeFile::ImportLinker : public ElfLinkerAMD64 char *n = name + 1 + 2 * l; do { *n++ = tolower(*dll); - } while(*dll++); + } while (*dll++); return encode_name(name + 1 + 2 * l, name + 1) - 1; } - static char *name_for_proc(const char *dll, const char *proc, - char first_char, char separator) - { + static char *name_for_proc(const char *dll, const char *proc, char first_char, char separator) { unsigned len = 1 + 2 * strlen(dll) + 1 + 2 * strlen(proc) + 1 + 1; tstr dlln(name_for_dll(dll, first_char)); char *procn = New(char, len); - upx_safe_snprintf(procn, len, "%s%c", (const char*) dlln, separator); + upx_safe_snprintf(procn, len, "%s%c", (const char *) dlln, separator); encode_name(proc, procn + strlen(procn)); return procn; } @@ -678,21 +630,18 @@ class PeFile::ImportLinker : public ElfLinkerAMD64 unsigned thunk_size; // 4 or 8 bytes - void add(const char *dll, const char *proc, unsigned ordinal) - { + void add(const char *dll, const char *proc, unsigned ordinal) { tstr sdll(name_for_dll(dll, dll_name_id)); tstr desc_name(name_for_dll(dll, descriptor_id)); char tsep = thunk_separator; - if (findSection(sdll, false) == nullptr) - { + if (findSection(sdll, false) == nullptr) { tsep = thunk_separator_first; addSection(sdll, dll, strlen(dll) + 1, 0); // name of the dll addSymbol(sdll, sdll, 0); addSection(desc_name, zeros, sizeof(zeros), 0); // descriptor - addRelocation(desc_name, offsetof(import_desc, dllname), - "R_X86_64_32", sdll, 0); + addRelocation(desc_name, offsetof(import_desc, dllname), "R_X86_64_32", sdll, 0); } tstr thunk(proc == nullptr ? name_for_dll(dll, thunk_id) : name_for_proc(dll, proc, thunk_id, tsep)); @@ -701,23 +650,17 @@ class PeFile::ImportLinker : public ElfLinkerAMD64 return; // we already have this dll/proc addSection(thunk, zeros, thunk_size, 0); addSymbol(thunk, thunk, 0); - if (tsep == thunk_separator_first) - { - addRelocation(desc_name, offsetof(import_desc, iat), - "R_X86_64_32", thunk, 0); + if (tsep == thunk_separator_first) { + addRelocation(desc_name, offsetof(import_desc, iat), "R_X86_64_32", thunk, 0); tstr last_thunk(name_for_proc(dll, "X", thunk_id, thunk_separator_last)); addSection(last_thunk, zeros, thunk_size, 0); } const char *reltype = thunk_size == 4 ? "R_X86_64_32" : "R_X86_64_64"; - if (ordinal != 0u) - { - addRelocation(thunk, 0, reltype, "*UND*", - ordinal | (1ull << (thunk_size * 8 - 1))); - } - else if (proc != nullptr) - { + if (ordinal != 0u) { + addRelocation(thunk, 0, reltype, "*UND*", ordinal | (1ull << (thunk_size * 8 - 1))); + } else if (proc != nullptr) { tstr proc_name(name_for_proc(dll, proc, proc_name_id, procname_separator)); addSection(proc_name, zeros, 2, 1); // 2 bytes of word aligned "hint" addSymbol(proc_name, proc_name, 0); @@ -725,22 +668,19 @@ class PeFile::ImportLinker : public ElfLinkerAMD64 strcat(proc_name, "X"); addSection(proc_name, proc, strlen(proc), 0); // the name of the symbol - } - else + } else infoWarning("empty import: %s", dll); } - static int __acc_cdecl_qsort compare(const void *p1, const void *p2) - { - const Section *s1 = * (const Section * const *) p1; - const Section *s2 = * (const Section * const *) p2; + static int __acc_cdecl_qsort compare(const void *p1, const void *p2) { + const Section *s1 = *(const Section *const *) p1; + const Section *s2 = *(const Section *const *) p2; return strcmp(s1->name, s2->name); } virtual void alignCode(unsigned len) override { alignWithByte(len, 0); } - const Section *getThunk(const char *dll, const char *proc, char tsep) const - { + const Section *getThunk(const char *dll, const char *proc, char tsep) const { assert(dll); assert(proc); tstr thunk(name_for_proc(dll, proc, thunk_id, tsep)); @@ -748,8 +688,7 @@ class PeFile::ImportLinker : public ElfLinkerAMD64 } public: - explicit ImportLinker(unsigned thunk_size_) : thunk_size(thunk_size_) - { + explicit ImportLinker(unsigned thunk_size_) : thunk_size(thunk_size_) { assert(thunk_size == 4 || thunk_size == 8); addSection("*UND*", nullptr, 0, 0); addSymbol("*UND*", "*UND*", 0); @@ -763,26 +702,23 @@ public: } template - void add(const C *dll, unsigned ordinal) - { - ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" + void add(const C *dll, unsigned ordinal) { + ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" assert(ordinal < 0x10000); - char ord[1+5+1]; + char ord[1 + 5 + 1]; upx_safe_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal); - add((const char*) dll, ordinal ? ord : nullptr, ordinal); + add((const char *) dll, ordinal ? ord : nullptr, ordinal); } template - void add(const C1 *dll, const C2 *proc) - { - ACC_COMPILE_TIME_ASSERT(sizeof(C1) == 1) // "char" or "unsigned char" - ACC_COMPILE_TIME_ASSERT(sizeof(C2) == 1) // "char" or "unsigned char" + void add(const C1 *dll, const C2 *proc) { + ACC_COMPILE_TIME_ASSERT(sizeof(C1) == 1) // "char" or "unsigned char" + ACC_COMPILE_TIME_ASSERT(sizeof(C2) == 1) // "char" or "unsigned char" assert(proc); - add((const char*) dll, (const char*) proc, 0); + add((const char *) dll, (const char *) proc, 0); } - unsigned build() - { + unsigned build() { assert(output == nullptr); int osize = 4 + 2 * nsections; // upper limit for alignments for (unsigned ic = 0; ic < nsections; ic++) @@ -791,79 +727,68 @@ public: outputlen = 0; // sort the sections by name before adding them all - qsort(sections, nsections, sizeof (Section*), ImportLinker::compare); + qsort(sections, nsections, sizeof(Section *), ImportLinker::compare); for (unsigned ic = 0; ic < nsections; ic++) addLoader(sections[ic]->name); addLoader("+40D"); assert(outputlen <= osize); - //OutputFile::dump("il0.imp", output, outputlen); + // OutputFile::dump("il0.imp", output, outputlen); return outputlen; } - void relocate_import(unsigned myimport) - { + void relocate_import(unsigned myimport) { assert(nsections > 0); assert(output); defineSymbol("*ZSTART", /*0xffffffffff1000ull + 0 * */ myimport); ElfLinkerAMD64::relocate(); - //OutputFile::dump("il1.imp", output, outputlen); + // OutputFile::dump("il1.imp", output, outputlen); } template - upx_uint64_t getAddress(const C1 *dll, const C2 *proc) const - { - ACC_COMPILE_TIME_ASSERT(sizeof(C1) == 1) // "char" or "unsigned char" - ACC_COMPILE_TIME_ASSERT(sizeof(C2) == 1) // "char" or "unsigned char" - const Section *s = getThunk((const char*) dll, (const char*) proc, - thunk_separator_first); - if (s == nullptr && (s = getThunk((const char*) dll,(const char*) proc, - thunk_separator)) == nullptr) + upx_uint64_t getAddress(const C1 *dll, const C2 *proc) const { + ACC_COMPILE_TIME_ASSERT(sizeof(C1) == 1) // "char" or "unsigned char" + ACC_COMPILE_TIME_ASSERT(sizeof(C2) == 1) // "char" or "unsigned char" + const Section *s = getThunk((const char *) dll, (const char *) proc, thunk_separator_first); + if (s == nullptr && + (s = getThunk((const char *) dll, (const char *) proc, thunk_separator)) == nullptr) throwInternalError("entry not found"); return s->offset; } template - upx_uint64_t getAddress(const C *dll, unsigned ordinal) const - { - ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" + upx_uint64_t getAddress(const C *dll, unsigned ordinal) const { + ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" assert(ordinal > 0 && ordinal < 0x10000); - char ord[1+5+1]; + char ord[1 + 5 + 1]; upx_safe_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal); - const Section *s = getThunk((const char*) dll, ord, thunk_separator_first); - if (s == nullptr - && (s = getThunk((const char*) dll, ord, thunk_separator)) == nullptr) + const Section *s = getThunk((const char *) dll, ord, thunk_separator_first); + if (s == nullptr && (s = getThunk((const char *) dll, ord, thunk_separator)) == nullptr) throwInternalError("entry not found"); return s->offset; } template - upx_uint64_t getAddress(const C *dll) const - { - ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" - tstr sdll(name_for_dll((const char*) dll, dll_name_id)); + upx_uint64_t getAddress(const C *dll) const { + ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" + tstr sdll(name_for_dll((const char *) dll, dll_name_id)); return findSection(sdll, true)->offset; } template - upx_uint64_t hasDll(const C *dll) const - { - ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" - tstr sdll(name_for_dll((const char*) dll, dll_name_id)); + upx_uint64_t hasDll(const C *dll) const { + ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" + tstr sdll(name_for_dll((const char *) dll, dll_name_id)); return findSection(sdll, false) != nullptr; } }; -const char PeFile::ImportLinker::zeros[sizeof(import_desc)] = { 0 }; +const char PeFile::ImportLinker::zeros[sizeof(import_desc)] = {0}; -void PeFile::addKernelImport(const char *name) -{ - ilinker->add(kernelDll(), name); -} +void PeFile::addKernelImport(const char *name) { ilinker->add(kernelDll(), name); } -void PeFile::addStubImports() -{ +void PeFile::addStubImports() { addKernelImport("LoadLibraryA"); addKernelImport("GetProcAddress"); if (!isdll) @@ -882,7 +807,7 @@ void PeFile::processImports2(unsigned myimport, unsigned) // pass 2 int len; oimpdlls = ilinker->getLoader(&len); assert(len == (int) soimpdlls); - //OutputFile::dump("x1.imp", oimpdlls, soimpdlls); + // OutputFile::dump("x1.imp", oimpdlls, soimpdlls); } template @@ -898,84 +823,87 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 unsigned dllnum = 0; unsigned const take = IDSIZE(PEDIR_IMPORT); unsigned const skip = IDADDR(PEDIR_IMPORT); - import_desc *im = (import_desc*)ibuf.subref("bad import %#x", skip, take); - import_desc * const im_save = im; - if (IDADDR(PEDIR_IMPORT)) - { + import_desc *im = (import_desc *) ibuf.subref("bad import %#x", skip, take); + import_desc *const im_save = im; + if (IDADDR(PEDIR_IMPORT)) { for (;; ++dllnum, ++im) { unsigned const skip2 = ptr_diff_bytes(im, ibuf); - (void)ibuf.subref("bad import %#x", skip2, sizeof(*im)); + (void) ibuf.subref("bad import %#x", skip2, sizeof(*im)); if (!im->dllname) break; } im = im_save; } - struct udll - { + struct udll { const upx_byte *name; const upx_byte *shname; - unsigned ordinal; - unsigned iat; - LEXX *lookupt; - unsigned original_position; - bool isk32; + unsigned ordinal; + unsigned iat; + LEXX *lookupt; + unsigned original_position; + bool isk32; - static int __acc_cdecl_qsort compare(const void *p1, const void *p2) - { - const udll *u1 = * (const udll * const *) p1; - const udll *u2 = * (const udll * const *) p2; - if (u1->isk32) return -1; - if (u2->isk32) return 1; - if (!*u1->lookupt) return 1; - if (!*u2->lookupt) return -1; - int rc = strcasecmp(u1->name,u2->name); - if (rc) return rc; - if (u1->ordinal) return -1; - if (u2->ordinal) return 1; - if (!u1->shname) return 1; - if (!u2->shname) return -1; + static int __acc_cdecl_qsort compare(const void *p1, const void *p2) { + const udll *u1 = *(const udll *const *) p1; + const udll *u2 = *(const udll *const *) p2; + if (u1->isk32) + return -1; + if (u2->isk32) + return 1; + if (!*u1->lookupt) + return 1; + if (!*u2->lookupt) + return -1; + int rc = strcasecmp(u1->name, u2->name); + if (rc) + return rc; + if (u1->ordinal) + return -1; + if (u2->ordinal) + return 1; + if (!u1->shname) + return 1; + if (!u2->shname) + return -1; rc = (int) (upx_safe_strlen(u1->shname) - upx_safe_strlen(u2->shname)); - if (rc) return rc; + if (rc) + return rc; return strcmp(u1->shname, u2->shname); } }; // +1 for dllnum=0 - Array(struct udll, dlls, dllnum+1); - Array(struct udll *, idlls, dllnum+1); + Array(struct udll, dlls, dllnum + 1); + Array(struct udll *, idlls, dllnum + 1); soimport = 1024; // safety unsigned ic; - for (ic = 0; dllnum && im->dllname; ic++, im++) - { + for (ic = 0; dllnum && im->dllname; ic++, im++) { idlls[ic] = dlls + ic; dlls[ic].name = ibuf.subref("bad dllname %#x", im->dllname, 1); dlls[ic].shname = nullptr; dlls[ic].ordinal = 0; dlls[ic].iat = im->iat; unsigned const skip2 = (im->oft ? im->oft : im->iat); - dlls[ic].lookupt = (LEXX*)ibuf.subref("bad dll lookupt %#x", skip2, sizeof(LEXX)); + dlls[ic].lookupt = (LEXX *) ibuf.subref("bad dll lookupt %#x", skip2, sizeof(LEXX)); dlls[ic].original_position = ic; dlls[ic].isk32 = strcasecmp(kernelDll(), dlls[ic].name) == 0; soimport += strlen(dlls[ic].name) + 1 + 4; - for (IPTR_I(LEXX, tarr, dlls[ic].lookupt); *tarr; tarr += 1) - { - if (*tarr & ord_mask) - { + for (IPTR_I(LEXX, tarr, dlls[ic].lookupt); *tarr; tarr += 1) { + if (*tarr & ord_mask) { importbyordinal = true; soimport += 2; // ordinal num: 2 bytes dlls[ic].ordinal = *tarr & 0xffff; - } - else //it's an import by name + } else // it's an import by name { IPTR_I(const upx_byte, n, ibuf + *tarr + 2); unsigned len = strlen(n); soimport += len + 1; - if (dlls[ic].shname == nullptr || len < strlen (dlls[ic].shname)) + if (dlls[ic].shname == nullptr || len < strlen(dlls[ic].shname)) dlls[ic].shname = ibuf + *tarr + 2; } soimport++; // separator @@ -985,7 +913,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 mb_oimport.clear(); oimport = mb_oimport; - qsort(idlls,dllnum,sizeof (udll*),udll::compare); + qsort(idlls, dllnum, sizeof(udll *), udll::compare); info("Processing imports: %d DLLs", dllnum); @@ -993,10 +921,8 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 // create the new import table addStubImports(); - for (ic = 0; ic < dllnum; ic++) - { - if (idlls[ic]->isk32) - { + for (ic = 0; ic < dllnum; ic++) { + if (idlls[ic]->isk32) { // for kernel32.dll we need to put all the imported // ordinals into the output import table, as on // some versions of windows GetProcAddress does not resolve them @@ -1004,14 +930,11 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 continue; if (idlls[ic]->ordinal) for (LEXX *tarr = idlls[ic]->lookupt; *tarr; tarr++) - if (*tarr & ord_mask) - { + if (*tarr & ord_mask) { ilinker->add(kernelDll(), *tarr & 0xffff); kernel32ordinal = true; } - } - else if (!ilinker->hasDll(idlls[ic]->name)) - { + } else if (!ilinker->hasDll(idlls[ic]->name)) { if (idlls[ic]->shname && !idlls[ic]->ordinal) ilinker->add(idlls[ic]->name, idlls[ic]->shname); else @@ -1021,66 +944,59 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 soimpdlls = ilinker->build(); - Interval names(ibuf),iats(ibuf),lookups(ibuf); + Interval names(ibuf), iats(ibuf), lookups(ibuf); // create the preprocessed data - SPAN_P_VAR(upx_byte, ppi, oimport); // preprocessed imports - for (ic = 0; ic < dllnum; ic++) - { + SPAN_P_VAR(upx_byte, ppi, oimport); // preprocessed imports + for (ic = 0; ic < dllnum; ic++) { LEXX *tarr = idlls[ic]->lookupt; set_le32(ppi, ilinker->getAddress(idlls[ic]->name)); - set_le32(ppi+4,idlls[ic]->iat - rvamin); + set_le32(ppi + 4, idlls[ic]->iat - rvamin); ppi += 8; for (; *tarr; tarr++) - if (*tarr & ord_mask) - { + if (*tarr & ord_mask) { unsigned ord = *tarr & 0xffff; - if (idlls[ic]->isk32 && kernel32ordinal) - { + if (idlls[ic]->isk32 && kernel32ordinal) { *ppi++ = 0xfe; // signed + odd parity set_le32(ppi, ilinker->getAddress(idlls[ic]->name, ord)); ppi += 4; - } - else - { + } else { *ppi++ = 0xff; set_le16(ppi, ord); ppi += 2; } - } - else - { + } else { *ppi++ = 1; - unsigned const skip2 = 2+ *tarr; - unsigned const take2 = 1+ strlen(ibuf.subref("bad import name %#x", skip2, 1)); - memcpy(ppi,ibuf.subref("bad import name %#x", skip2, take2), take2); + unsigned const skip2 = 2 + *tarr; + unsigned const take2 = 1 + strlen(ibuf.subref("bad import name %#x", skip2, 1)); + memcpy(ppi, ibuf.subref("bad import name %#x", skip2, take2), take2); ppi += take2; - names.add(*tarr, 2+ take2); + names.add(*tarr, 2 + take2); } ppi++; unsigned esize = ptr_diff_bytes(tarr, idlls[ic]->lookupt); - lookups.add(idlls[ic]->lookupt,esize); - if (ptr_diff_bytes(ibuf.subref("bad import name %#x", idlls[ic]->iat, 1), (char *)idlls[ic]->lookupt) != 0) - { - memcpy(ibuf.subref("bad import name %#x", idlls[ic]->iat, esize), idlls[ic]->lookupt, esize); - iats.add(idlls[ic]->iat,esize); + lookups.add(idlls[ic]->lookupt, esize); + if (ptr_diff_bytes(ibuf.subref("bad import name %#x", idlls[ic]->iat, 1), + (char *) idlls[ic]->lookupt) != 0) { + memcpy(ibuf.subref("bad import name %#x", idlls[ic]->iat, esize), idlls[ic]->lookupt, + esize); + iats.add(idlls[ic]->iat, esize); } - names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1); + names.add(idlls[ic]->name, strlen(idlls[ic]->name) + 1 + 1); } ppi += 4; - assert(ppi < oimport+soimport); - soimport = ptr_diff_bytes(ppi,oimport); + assert(ppi < oimport + soimport); + soimport = ptr_diff_bytes(ppi, oimport); if (soimport == 4) soimport = 0; - //OutputFile::dump("x0.imp", oimport, soimport); + // OutputFile::dump("x0.imp", oimport, soimport); unsigned ilen = 0; names.flatten(); - if (names.ivnum > 1) - { + if (names.ivnum > 1) { // The area occupied by the dll and imported names is not continuous // so to still support uncompression, I can't zero the iat area. // This decreases compression ratio, so FIXME somehow. @@ -1092,15 +1008,12 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 #endif // do some work for the unpacker im = im_save; - for (ic = 0; ic < dllnum; ic++, im++) - { - memset(im,FILLVAL,sizeof(*im)); - im->dllname = ptr_diff_bytes(dlls[idlls[ic]->original_position].name,ibuf); + for (ic = 0; ic < dllnum; ic++, im++) { + memset(im, FILLVAL, sizeof(*im)); + im->dllname = ptr_diff_bytes(dlls[idlls[ic]->original_position].name, ibuf); } - } - else - { - iats.add(im_save,sizeof(import_desc) * dllnum); + } else { + iats.add(im_save, sizeof(import_desc) * dllnum); // zero unneeded data iats.clear(); lookups.clear(); @@ -1113,7 +1026,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 for (ic = 0; ic < iats.ivnum; ic++) ilen += iats.ivarr[ic].len; - info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport); + info("Imports: original size: %u bytes, preprocessed size: %u bytes", ilen, soimport); return names.ivnum == 1 ? names.ivarr[0].start : 0; } @@ -1121,83 +1034,78 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 // export handling **************************************************************************/ -PeFile::Export::Export(char *_base) : base(_base), iv(_base) -{ +PeFile::Export::Export(char *_base) : base(_base), iv(_base) { COMPILE_TIME_ASSERT(sizeof(export_dir_t) == 40) COMPILE_TIME_ASSERT_ALIGNED1(export_dir_t) ename = functionptrs = ordinals = nullptr; names = nullptr; - memset(&edir,0,sizeof(edir)); + memset(&edir, 0, sizeof(edir)); size = 0; } -PeFile::Export::~Export() -{ +PeFile::Export::~Export() { free(ename); - delete [] functionptrs; - delete [] ordinals; + delete[] functionptrs; + delete[] ordinals; if (names) { unsigned const limit = edir.names + edir.functions; for (unsigned ic = 0; ic < limit; ic++) - if (names[ic]) free(names[ic]); // allocated by strdup() - delete [] names; + if (names[ic]) + free(names[ic]); // allocated by strdup() + delete[] names; } } -void PeFile::Export::convert(unsigned eoffs,unsigned esize) -{ - memcpy(&edir,base + eoffs,sizeof(export_dir_t)); +void PeFile::Export::convert(unsigned eoffs, unsigned esize) { + memcpy(&edir, base + eoffs, sizeof(export_dir_t)); size = sizeof(export_dir_t); - iv.add(eoffs,size); + iv.add(eoffs, size); - if (!edir.name || eoffs + esize <= (unsigned)edir.name) { - char msg[50]; snprintf(msg, sizeof(msg), - "bad export directory name RVA %#x", (unsigned)edir.name); + if (!edir.name || eoffs + esize <= (unsigned) edir.name) { + char msg[50]; + snprintf(msg, sizeof(msg), "bad export directory name RVA %#x", (unsigned) edir.name); throwInternalError(msg); } unsigned len = strlen(base + edir.name) + 1; ename = strdup(base + edir.name); size += len; - iv.add(edir.name,len); + iv.add(edir.name, len); len = 4 * edir.functions; functionptrs = New(char, len + 1); - memcpy(functionptrs,base + edir.addrtable,len); + memcpy(functionptrs, base + edir.addrtable, len); size += len; - iv.add(edir.addrtable,len); + iv.add(edir.addrtable, len); unsigned ic; names = New(char *, edir.names + edir.functions + 1); - for (ic = 0; ic < edir.names; ic++) - { + for (ic = 0; ic < edir.names; ic++) { char *n = base + get_le32(base + edir.nameptrtable + ic * 4); len = strlen(n) + 1; names[ic] = strdup(n); size += len; - iv.add(get_le32(base + edir.nameptrtable + ic * 4),len); + iv.add(get_le32(base + edir.nameptrtable + ic * 4), len); } - iv.add(edir.nameptrtable,4 * edir.names); + iv.add(edir.nameptrtable, 4 * edir.names); size += 4 * edir.names; - LE32 *fp = (LE32*) functionptrs; + LE32 *fp = (LE32 *) functionptrs; // export forwarders for (ic = 0; ic < edir.functions; ic++) - if (fp[ic] >= eoffs && fp[ic] < eoffs + esize) - { + if (fp[ic] >= eoffs && fp[ic] < eoffs + esize) { char *forw = base + fp[ic]; len = strlen(forw) + 1; - iv.add(forw,len); + iv.add(forw, len); size += len; names[ic + edir.names] = strdup(forw); - } - else + } else names[ic + edir.names] = nullptr; len = 2 * edir.names; ordinals = New(char, len + 1); - memcpy(ordinals,base + edir.ordinaltable,len); + memcpy(ordinals, base + edir.ordinaltable, len); size += len; - iv.add(edir.ordinaltable,len); + iv.add(edir.ordinaltable, len); iv.flatten(); if (iv.ivnum == 1) iv.clear(); @@ -1207,67 +1115,62 @@ void PeFile::Export::convert(unsigned eoffs,unsigned esize) #endif } -void PeFile::Export::build(char *newbase, unsigned newoffs) -{ - char * const functionp = newbase + sizeof(edir); - char * const namep = functionp + 4 * edir.functions; - char * const ordinalp = namep + 4 * edir.names; - char * const enamep = ordinalp + 2 * edir.names; - char * exports = enamep + strlen(ename) + 1; +void PeFile::Export::build(char *newbase, unsigned newoffs) { + char *const functionp = newbase + sizeof(edir); + char *const namep = functionp + 4 * edir.functions; + char *const ordinalp = namep + 4 * edir.names; + char *const enamep = ordinalp + 2 * edir.names; + char *exports = enamep + strlen(ename) + 1; edir.addrtable = newoffs + ptr_diff_bytes(functionp, newbase); edir.ordinaltable = newoffs + ptr_diff_bytes(ordinalp, newbase); - memcpy(ordinalp,ordinals,2 * edir.names); + memcpy(ordinalp, ordinals, 2 * edir.names); edir.name = newoffs + ptr_diff_bytes(enamep, newbase); - strcpy(enamep,ename); + strcpy(enamep, ename); edir.nameptrtable = newoffs + ptr_diff_bytes(namep, newbase); unsigned ic; - for (ic = 0; ic < edir.names; ic++) - { - strcpy(exports,names[ic]); - set_le32(namep + 4 * ic,newoffs + ptr_diff_bytes(exports, newbase)); + for (ic = 0; ic < edir.names; ic++) { + strcpy(exports, names[ic]); + set_le32(namep + 4 * ic, newoffs + ptr_diff_bytes(exports, newbase)); exports += strlen(exports) + 1; } - memcpy(functionp,functionptrs,4 * edir.functions); + memcpy(functionp, functionptrs, 4 * edir.functions); for (ic = 0; ic < edir.functions; ic++) - if (names[edir.names + ic]) - { - strcpy(exports,names[edir.names + ic]); - set_le32(functionp + 4 * ic,newoffs + ptr_diff_bytes(exports, newbase)); + if (names[edir.names + ic]) { + strcpy(exports, names[edir.names + ic]); + set_le32(functionp + 4 * ic, newoffs + ptr_diff_bytes(exports, newbase)); exports += strlen(exports) + 1; } - memcpy(newbase,&edir,sizeof(edir)); + memcpy(newbase, &edir, sizeof(edir)); assert(exports - newbase == (int) size); } void PeFile::processExports(Export *xport) // pass1 { - soexport = ALIGN_UP(IDSIZE(PEDIR_EXPORT),4u); + soexport = ALIGN_UP(IDSIZE(PEDIR_EXPORT), 4u); if (soexport == 0) return; - if (!isdll && opt->win32_pe.compress_exports) - { + if (!isdll && opt->win32_pe.compress_exports) { infoWarning("exports compressed, --compress-exports=0 might be needed"); soexport = 0; return; } - xport->convert(IDADDR(PEDIR_EXPORT),IDSIZE(PEDIR_EXPORT)); + xport->convert(IDADDR(PEDIR_EXPORT), IDSIZE(PEDIR_EXPORT)); soexport = ALIGN_UP(xport->getsize(), 4u); mb_oexport.alloc(soexport); mb_oexport.clear(); oexport = mb_oexport; } -void PeFile::processExports(Export *xport,unsigned newoffs) // pass2 +void PeFile::processExports(Export *xport, unsigned newoffs) // pass2 { if (soexport) xport->build((char *) raw_bytes(oexport, 0), newoffs); } - /************************************************************************* // TLS handling **************************************************************************/ @@ -1282,8 +1185,7 @@ void PeFile::processExports(Export *xport,unsigned newoffs) // pass2 // of course it was impossible to debug this ;-) template <> -struct PeFile::tls_traits -{ +struct PeFile::tls_traits { struct alignas(1) tls { LE32 datastart; // VA tls init data start LE32 dataend; // VA tls init data end @@ -1300,8 +1202,7 @@ struct PeFile::tls_traits }; template <> -struct PeFile::tls_traits -{ +struct PeFile::tls_traits { struct alignas(1) tls { LE64 datastart; // VA tls init data start LE64 dataend; // VA tls init data end @@ -1314,12 +1215,11 @@ struct PeFile::tls_traits static const unsigned cb_size = 8; typedef upx_uint64_t cb_value_t; static const unsigned reloc_type = 10; - static const int tls_handler_offset_reloc = -1; // no need to relocate + static const int tls_handler_offset_reloc = -1; // no need to relocate }; template -void PeFile::processTls1(Interval *iv, - typename tls_traits::cb_value_t imagebase, +void PeFile::processTls1(Interval *iv, typename tls_traits::cb_value_t imagebase, unsigned imagesize) // pass 1 { typedef typename tls_traits::tls tls; @@ -1332,39 +1232,37 @@ void PeFile::processTls1(Interval *iv, if (isefi && IDSIZE(PEDIR_TLS)) throwCantPack("TLS not supported on EFI"); - unsigned const take = ALIGN_UP(IDSIZE(PEDIR_TLS),4u); + unsigned const take = ALIGN_UP(IDSIZE(PEDIR_TLS), 4u); sotls = take; if (!sotls) return; unsigned const skip = IDADDR(PEDIR_TLS); - const tls * const tlsp = (const tls*)ibuf.subref("bad tls %#x", skip, sizeof(tls)); + const tls *const tlsp = (const tls *) ibuf.subref("bad tls %#x", skip, sizeof(tls)); // note: TLS callbacks are not implemented in Windows 95/98/ME - if (tlsp->callbacks) - { + if (tlsp->callbacks) { if (tlsp->callbacks < imagebase) throwCantPack("invalid TLS callback"); else if (tlsp->callbacks - imagebase + 4 >= imagesize) throwCantPack("invalid TLS callback"); - cb_value_t v = *(LEXX*)ibuf.subref("bad TLS %#x", (tlsp->callbacks - imagebase), sizeof(LEXX)); + cb_value_t v = + *(LEXX *) ibuf.subref("bad TLS %#x", (tlsp->callbacks - imagebase), sizeof(LEXX)); - if(v != 0) - { - //count number of callbacks, just for information string - Stefan Widmann + if (v != 0) { + // count number of callbacks, just for information string - Stefan Widmann unsigned num_callbacks = 0; unsigned callback_offset = 0; - while (*(LEXX*)ibuf.subref("bad TLS %#x", - tlsp->callbacks - imagebase + callback_offset, sizeof(LEXX))) - { - //increment number of callbacks + while (*(LEXX *) ibuf.subref( + "bad TLS %#x", tlsp->callbacks - imagebase + callback_offset, sizeof(LEXX))) { + // increment number of callbacks num_callbacks++; callback_offset += cb_size; } info("TLS: %u callback(s) found, adding TLS callback handler", num_callbacks); - //set flag to include necessary sections in loader + // set flag to include necessary sections in loader use_tls_callbacks = true; - //define linker symbols + // define linker symbols tlscb_ptr = tlsp->callbacks; } } @@ -1376,17 +1274,17 @@ void PeFile::processTls1(Interval *iv, unsigned const take2 = IDSIZE(PEDIR_RELOC); unsigned const skip2 = IDADDR(PEDIR_RELOC); Reloc rel(ibuf.subref("bad tls reloc %#x", skip2, take2), take2); - unsigned pos,type; - while (rel.next(pos,type)) + unsigned pos, type; + while (rel.next(pos, type)) if (pos >= tlsdatastart && pos < tlsdataend) - iv->add(pos,type); + iv->add(pos, type); sotls = sizeof(tls) + tlsdataend - tlsdatastart; // if TLS callbacks are used, we need two more {D|Q}WORDS at the end of the TLS // ... and those dwords should be correctly aligned if (use_tls_callbacks) sotls = ALIGN_UP(sotls, cb_size) + 2 * cb_size; - const unsigned aligned_sotls = ALIGN_UP(sotls, (unsigned)sizeof(LEXX)); + const unsigned aligned_sotls = ALIGN_UP(sotls, (unsigned) sizeof(LEXX)); // the PE loader wants this stuff uncompressed mb_otls.alloc(aligned_sotls); @@ -1394,14 +1292,14 @@ void PeFile::processTls1(Interval *iv, otls = mb_otls; // => otls now is a SPAN_S unsigned const take1 = sizeof(tls); unsigned const skip1 = IDADDR(PEDIR_TLS); - memcpy(otls,ibuf.subref("bad tls %#x", skip1, take1), take1); + memcpy(otls, ibuf.subref("bad tls %#x", skip1, take1), take1); // WARNING: this can acces data in BSS unsigned const take3 = sotls - sizeof(tls); - memcpy(otls + sizeof(tls),ibuf.subref("bad tls %#x", tlsdatastart, take3), take3); + memcpy(otls + sizeof(tls), ibuf.subref("bad tls %#x", tlsdatastart, take3), take3); tlsindex = tlsp->tlsindex - imagebase; - //NEW: subtract two dwords if TLS callbacks are used - Stefan Widmann + // 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 ? 2 * cb_size : 0),iv->ivnum); + sotls - (unsigned) sizeof(tls) - (use_tls_callbacks ? 2 * cb_size : 0), iv->ivnum); // makes sure tls index is zero after decompression if (tlsindex && tlsindex < imagesize) @@ -1409,7 +1307,7 @@ void PeFile::processTls1(Interval *iv, } template -void PeFile::processTls2(Reloc *rel,const Interval *iv,unsigned newaddr, +void PeFile::processTls2(Reloc *rel, const Interval *iv, unsigned newaddr, typename tls_traits::cb_value_t imagebase) // pass 2 { typedef typename tls_traits::tls tls; @@ -1422,46 +1320,44 @@ void PeFile::processTls2(Reloc *rel,const Interval *iv,unsigned newaddr, return; // add new relocation entries - if __acc_cte(tls_handler_offset > 0 && tls_handler_offset_reloc > 0) + if __acc_cte (tls_handler_offset > 0 && tls_handler_offset_reloc > 0) rel->add(tls_handler_offset + tls_handler_offset_reloc, reloc_type); 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) rel->add(newaddr + ic, reloc_type); SPAN_S_VAR(tls, const tlsp, mb_otls); // now the relocation entries in the tls data area - for (ic = 0; ic < iv->ivnum; ic += 4) - { - SPAN_S_VAR(upx_byte, pp, otls + (iv->ivarr[ic].start - (tlsp->datastart - imagebase) + sizeof(tls))); - LEXX * const p = (LEXX *) raw_bytes(pp, sizeof(LEXX)); + for (ic = 0; ic < iv->ivnum; ic += 4) { + SPAN_S_VAR(upx_byte, pp, + otls + (iv->ivarr[ic].start - (tlsp->datastart - imagebase) + sizeof(tls))); + LEXX *const p = (LEXX *) raw_bytes(pp, sizeof(LEXX)); cb_value_t kc = *p; - if (kc < tlsp->dataend && kc >= tlsp->datastart) - { - kc += newaddr + sizeof(tls) - tlsp->datastart; + if (kc < tlsp->dataend && kc >= tlsp->datastart) { + kc += newaddr + sizeof(tls) - tlsp->datastart; *p = kc + imagebase; - rel->add(kc,iv->ivarr[ic].len); - } - else - rel->add(kc - imagebase,iv->ivarr[ic].len); + rel->add(kc, iv->ivarr[ic].len); + } else + rel->add(kc - imagebase, iv->ivarr[ic].len); } const unsigned tls_data_size = tlsp->dataend - tlsp->datastart; tlsp->datastart = newaddr + sizeof(tls) + imagebase; tlsp->dataend = tlsp->datastart + tls_data_size; - // NEW: if we have TLS callbacks to handle, we create a pointer to the new callback chain - Stefan Widmann + // 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 + imagebase - 2 * cb_size : 0); - if (use_tls_callbacks) - { + if (use_tls_callbacks) { // set handler offset SPAN_S_VAR(upx_byte, pp, otls); pp = otls + (sotls - 2 * cb_size); - * (LEXX *) raw_bytes(pp, sizeof(LEXX)) = tls_handler_offset + imagebase; + *(LEXX *) raw_bytes(pp, sizeof(LEXX)) = tls_handler_offset + imagebase; pp = otls + (sotls - 1 * cb_size); - * (LEXX *) raw_bytes(pp, sizeof(LEXX)) = 0; // end of one-item list + *(LEXX *) raw_bytes(pp, sizeof(LEXX)) = 0; // end of one-item list // add relocation for TLS handler offset rel->add(newaddr + sotls - 2 * cb_size, reloc_type); } @@ -1477,11 +1373,11 @@ void PeFile::processLoadConf(Interval *iv) // pass 1 return; const unsigned lcaddr = IDADDR(PEDIR_LOADCONF); - const upx_byte * const loadconf = ibuf.subref("bad loadconf %#x", lcaddr, 4); + const upx_byte *const loadconf = ibuf.subref("bad loadconf %#x", lcaddr, 4); soloadconf = get_le32(loadconf); if (soloadconf == 0) return; - static unsigned const MAX_SOLOADCONF = 256; // XXX FIXME: Why? + static unsigned const MAX_SOLOADCONF = 256; // XXX FIXME: Why? if (soloadconf > MAX_SOLOADCONF) info("Load Configuration directory %u > %u", soloadconf, MAX_SOLOADCONF); @@ -1490,29 +1386,27 @@ void PeFile::processLoadConf(Interval *iv) // pass 1 unsigned const take = IDSIZE(PEDIR_RELOC); unsigned const skip = IDADDR(PEDIR_RELOC); Reloc rel(ibuf.subref("bad reloc %#x", skip, take), take); - unsigned pos,type; + unsigned pos, type; while (rel.next(pos, type)) - if (pos >= lcaddr && pos < lcaddr + soloadconf) - { + if (pos >= lcaddr && pos < lcaddr + soloadconf) { iv->add(pos - lcaddr, type); NO_printf("loadconf reloc detected: %x\n", pos); } mb_oloadconf.alloc(soloadconf); - oloadconf = (upx_byte *)mb_oloadconf.getVoidPtr(); + oloadconf = (upx_byte *) mb_oloadconf.getVoidPtr(); memcpy(oloadconf, loadconf, soloadconf); } void PeFile::processLoadConf(Reloc *rel, const Interval *iv, - unsigned newaddr) // pass2 + unsigned newaddr) // pass2 { // now we have the address of the new load config table // so we can create the new relocation entries - for (unsigned ic = 0; ic < iv->ivnum; ic++) - { + for (unsigned ic = 0; ic < iv->ivnum; ic++) { rel->add(iv->ivarr[ic].start + newaddr, iv->ivarr[ic].len); - NO_printf("loadconf reloc added: %x %d\n", - iv->ivarr[ic].start + newaddr, iv->ivarr[ic].len); + NO_printf("loadconf reloc added: %x %d\n", iv->ivarr[ic].start + newaddr, + iv->ivarr[ic].len); } } @@ -1521,127 +1415,93 @@ void PeFile::processLoadConf(Reloc *rel, const Interval *iv, **************************************************************************/ struct alignas(1) PeFile::Resource::res_dir_entry { - LE32 tnl; // Type | Name | Language id - depending on level - LE32 child; + LE32 tnl; // Type | Name | Language id - depending on level + LE32 child; }; struct alignas(1) PeFile::Resource::res_dir { - char _[12]; // flags, timedate, version - LE16 namedentr; - LE16 identr; + char _[12]; // flags, timedate, version + LE16 namedentr; + LE16 identr; - unsigned Sizeof() const { return 16 + sizeof(res_dir_entry)*(namedentr + identr); } + unsigned Sizeof() const { return 16 + sizeof(res_dir_entry) * (namedentr + identr); } res_dir_entry entries[1]; // it's usually safe to assume that every res_dir contains // at least one res_dir_entry - check() complains otherwise }; struct alignas(1) PeFile::Resource::res_data { - LE32 offset; - LE32 size; - char _[8]; // codepage, reserved + LE32 offset; + LE32 size; + char _[8]; // codepage, reserved }; -struct PeFile::Resource::upx_rnode -{ - unsigned id; - upx_byte *name; - upx_rnode *parent; +struct PeFile::Resource::upx_rnode { + unsigned id; + upx_byte *name; + upx_rnode *parent; }; -struct PeFile::Resource::upx_rbranch : public PeFile::Resource::upx_rnode -{ - unsigned nc; - upx_rnode **children; - res_dir data; +struct PeFile::Resource::upx_rbranch : public PeFile::Resource::upx_rnode { + unsigned nc; + upx_rnode **children; + res_dir data; }; -struct PeFile::Resource::upx_rleaf : public PeFile::Resource::upx_rnode -{ - upx_rleaf *next; - unsigned newoffset; - res_data data; +struct PeFile::Resource::upx_rleaf : public PeFile::Resource::upx_rnode { + upx_rleaf *next; + unsigned newoffset; + res_data data; }; -PeFile::Resource::Resource(const upx_byte *ibufstart_, - const upx_byte *ibufend_) : root(nullptr) -{ +PeFile::Resource::Resource(const upx_byte *ibufstart_, const upx_byte *ibufend_) : root(nullptr) { ibufstart = ibufstart_; ibufend = ibufend_; } -PeFile::Resource::Resource(const upx_byte *p, - const upx_byte *ibufstart_, - const upx_byte *ibufend_) -{ +PeFile::Resource::Resource(const upx_byte *p, const upx_byte *ibufstart_, + const upx_byte *ibufend_) { ibufstart = ibufstart_; ibufend = ibufend_; init(p); } -PeFile::Resource::~Resource() -{ - if (root) { destroy(root, 0); root = nullptr; } +PeFile::Resource::~Resource() { + if (root) { + destroy(root, 0); + root = nullptr; + } } -unsigned PeFile::Resource::dirsize() const -{ - return ALIGN_UP(dsize + ssize, 4u); -} +unsigned PeFile::Resource::dirsize() const { return ALIGN_UP(dsize + ssize, 4u); } -bool PeFile::Resource::next() -{ +bool PeFile::Resource::next() { // wow, builtin autorewind... :-) return (current = current ? current->next : head) != nullptr; } -unsigned PeFile::Resource::itype() const -{ - return current->parent->parent->id; -} +unsigned PeFile::Resource::itype() const { return current->parent->parent->id; } -const upx_byte *PeFile::Resource::ntype() const -{ - return current->parent->parent->name; -} +const upx_byte *PeFile::Resource::ntype() const { return current->parent->parent->name; } -unsigned PeFile::Resource::size() const -{ - return ALIGN_UP(current->data.size, 4u); -} +unsigned PeFile::Resource::size() const { return ALIGN_UP(current->data.size, 4u); } -unsigned PeFile::Resource::offs() const -{ - return current->data.offset; -} +unsigned PeFile::Resource::offs() const { return current->data.offset; } -unsigned &PeFile::Resource::newoffs() -{ - return current->newoffset; -} +unsigned &PeFile::Resource::newoffs() { return current->newoffset; } -void PeFile::Resource::dump() const -{ - dump(root,0); -} +void PeFile::Resource::dump() const { dump(root, 0); } -unsigned PeFile::Resource::iname() const -{ - return current->parent->id; -} +unsigned PeFile::Resource::iname() const { return current->parent->id; } -const upx_byte *PeFile::Resource::nname() const -{ - return current->parent->name; -} +const upx_byte *PeFile::Resource::nname() const { return current->parent->name; } /* unsigned ilang() const {return current->id;} const upx_byte *nlang() const {return current->name;} */ -void PeFile::Resource::init(const upx_byte *res) -{ +void PeFile::Resource::init(const upx_byte *res) { COMPILE_TIME_ASSERT(sizeof(res_dir_entry) == 8) COMPILE_TIME_ASSERT(sizeof(res_dir) == 16 + 8) COMPILE_TIME_ASSERT(sizeof(res_data) == 16) @@ -1652,38 +1512,32 @@ void PeFile::Resource::init(const upx_byte *res) start = res; root = head = current = nullptr; dsize = ssize = 0; - check((const res_dir*) start,0); - root = convert(start,nullptr,0); + check((const res_dir *) start, 0); + root = convert(start, nullptr, 0); } -void PeFile::Resource::check(const res_dir *node,unsigned level) -{ +void PeFile::Resource::check(const res_dir *node, unsigned level) { ibufcheck(node, sizeof(*node)); int ic = node->identr + node->namedentr; if (ic == 0) return; - for (const res_dir_entry *rde = node->entries; --ic >= 0; rde++) - { + for (const res_dir_entry *rde = node->entries; --ic >= 0; rde++) { ibufcheck(rde, sizeof(*rde)); if (((rde->child & 0x80000000) == 0) ^ (level == 2)) throwCantPack("unsupported resource structure"); else if (level != 2) - check((const res_dir*) (start + (rde->child & 0x7fffffff)),level + 1); + check((const res_dir *) (start + (rde->child & 0x7fffffff)), level + 1); } } -void PeFile::Resource::ibufcheck(const void *m, unsigned siz) -{ +void PeFile::Resource::ibufcheck(const void *m, unsigned siz) { if (m < ibufstart || m > ibufend - siz) throwCantUnpack("corrupted resources"); } -PeFile::Resource::upx_rnode *PeFile::Resource::convert(const void *rnode, - upx_rnode *parent, - unsigned level) -{ - if (level == 3) - { +PeFile::Resource::upx_rnode *PeFile::Resource::convert(const void *rnode, upx_rnode *parent, + unsigned level) { + if (level == 3) { const res_data *node = ACC_STATIC_CAST(const res_data *, rnode); ibufcheck(node, sizeof(*node)); upx_rleaf *leaf = new upx_rleaf; @@ -1713,37 +1567,33 @@ PeFile::Resource::upx_rnode *PeFile::Resource::convert(const void *rnode, branch->children = New(upx_rnode *, ic); branch->data = *node; - for (const res_dir_entry *rde = node->entries + ic - 1; --ic >= 0; rde--) - { - upx_rnode *child = convert(start + (rde->child & 0x7fffffff),branch,level + 1); + for (const res_dir_entry *rde = node->entries + ic - 1; --ic >= 0; rde--) { + upx_rnode *child = convert(start + (rde->child & 0x7fffffff), branch, level + 1); xcheck(child); branch->children[ic] = child; child->id = rde->tnl; - if (child->id & 0x80000000) - { + if (child->id & 0x80000000) { const upx_byte *p = start + (child->id & 0x7fffffff); ibufcheck(p, 2); const unsigned len = 2 + 2 * get_le16(p); ibufcheck(p, len); child->name = New(upx_byte, len); - memcpy(child->name,p,len); // copy unicode string - ssize += len; // size of unicode strings + memcpy(child->name, p, len); // copy unicode string + ssize += len; // size of unicode strings } } dsize += node->Sizeof(); return branch; } -void PeFile::Resource::build(const upx_rnode *node, unsigned &bpos, - unsigned &spos, unsigned level) -{ - if (level == 3) - { +void PeFile::Resource::build(const upx_rnode *node, unsigned &bpos, unsigned &spos, + unsigned level) { + if (level == 3) { if (bpos + sizeof(res_data) > dirsize()) throwCantUnpack("corrupted resources"); - res_data *l = (res_data*) (newstart + bpos); - const upx_rleaf *leaf = (const upx_rleaf*) node; + res_data *l = (res_data *) (newstart + bpos); + const upx_rleaf *leaf = (const upx_rleaf *) node; *l = leaf->data; if (leaf->newoffset) l->offset = leaf->newoffset; @@ -1753,115 +1603,105 @@ void PeFile::Resource::build(const upx_rnode *node, unsigned &bpos, if (bpos + sizeof(res_dir) > dirsize()) throwCantUnpack("corrupted resources"); - res_dir * const b = (res_dir*) (newstart + bpos); - const upx_rbranch *branch = (const upx_rbranch*) node; + res_dir *const b = (res_dir *) (newstart + bpos); + const upx_rbranch *branch = (const upx_rbranch *) node; *b = branch->data; bpos += b->Sizeof(); res_dir_entry *be = b->entries; - for (unsigned ic = 0; ic < branch->nc; ic++, be++) - { + for (unsigned ic = 0; ic < branch->nc; ic++, be++) { xcheck(branch->children[ic]); be->tnl = branch->children[ic]->id; be->child = bpos + ((level < 2) ? 0x80000000 : 0); const upx_byte *p; - if ((p = branch->children[ic]->name) != nullptr) - { + if ((p = branch->children[ic]->name) != nullptr) { be->tnl = spos + 0x80000000; if (spos + get_le16(p) * 2 + 2 > dirsize()) throwCantUnpack("corrupted resources"); - memcpy(newstart + spos,p,get_le16(p) * 2 + 2); + memcpy(newstart + spos, p, get_le16(p) * 2 + 2); spos += get_le16(p) * 2 + 2; } - build(branch->children[ic],bpos,spos,level + 1); + build(branch->children[ic], bpos, spos, level + 1); } } -upx_byte *PeFile::Resource::build() -{ +upx_byte *PeFile::Resource::build() { mb_start.dealloc(); newstart = nullptr; if (dirsize()) { - mb_start.alloc(dirsize()); - newstart = static_cast(mb_start.getVoidPtr()); - unsigned bpos = 0,spos = dsize; - build(root,bpos,spos,0); + mb_start.alloc(dirsize()); + newstart = static_cast(mb_start.getVoidPtr()); + unsigned bpos = 0, spos = dsize; + build(root, bpos, spos, 0); - // dirsize() is 4 bytes aligned, so we may need to zero - // up to 2 bytes to make valgrind happy - while (spos < dirsize()) - newstart[spos++] = 0; + // dirsize() is 4 bytes aligned, so we may need to zero + // up to 2 bytes to make valgrind happy + while (spos < dirsize()) + newstart[spos++] = 0; } return newstart; } -void PeFile::Resource::destroy(upx_rnode *node,unsigned level) -{ +void PeFile::Resource::destroy(upx_rnode *node, unsigned level) { xcheck(node); - if (level == 3) - { + if (level == 3) { upx_rleaf *leaf = ACC_STATIC_CAST(upx_rleaf *, node); - delete [] leaf->name; leaf->name = nullptr; + delete[] leaf->name; + leaf->name = nullptr; delete leaf; - } - else - { + } else { upx_rbranch *branch = ACC_STATIC_CAST(upx_rbranch *, node); - delete [] branch->name; branch->name = nullptr; - for (int ic = branch->nc; --ic >= 0; ) + delete[] branch->name; + branch->name = nullptr; + for (int ic = branch->nc; --ic >= 0;) destroy(branch->children[ic], level + 1); - delete [] branch->children; branch->children = nullptr; + delete[] branch->children; + branch->children = nullptr; delete branch; } } -static void lame_print_unicode(const upx_byte *p) -{ +static void lame_print_unicode(const upx_byte *p) { for (unsigned ic = 0; ic < get_le16(p); ic++) - printf("%c",(char)p[ic * 2 + 2]); + printf("%c", (char) p[ic * 2 + 2]); } -void PeFile::Resource::dump(const upx_rnode *node,unsigned level) const -{ - if (level) - { +void PeFile::Resource::dump(const upx_rnode *node, unsigned level) const { + if (level) { for (unsigned ic = 1; ic < level; ic++) printf("\t\t"); if (node->name) lame_print_unicode(node->name); else - printf("0x%x",node->id); + printf("0x%x", node->id); printf("\n"); } if (level == 3) return; - const upx_rbranch * const branch = (const upx_rbranch *) node; + const upx_rbranch *const branch = (const upx_rbranch *) node; for (unsigned ic = 0; ic < branch->nc; ic++) - dump(branch->children[ic],level + 1); + dump(branch->children[ic], level + 1); } -void PeFile::Resource::clear(upx_byte *node,unsigned level,Interval *iv) -{ +void PeFile::Resource::clear(upx_byte *node, unsigned level, Interval *iv) { if (level == 3) - iv->add(node,sizeof (res_data)); - else - { - const res_dir * const rd = (res_dir*) node; + iv->add(node, sizeof(res_data)); + else { + const res_dir *const rd = (res_dir *) node; const unsigned n = rd->identr + rd->namedentr; const res_dir_entry *rde = rd->entries; for (unsigned ic = 0; ic < n; ic++, rde++) - clear(newstart + (rde->child & 0x7fffffff),level + 1,iv); - iv->add(rd,rd->Sizeof()); + clear(newstart + (rde->child & 0x7fffffff), level + 1, iv); + iv->add(rd, rd->Sizeof()); } } -bool PeFile::Resource::clear() -{ - newstart = const_cast (start); +bool PeFile::Resource::clear() { + newstart = const_cast(start); Interval iv(newstart); - clear(newstart,0,&iv); + clear(newstart, 0, &iv); iv.flatten(); if (iv.ivnum == 1) iv.clear(); @@ -1872,32 +1712,26 @@ bool PeFile::Resource::clear() return iv.ivnum == 1; } -void PeFile::processResources(Resource *res,unsigned newaddr) -{ +void PeFile::processResources(Resource *res, unsigned newaddr) { if (IDSIZE(PEDIR_RESOURCE) == 0) return; while (res->next()) if (res->newoffs()) res->newoffs() += newaddr; if (res->dirsize()) { - upx_byte *p = res->build(); - memcpy(oresources,p,res->dirsize()); + upx_byte *p = res->build(); + memcpy(oresources, p, res->dirsize()); } } -static bool match(unsigned itype, const unsigned char *ntype, - unsigned iname, const unsigned char *nname, - const char *keep) -{ +static bool match(unsigned itype, const unsigned char *ntype, unsigned iname, + const unsigned char *nname, const char *keep) { // format of string keep: type1[/name1],type2[/name2], .... // typex and namex can be string or number // hopefully resource names do not have '/' or ',' characters inside - struct helper - { - static bool match(unsigned num, const unsigned char *unistr, - const char *mkeep) - { + struct helper { + static bool match(unsigned num, const unsigned char *unistr, const char *mkeep) { if (!unistr) return (unsigned) atoi(mkeep) == num; @@ -1910,12 +1744,10 @@ static bool match(unsigned itype, const unsigned char *ntype, }; // FIXME this comparison is not too exact - for (;;) - { + for (;;) { char const *delim1 = strchr(keep, '/'); char const *delim2 = strchr(keep, ','); - if (helper::match(itype, ntype, keep)) - { + if (helper::match(itype, ntype, keep)) { if (!delim1) return true; if (delim2 && delim2 < delim1) @@ -1931,8 +1763,7 @@ static bool match(unsigned itype, const unsigned char *ntype, return false; } -void PeFile::processResources(Resource *res) -{ +void PeFile::processResources(Resource *res) { const unsigned vaddr = IDADDR(PEDIR_RESOURCE); if ((soresources = IDSIZE(PEDIR_RESOURCE)) == 0) return; @@ -1940,17 +1771,15 @@ void PeFile::processResources(Resource *res) // setup default options for resource compression if (opt->win32_pe.compress_resources < 0) opt->win32_pe.compress_resources = !isefi; - if (!opt->win32_pe.compress_resources) - { + if (!opt->win32_pe.compress_resources) { opt->win32_pe.compress_icons = false; for (int i = 0; i < RT_LAST; i++) opt->win32_pe.compress_rt[i] = false; } - if (opt->win32_pe.compress_rt[RT_STRING] < 0) - { + if (opt->win32_pe.compress_rt[RT_STRING] < 0) { // by default, don't compress RT_STRINGs of screensavers (".scr") opt->win32_pe.compress_rt[RT_STRING] = true; - if (fn_has_ext(fi->getName(),"scr")) + if (fn_has_ext(fi->getName(), "scr")) opt->win32_pe.compress_rt[RT_STRING] = false; } @@ -1967,14 +1796,14 @@ void PeFile::processResources(Resource *res) unsigned iconsin1stdir = 0; if (opt->win32_pe.compress_icons == 2) while (res->next()) // there is no rewind() in Resource - if (res->itype() == RT_GROUP_ICON && iconsin1stdir == 0) - { + if (res->itype() == RT_GROUP_ICON && iconsin1stdir == 0) { iconsin1stdir = get_le16(ibuf.subref("bad resoff %#x", res->offs() + 4, 2)); keep_icons = New(char, 1 + iconsin1stdir * 9); *keep_icons = 0; for (unsigned ic = 0; ic < iconsin1stdir; ic++) - upx_safe_snprintf(keep_icons + strlen(keep_icons), 9, "3/%u,", - get_le16(ibuf.subref("bad resoff %#x", res->offs() + 6 + ic * 14 + 12, 2))); + upx_safe_snprintf( + keep_icons + strlen(keep_icons), 9, "3/%u,", + get_le16(ibuf.subref("bad resoff %#x", res->offs() + 6 + ic * 14 + 12, 2))); if (*keep_icons) keep_icons[strlen(keep_icons) - 1] = 0; } @@ -1995,36 +1824,32 @@ void PeFile::processResources(Resource *res) unsigned unum = 0; unsigned cnum = 0; - while (res->next()) - { + while (res->next()) { const unsigned rtype = res->itype(); bool do_compress = true; if (!opt->win32_pe.compress_resources) do_compress = false; - else if (rtype == RT_ICON) // icon + else if (rtype == RT_ICON) // icon { if (opt->win32_pe.compress_icons == 0) do_compress = false; else if (opt->win32_pe.compress_icons == 1) - if ((first_icon_id == (unsigned) -1 - || first_icon_id == res->iname())) + if ((first_icon_id == (unsigned) -1 || first_icon_id == res->iname())) do_compress = compress_icon; - } - else if (rtype == RT_GROUP_ICON) // icon directory + } else if (rtype == RT_GROUP_ICON) // icon directory do_compress = compress_idir && opt->win32_pe.compress_icons; else if (rtype > 0 && rtype < RT_LAST) do_compress = opt->win32_pe.compress_rt[rtype] ? true : false; if (keep_icons) - do_compress &= !match(res->itype(), res->ntype(), res->iname(), - res->nname(), keep_icons); - do_compress &= !match(res->itype(), res->ntype(), res->iname(), - res->nname(), "TYPELIB,REGISTRY,16"); - do_compress &= !match(res->itype(), res->ntype(), res->iname(), - res->nname(), opt->win32_pe.keep_resource); + do_compress &= + !match(res->itype(), res->ntype(), res->iname(), res->nname(), keep_icons); + do_compress &= + !match(res->itype(), res->ntype(), res->iname(), res->nname(), "TYPELIB,REGISTRY,16"); + do_compress &= !match(res->itype(), res->ntype(), res->iname(), res->nname(), + opt->win32_pe.keep_resource); - if (do_compress) - { + if (do_compress) { csize += res->size(); cnum++; continue; @@ -2033,88 +1858,78 @@ void PeFile::processResources(Resource *res) usize += res->size(); unum++; - set_le32(ores,res->offs()); // save original offset + set_le32(ores, res->offs()); // save original offset ores += 4; unsigned const take = res->size(); ICHECK(ibuf + res->offs(), take); memcpy(ores, ibuf.subref("bad resoff %#x", res->offs(), take), take); ibuf.fill(res->offs(), take, FILLVAL); - res->newoffs() = ptr_diff_bytes(ores,oresources); + res->newoffs() = ptr_diff_bytes(ores, oresources); if (rtype == RT_ICON && opt->win32_pe.compress_icons == 1) compress_icon = true; - else if (rtype == RT_GROUP_ICON) - { - if (opt->win32_pe.compress_icons == 1) - { - icondir_offset = 4 + ptr_diff_bytes(ores,oresources); + else if (rtype == RT_GROUP_ICON) { + if (opt->win32_pe.compress_icons == 1) { + icondir_offset = 4 + ptr_diff_bytes(ores, oresources); icondir_count = get_le16(oresources + icondir_offset); - set_le16(oresources + icondir_offset,1); + set_le16(oresources + icondir_offset, 1); } compress_idir = true; } ores += res->size(); } - soresources = ptr_diff_bytes(ores,oresources); + soresources = ptr_diff_bytes(ores, oresources); delete[] keep_icons; - if (!res->clear()) - { + if (!res->clear()) { // The area occupied by the resource directory is not continuous // so to still support uncompression, I can't zero this area. // This decreases compression ratio, so FIXME somehow. infoWarning("can't remove unneeded resource directory"); } - info("Resources: compressed %u (%u bytes), not compressed %u (%u bytes)",cnum,csize,unum,usize); + info("Resources: compressed %u (%u bytes), not compressed %u (%u bytes)", cnum, csize, unum, + usize); } - -unsigned PeFile::virta2objnum(unsigned addr,SPAN_0(pe_section_t) sect,unsigned objs) -{ +unsigned PeFile::virta2objnum(unsigned addr, SPAN_0(pe_section_t) sect, unsigned objs) { unsigned ic; - for (ic = 0; ic < objs; ic++) - { + for (ic = 0; ic < objs; ic++) { if (sect->vaddr <= addr && sect->vaddr + sect->vsize > addr) return ic; sect++; } - //throwCantPack("virta2objnum() failed"); + // throwCantPack("virta2objnum() failed"); return ic; } - -unsigned PeFile::tryremove (unsigned vaddr,unsigned objs) -{ - unsigned ic = virta2objnum(vaddr,isection,objs); - if (ic && ic == objs - 1) - { - NO_fprintf(stderr,"removed section: %d size: %lx\n",ic,(long)isection[ic].size); - info("removed section: %d size: 0x%lx",ic,(long)isection[ic].size); +unsigned PeFile::tryremove(unsigned vaddr, unsigned objs) { + unsigned ic = virta2objnum(vaddr, isection, objs); + if (ic && ic == objs - 1) { + NO_fprintf(stderr, "removed section: %d size: %lx\n", ic, (long) isection[ic].size); + info("removed section: %d size: 0x%lx", ic, (long) isection[ic].size); objs--; } return objs; } - -unsigned PeFile::stripDebug(unsigned overlaystart) -{ +unsigned PeFile::stripDebug(unsigned overlaystart) { if (IDADDR(PEDIR_DEBUG) == 0) return overlaystart; struct alignas(1) debug_dir_t { - char _[16]; // flags, time/date, version, type - LE32 size; - char __[4]; // rva - LE32 fpos; + char _[16]; // flags, time/date, version, type + LE32 size; + char __[4]; // rva + LE32 fpos; }; COMPILE_TIME_ASSERT(sizeof(debug_dir_t) == 28) COMPILE_TIME_ASSERT_ALIGNED1(debug_dir_t) - COMPILE_TIME_ASSERT(sizeof(((debug_dir_t*)nullptr)->_) == 16) - COMPILE_TIME_ASSERT(sizeof(((debug_dir_t*)nullptr)->__) == 4) + COMPILE_TIME_ASSERT(sizeof(((debug_dir_t *) nullptr)->_) == 16) + COMPILE_TIME_ASSERT(sizeof(((debug_dir_t *) nullptr)->__) == 4) unsigned const take = IDSIZE(PEDIR_DEBUG); unsigned const skip = IDADDR(PEDIR_DEBUG); - const debug_dir_t *dd = (const debug_dir_t*)ibuf.subref("bad debug %#x", skip, take); + const debug_dir_t *dd = (const debug_dir_t *) ibuf.subref("bad debug %#x", skip, take); for (unsigned ic = 0; ic < IDSIZE(PEDIR_DEBUG) / sizeof(debug_dir_t); ic++, dd++) if (overlaystart == dd->fpos) overlaystart += dd->size; @@ -2122,67 +1937,64 @@ unsigned PeFile::stripDebug(unsigned overlaystart) return overlaystart; } - /************************************************************************* // pack **************************************************************************/ -void PeFile::readSectionHeaders(unsigned objs, unsigned sizeof_ih) -{ +void PeFile::readSectionHeaders(unsigned objs, unsigned sizeof_ih) { if (!objs) { return; } mb_isection.alloc(sizeof(pe_section_t) * objs); isection = mb_isection; // => isection now is a SPAN_S - if (file_size_u < pe_offset + sizeof_ih + sizeof(pe_section_t)*objs) { - char buf[32]; snprintf(buf, sizeof(buf), "too many sections %d", objs); + if (file_size_u < pe_offset + sizeof_ih + sizeof(pe_section_t) * objs) { + char buf[32]; + snprintf(buf, sizeof(buf), "too many sections %d", objs); throwCantPack(buf); } - fi->seek(pe_offset+sizeof_ih,SEEK_SET); - fi->readx(isection,sizeof(pe_section_t)*objs); + fi->seek(pe_offset + sizeof_ih, SEEK_SET); + fi->readx(isection, sizeof(pe_section_t) * objs); rvamin = isection[0].vaddr; - unsigned const rvalast = isection[-1+ objs].vsize + isection[-1+ objs].vaddr; - for (unsigned j=0; j < objs; ++j) { // expect: first is min, last is max + unsigned const rvalast = isection[-1 + objs].vsize + isection[-1 + objs].vaddr; + for (unsigned j = 0; j < objs; ++j) { // expect: first is min, last is max unsigned lo = isection[j].vaddr, hi = isection[j].vsize + lo; if (hi < lo) { // this checks first and last sections, too! - char buf[64]; snprintf(buf, sizeof(buf), - "bad section[%d] wrap-around %#x %#x", j, lo, hi - lo); + char buf[64]; + snprintf(buf, sizeof(buf), "bad section[%d] wrap-around %#x %#x", j, lo, hi - lo); throwCantPack(buf); } if (lo < rvamin) { - char buf[64]; snprintf(buf, sizeof(buf), - "bad section .rva [%d] %#x < [0] %#x", j, lo, rvamin); + char buf[64]; + snprintf(buf, sizeof(buf), "bad section .rva [%d] %#x < [0] %#x", j, lo, rvamin); throwCantPack(buf); } if (rvalast < hi) { - char buf[80]; snprintf(buf, sizeof(buf), - "bad section .rva+.vsize [%d] %#x > [%d] %#x", j, hi, - (-1+ objs), rvalast); + char buf[80]; + snprintf(buf, sizeof(buf), "bad section .rva+.vsize [%d] %#x > [%d] %#x", j, hi, + (-1 + objs), rvalast); throwCantPack(buf); } } - infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs); + infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), + objs); } -void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask, - unsigned ih_entry, unsigned ih_filealign) -{ - if ((1u << subsystem) & ~mask) - { +void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask, unsigned ih_entry, + unsigned ih_filealign) { + if ((1u << subsystem) & ~mask) { char buf[100]; - upx_safe_snprintf(buf, sizeof(buf), "PE: subsystem %u is not supported", - subsystem); + upx_safe_snprintf(buf, sizeof(buf), "PE: subsystem %u is not supported", subsystem); throwCantPack(buf); } - //check CLR Runtime Header directory entry + // check CLR Runtime Header directory entry if (IDSIZE(PEDIR_COMRT)) throwCantPack(".NET files are not yet supported"); if (isection == nullptr) throwCantPack("No section was found"); - if (memcmp(isection[0].name,"UPX",3) == 0) + if (memcmp(isection[0].name, "UPX", 3) == 0) throwAlreadyPackedByUPX(); if (!opt->force && IDSIZE(15)) @@ -2192,38 +2004,33 @@ void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask, throwCantPack("run a virus scanner on this file!"); const unsigned fam1 = ih_filealign - 1; - if (!(1+ fam1) || (1+ fam1) & fam1) { // ih_filealign is not a power of 2 - char buf[32]; snprintf(buf, sizeof(buf), "bad file alignment %#x", 1+ fam1); + if (!(1 + fam1) || (1 + fam1) & fam1) { // ih_filealign is not a power of 2 + char buf[32]; + snprintf(buf, sizeof(buf), "bad file alignment %#x", 1 + fam1); throwCantPack(buf); } } -unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase, - upx_uint64_t default_imagebase, - LE16 &dllflags) -{ - if (opt->win32_pe.strip_relocs < 0) - { +unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase, upx_uint64_t default_imagebase, + LE16 &dllflags) { + if (opt->win32_pe.strip_relocs < 0) { if (isdll || isefi || dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) opt->win32_pe.strip_relocs = false; else opt->win32_pe.strip_relocs = ih_imagebase >= default_imagebase; } - if (opt->win32_pe.strip_relocs) - { + if (opt->win32_pe.strip_relocs) { if (isdll || isefi) throwCantPack("--strip-relocs is not allowed with DLL and EFI images"); - if (dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) - { + if (dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) { if (opt->force) // Disable ASLR { // The bit is set, so clear it with XOR dllflags ^= IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; // HIGH_ENTROPY_VA has no effect without DYNAMIC_BASE, so clear // it also if set - dllflags &= ~(unsigned)IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA; - } - else + dllflags &= ~(unsigned) IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA; + } else throwCantPack("--strip-relocs is not allowed with ASLR (use " "with --force to remove)"); } @@ -2231,55 +2038,48 @@ unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase, throwCantPack("--strip-relocs may not support this imagebase (try " "with --force)"); return RELOCS_STRIPPED; - } - else + } else info("Base relocations stripping is disabled for this image"); return 0; } -static unsigned umax(unsigned a, unsigned b) -{ - return (a >= b) ? a : b; -} +static unsigned umax(unsigned a, unsigned b) { return (a >= b) ? a : b; } -unsigned PeFile::readSections(unsigned objs, unsigned usize, - unsigned ih_filealign, unsigned ih_datasize) -{ - const unsigned xtrasize = UPX_MAX(ih_datasize, 65536u) + IDSIZE(PEDIR_IMPORT) - + IDSIZE(PEDIR_BOUNDIM) + IDSIZE(PEDIR_IAT) + IDSIZE(PEDIR_DELAYIMP) - + IDSIZE(PEDIR_RELOC); +unsigned PeFile::readSections(unsigned objs, unsigned usize, unsigned ih_filealign, + unsigned ih_datasize) { + const unsigned xtrasize = UPX_MAX(ih_datasize, 65536u) + IDSIZE(PEDIR_IMPORT) + + IDSIZE(PEDIR_BOUNDIM) + IDSIZE(PEDIR_IAT) + IDSIZE(PEDIR_DELAYIMP) + + IDSIZE(PEDIR_RELOC); ibuf.alloc(usize + xtrasize); // BOUND IMPORT support. FIXME: is this ok? ibufgood = isection[0].rawdataptr; - fi->seek(0,SEEK_SET); + fi->seek(0, SEEK_SET); fi->readx(ibuf, ibufgood); - //Interval holes(ibuf); + // Interval holes(ibuf); - unsigned ic,jc,overlaystart = 0; + unsigned ic, jc, overlaystart = 0; ibuf.clear(0, usize); - for (ic = jc = 0; ic < objs; ic++) - { + for (ic = jc = 0; ic < objs; ic++) { if (isection[ic].rawdataptr && overlaystart < isection[ic].rawdataptr + isection[ic].size) - overlaystart = ALIGN_UP(isection[ic].rawdataptr + isection[ic].size,ih_filealign); + overlaystart = ALIGN_UP(isection[ic].rawdataptr + isection[ic].size, ih_filealign); if (isection[ic].vsize == 0) isection[ic].vsize = isection[ic].size; - if ((isection[ic].flags & PEFL_BSS) || isection[ic].rawdataptr == 0 - || (isection[ic].flags & PEFL_INFO)) - { - //holes.add(isection[ic].vaddr,isection[ic].vsize); + if ((isection[ic].flags & PEFL_BSS) || isection[ic].rawdataptr == 0 || + (isection[ic].flags & PEFL_INFO)) { + // holes.add(isection[ic].vaddr,isection[ic].vsize); continue; } if (isection[ic].vaddr + isection[ic].size > usize) throwCantPack("section size problem"); - if (!isrtm && ((isection[ic].flags & (PEFL_WRITE|PEFL_SHARED)) - == (PEFL_WRITE|PEFL_SHARED))) + if (!isrtm && + ((isection[ic].flags & (PEFL_WRITE | PEFL_SHARED)) == (PEFL_WRITE | PEFL_SHARED))) if (!opt->force) throwCantPack("writable shared sections not supported (try --force)"); if (jc && isection[ic].rawdataptr - jc > ih_filealign && !opt->force) throwCantPack("superfluous data between sections (try --force)"); - fi->seek(isection[ic].rawdataptr,SEEK_SET); + fi->seek(isection[ic].rawdataptr, SEEK_SET); jc = isection[ic].size; if (jc > isection[ic].vsize) jc = isection[ic].vsize; @@ -2288,20 +2088,17 @@ unsigned PeFile::readSections(unsigned objs, unsigned usize, if (isection[ic].vaddr + jc > ibuf.getSize()) throwInternalError("buffer too small 1"); fi->readx(ibuf.subref("bad section %#x", isection[ic].vaddr, jc), jc); - ibufgood= umax(ibufgood, jc + isection[ic].vaddr); // FIXME: simplistic + ibufgood = umax(ibufgood, jc + isection[ic].vaddr); // FIXME: simplistic jc += isection[ic].rawdataptr; } return overlaystart; } -void PeFile::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase) -{ - compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy, - ih_codebase, rvamin, 0, nullptr, 0); +void PeFile::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase) { + compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy, ih_codebase, rvamin, 0, nullptr, 0); } -void PeFile::callProcessRelocs(Reloc &rel, unsigned &ic) -{ +void PeFile::callProcessRelocs(Reloc &rel, unsigned &ic) { // wince wants relocation data at the beginning of a section PeFile::processRelocs(&rel); ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; @@ -2309,20 +2106,17 @@ void PeFile::callProcessRelocs(Reloc &rel, unsigned &ic) ic += soxrelocs; } -void PeFile::callProcessResources(Resource &res, unsigned &ic) -{ +void PeFile::callProcessResources(Resource &res, unsigned &ic) { if (soresources) - processResources(&res,ic); + processResources(&res, ic); ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0; ODSIZE(PEDIR_RESOURCE) = soresources; ic += soresources; } template -void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, - unsigned subsystem_mask, upx_uint64_t default_imagebase, - bool last_section_rsrc_only) -{ +void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, + upx_uint64_t default_imagebase, bool last_section_rsrc_only) { // FIXME: we need to think about better support for --exact if (opt->exact) throwCantPackExact(); @@ -2332,16 +2126,15 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, if (!opt->force && handleForceOption()) throwCantPack("unexpected value in PE header (try --force)"); - if (ih.dllflags & IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY) - { + if (ih.dllflags & IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY) { if (opt->force) - ih.dllflags &= ~(unsigned)IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY; + ih.dllflags &= ~(unsigned) IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY; else throwCantPack("image forces integrity check (use --force to remove)"); } checkHeaderValues(ih.subsystem, subsystem_mask, ih.entry, ih.filealign); - //remove certificate directory entry + // remove certificate directory entry if (IDSIZE(PEDIR_SEC)) IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0; @@ -2360,34 +2153,30 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, // and small file alignment benefits from extra space unsigned char stub[0x40]; memset(stub, 0, sizeof(stub)); - set_le16(stub, 'M' + 'Z'*256); + set_le16(stub, 'M' + 'Z' * 256); set_le32(stub + sizeof(stub) - sizeof(LE32), sizeof(stub)); fo->write(stub, sizeof(stub)); pe_offset = sizeof(stub); } else - handleStub(fi,fo,pe_offset); + handleStub(fi, fo, pe_offset); unsigned overlaystart = readSections(objs, ih.imagesize, ih.filealign, ih.datasize); unsigned overlay = file_size - stripDebug(overlaystart); if (overlay >= (unsigned) file_size) overlay = 0; checkOverlay(overlay); - if (ih.dllflags & IMAGE_DLLCHARACTERISTICS_CONTROL_FLOW_GUARD) - { - if (opt->force) - { + if (ih.dllflags & IMAGE_DLLCHARACTERISTICS_CONTROL_FLOW_GUARD) { + if (opt->force) { const unsigned lcsize = IDSIZE(PEDIR_LOADCONF); const unsigned lcaddr = IDADDR(PEDIR_LOADCONF); - const unsigned gfpos = 14 * sizeof(ih.imagebase) + - 6 * sizeof(LE32) + 4 * sizeof(LE16); + const unsigned gfpos = 14 * sizeof(ih.imagebase) + 6 * sizeof(LE32) + 4 * sizeof(LE16); if (lcaddr && lcsize >= gfpos + sizeof(LE32)) // GuardFlags: Set IMAGE_GUARD_SECURITY_COOKIE_UNUSED // and clear the rest - set_le32(ibuf.subref("bad guard flags at %#x", lcaddr + gfpos, - sizeof(LE32)), 0x00000800); + set_le32(ibuf.subref("bad guard flags at %#x", lcaddr + gfpos, sizeof(LE32)), + 0x00000800); ih.dllflags ^= IMAGE_DLLCHARACTERISTICS_CONTROL_FLOW_GUARD; - } - else + } else throwCantPack("CFGuard enabled PE files are not supported (use " "--force to disable)"); } @@ -2395,7 +2184,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, Resource res(ibuf, ibuf + ibuf.getSize()); Interval tlsiv(ibuf); Interval loadconfiv(ibuf); - Export xport((char*)(unsigned char*)ibuf); + Export xport((char *) (unsigned char *) ibuf); const unsigned dllstrings = processImports(); processTls(&tlsiv); // call before processRelocs!! @@ -2404,71 +2193,69 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, processExports(&xport); processRelocs(); - //OutputFile::dump("x1", ibuf, usize); + // OutputFile::dump("x1", ibuf, usize); // some checks for broken linkers - disable filter if necessary bool allow_filter = true; if (/*FIXME ih.codebase == ih.database - ||*/ ih.codebase + ih.codesize > ih.imagesize - || (isection[virta2objnum(ih.codebase,isection,objs)].flags & PEFL_CODE) == 0) + ||*/ ih.codebase + ih.codesize > ih.imagesize || + (isection[virta2objnum(ih.codebase, isection, objs)].flags & PEFL_CODE) == 0) allow_filter = false; const unsigned oam1 = ih.objectalign - 1; - if (!(1+ oam1) || (1+ oam1) & oam1) { // ih.objectalign is not a power of 2 - char buf[32]; snprintf(buf, sizeof(buf), "bad object alignment %#x", 1+ oam1); + if (!(1 + oam1) || (1 + oam1) & oam1) { // ih.objectalign is not a power of 2 + char buf[32]; + snprintf(buf, sizeof(buf), "bad object alignment %#x", 1 + oam1); throwCantPack(buf); } // FIXME: if the last object has a bss then this won't work // newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1; // temporary solution: - unsigned newvsize = (isection[objs-1].vaddr + isection[objs-1].vsize + oam1) &~ oam1; + unsigned newvsize = (isection[objs - 1].vaddr + isection[objs - 1].vsize + oam1) & ~oam1; - NO_fprintf(stderr,"newvsize=%x objs=%d\n",newvsize,objs); + NO_fprintf(stderr, "newvsize=%x objs=%d\n", newvsize, objs); if (newvsize + soimport + sorelocs > ibuf.getSize()) - throwInternalError("buffer too small 2"); - memcpy(ibuf+newvsize,oimport,soimport); - memcpy(ibuf+newvsize+soimport,orelocs,sorelocs); + throwInternalError("buffer too small 2"); + memcpy(ibuf + newvsize, oimport, soimport); + memcpy(ibuf + newvsize + soimport, orelocs, sorelocs); - cimports = newvsize - rvamin; // rva of preprocessed imports - crelocs = cimports + soimport; // rva of preprocessed fixups + cimports = newvsize - rvamin; // rva of preprocessed imports + crelocs = cimports + soimport; // rva of preprocessed fixups ph.u_len = newvsize + soimport + sorelocs; // some extra data for uncompression support unsigned s = 0; - upx_byte * const p1 = ibuf.subref("bad ph.u_len %#x", ph.u_len, sizeof(ih)); - memcpy(p1 + s,&ih,sizeof (ih)); - s += sizeof (ih); - memcpy(p1 + s,isection,ih.objects * sizeof(*isection)); + upx_byte *const p1 = ibuf.subref("bad ph.u_len %#x", ph.u_len, sizeof(ih)); + memcpy(p1 + s, &ih, sizeof(ih)); + s += sizeof(ih); + memcpy(p1 + s, isection, ih.objects * sizeof(*isection)); s += ih.objects * sizeof(*isection); - if (soimport) - { - set_le32(p1 + s,cimports); - set_le32(p1 + s + 4,dllstrings); + if (soimport) { + set_le32(p1 + s, cimports); + set_le32(p1 + s + 4, dllstrings); s += 8; } - if (sorelocs) - { - set_le32(p1 + s,crelocs); + if (sorelocs) { + set_le32(p1 + s, crelocs); p1[s + 4] = (unsigned char) (big_relocs & 6); s += 5; } - if (soresources) - { - set_le16(p1 + s,icondir_count); + if (soresources) { + set_le16(p1 + s, icondir_count); s += 2; } // end of extra data - set_le32(p1 + s,ptr_diff_bytes(p1,ibuf) - rvamin); + set_le32(p1 + s, ptr_diff_bytes(p1, ibuf) - rvamin); s += 4; ph.u_len += s; obuf.allocForCompression(ph.u_len); // prepare packheader if (ph.u_len < rvamin) { // readSectionHeaders() should have caught this - char buf[64]; snprintf(buf, sizeof(buf), - "bad PE header ph.u_len=%#x rvamin=%#x", ph.u_len, rvamin); + char buf[64]; + snprintf(buf, sizeof(buf), "bad PE header ph.u_len=%#x rvamin=%#x", ph.u_len, rvamin); throwInternalError(buf); } ph.u_len -= rvamin; @@ -2480,29 +2267,29 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, int filter_strategy = allow_filter ? 0 : -3; // disable filters for files with broken headers - if (ih.codebase + ih.codesize > ph.u_len) - { + if (ih.codebase + ih.codesize > ph.u_len) { ft.buf_len = 1; filter_strategy = -3; } callCompressWithFilters(ft, filter_strategy, ih.codebase); -// info: see buildLoader() - newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; - if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4) + // info: see buildLoader() + newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) & ~oam1; + if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) & ~oam1) > tlsindex + 4) tlsindex = 0; const int oh_filealign = UPX_MIN(ih.filealign, 0x200); const unsigned fam1 = oh_filealign - 1; int identsize = 0; - const unsigned codesize = getLoaderSection("IDENTSTR",&identsize); + const unsigned codesize = getLoaderSection("IDENTSTR", &identsize); assert(identsize > 0); unsigned ic; - getLoaderSection("UPX1HEAD",(int*)&ic); + getLoaderSection("UPX1HEAD", (int *) &ic); identsize += ic; - const bool has_oxrelocs = !opt->win32_pe.strip_relocs && (use_stub_relocs || sotls || loadconfiv.ivnum); + const bool has_oxrelocs = + !opt->win32_pe.strip_relocs && (use_stub_relocs || sotls || loadconfiv.ivnum); const bool has_ncsection = has_oxrelocs || soimpdlls || soexport || soresources; const unsigned oobjs = last_section_rsrc_only ? 4 : has_ncsection ? 3 : 2; ////pe_section_t osection[oobjs]; @@ -2528,23 +2315,25 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, identsplit = ALIGN_GAP(identsplit, oh_filealign); ic = identsize - identsplit; - 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); - const unsigned aligned_sotls = ALIGN_UP(sotls, (unsigned)sizeof(LEXX)); - const unsigned s1size = ALIGN_UP(ic + c_len + codesize, (unsigned) sizeof(LEXX)) + aligned_sotls + soloadconf; - const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1; + const unsigned aligned_sotls = ALIGN_UP(sotls, (unsigned) sizeof(LEXX)); + const unsigned s1size = + ALIGN_UP(ic + c_len + codesize, (unsigned) sizeof(LEXX)) + aligned_sotls + soloadconf; + const unsigned s1addr = (newvsize - (ic + c_len) + oam1) & ~oam1; - const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1; + const unsigned ncsection = (s1addr + s1size + oam1) & ~oam1; const unsigned upxsection = s1addr + ic + c_len; Reloc rel(1024); // new relocations are put here addNewRelocations(rel, upxsection); // new PE header - memcpy(&oh,&ih,sizeof(oh)); + memcpy(&oh, &ih, sizeof(oh)); oh.filealign = oh_filealign; // identsplit depends on this - memset(osection,0,sizeof(osection)); + memset(osection, 0, sizeof(osection)); oh.entry = upxsection; oh.objects = oobjs; @@ -2564,7 +2353,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, if (use_tls_callbacks) tls_handler_offset = linker->getSymbolOffset("PETLSC2") + upxsection; - processTls(&rel,&tlsiv,ic); + processTls(&rel, &tlsiv, ic); ODADDR(PEDIR_TLS) = aligned_sotls ? ic : 0; ODSIZE(PEDIR_TLS) = aligned_sotls ? (sizeof(LEXX) == 4 ? 0x18 : 0x28) : 0; ic += aligned_sotls; @@ -2587,11 +2376,10 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, ODSIZE(PEDIR_IMPORT) = soimpdlls; ic += soimpdlls; - processExports(&xport,ic); + processExports(&xport, ic); ODADDR(PEDIR_EXPORT) = soexport ? ic : 0; ODSIZE(PEDIR_EXPORT) = soexport; - if (!isdll && opt->win32_pe.compress_exports) - { + if (!isdll && opt->win32_pe.compress_exports) { ODADDR(PEDIR_EXPORT) = IDADDR(PEDIR_EXPORT); ODSIZE(PEDIR_EXPORT) = IDSIZE(PEDIR_EXPORT); } @@ -2601,21 +2389,20 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, callProcessRelocs(rel, ic); // when the resource is put alone into section 3 - const unsigned res_start = (ic + oam1) &~ oam1; + const unsigned res_start = (ic + oam1) & ~oam1; if (last_section_rsrc_only) callProcessResources(res, ic = res_start); - defineSymbols(ncsection, upxsection, sizeof(oh), - identsize - identsplit, s1addr); + defineSymbols(ncsection, upxsection, sizeof(oh), identsize - identsplit, s1addr); defineFilterSymbols(&ft); relocateLoader(); const unsigned lsize = getLoaderSize(); MemBuffer loader(lsize); - memcpy(loader,getLoader(),lsize); + memcpy(loader, getLoader(), lsize); patchPackHeader(loader, lsize); - const unsigned ncsize = soxrelocs + soimpdlls + soexport - + (!last_section_rsrc_only ? soresources : 0); + const unsigned ncsize = + soxrelocs + soimpdlls + soexport + (!last_section_rsrc_only ? soresources : 0); assert((soxrelocs == 0) == !has_oxrelocs); assert((ncsize == 0) == !has_ncsection); @@ -2625,8 +2412,8 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, const unsigned ncsize_virt_increase = soxrelocs && (ncsize & oam1) == 0 ? 8 : 0; // fill the sections - strcpy(osection[0].name,"UPX0"); - strcpy(osection[1].name,"UPX1"); + strcpy(osection[0].name, "UPX0"); + strcpy(osection[1].name, "UPX1"); // after some windoze debugging I found that the name of the sections // DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS) // and because of this lame dll, the resource stuff must be the @@ -2642,49 +2429,44 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, osection[2].vaddr = ncsection; osection[0].size = 0; - osection[1].size = (s1size + fam1) &~ fam1; - osection[2].size = (ncsize + fam1) &~ fam1; + osection[1].size = (s1size + fam1) & ~fam1; + osection[2].size = (ncsize + fam1) & ~fam1; osection[0].vsize = osection[1].vaddr - osection[0].vaddr; - if (!last_section_rsrc_only) - { - osection[1].vsize = (osection[1].size + oam1) &~ oam1; - osection[2].vsize = (osection[2].size + ncsize_virt_increase + oam1) &~ oam1; + if (!last_section_rsrc_only) { + osection[1].vsize = (osection[1].size + oam1) & ~oam1; + osection[2].vsize = (osection[2].size + ncsize_virt_increase + oam1) & ~oam1; oh.imagesize = osection[2].vaddr + osection[2].vsize; - osection[0].rawdataptr = (pe_offset + sizeof(ht) + sizeof_osection + fam1) &~ (size_t)fam1; + osection[0].rawdataptr = (pe_offset + sizeof(ht) + sizeof_osection + fam1) & ~(size_t) fam1; osection[1].rawdataptr = osection[0].rawdataptr; - } - else - { + } else { osection[1].vsize = osection[1].size; osection[2].vsize = osection[2].size; osection[0].rawdataptr = 0; - osection[1].rawdataptr = (pe_offset + sizeof(ht) + sizeof_osection + fam1) &~ (size_t)fam1; + osection[1].rawdataptr = (pe_offset + sizeof(ht) + sizeof_osection + fam1) & ~(size_t) fam1; } osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size; - osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ); - osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ); - osection[2].flags = (unsigned) (PEFL_DATA|PEFL_WRITE|PEFL_READ); + osection[0].flags = (unsigned) (PEFL_BSS | PEFL_EXEC | PEFL_WRITE | PEFL_READ); + osection[1].flags = (unsigned) (PEFL_DATA | PEFL_EXEC | PEFL_WRITE | PEFL_READ); + osection[2].flags = (unsigned) (PEFL_DATA | PEFL_WRITE | PEFL_READ); - if (last_section_rsrc_only) - { + if (last_section_rsrc_only) { strcpy(osection[3].name, ".rsrc"); osection[3].vaddr = res_start; - osection[3].size = (soresources + fam1) &~ fam1; + osection[3].size = (soresources + fam1) & ~fam1; osection[3].vsize = osection[3].size; osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size; - osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ); - osection[3].flags = (unsigned) (PEFL_DATA|PEFL_READ); - oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) &~ oam1; - if (soresources == 0) - { + osection[2].flags = (unsigned) (PEFL_DATA | PEFL_READ); + osection[3].flags = (unsigned) (PEFL_DATA | PEFL_READ); + oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) & ~oam1; + if (soresources == 0) { oh.objects = 3; memset(&osection[3], 0, sizeof(osection[3])); } } - oh.bsssize = osection[0].vsize; + oh.bsssize = osection[0].vsize; oh.datasize = osection[2].vsize + (oobjs > 3 ? osection[3].vsize : 0); setOhDataBase(osection); oh.codesize = osection[1].vsize; @@ -2696,30 +2478,29 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, if (opt->win32_pe.strip_relocs) oh.flags |= RELOCS_STRIPPED; - //for (ic = 0; ic < oh.filealign; ic += 4) - // set_le32(ibuf + ic,get_le32("UPX ")); + // for (ic = 0; ic < oh.filealign; ic += 4) + // set_le32(ibuf + ic,get_le32("UPX ")); ibuf.clear(0, oh.filealign); - info("Image size change: %u -> %u KiB", - ih.imagesize / 1024, oh.imagesize / 1024); + info("Image size change: %u -> %u KiB", ih.imagesize / 1024, oh.imagesize / 1024); infoHeader("[Writing compressed file]"); // write loader + compressed file - fo->write(&oh,sizeof(oh)); - fo->write(osection,sizeof(osection[0])*oobjs); + fo->write(&oh, sizeof(oh)); + fo->write(osection, sizeof(osection[0]) * oobjs); // some alignment - if (identsplit == identsize) - { - unsigned n = osection[!last_section_rsrc_only ? 0 : 1].rawdataptr - fo->getBytesWritten() - identsize; + if (identsplit == identsize) { + unsigned n = osection[!last_section_rsrc_only ? 0 : 1].rawdataptr - fo->getBytesWritten() - + identsize; assert(n <= oh.filealign); fo->write(ibuf, n); } - fo->write(loader + codesize,identsize); + fo->write(loader + codesize, identsize); infoWriting("loader", fo->getBytesWritten()); - fo->write(obuf,c_len); + fo->write(obuf, c_len); infoWriting("compressed data", c_len); - fo->write(loader,codesize); + fo->write(loader, codesize); if (opt->debug.dump_stub_loader) OutputFile::dump(opt->debug.dump_stub_loader, loader, codesize); if ((ic = fo->getBytesWritten() & (sizeof(LEXX) - 1)) != 0) @@ -2727,24 +2508,23 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, fo->write(raw_bytes(otls, aligned_sotls), aligned_sotls); fo->write(oloadconf, soloadconf); if ((ic = fo->getBytesWritten() & fam1) != 0) - fo->write(ibuf,oh.filealign - ic); + fo->write(ibuf, oh.filealign - ic); if (!last_section_rsrc_only) - fo->write(raw_bytes(oresources, soresources) ,soresources); + fo->write(raw_bytes(oresources, soresources), soresources); else - fo->write(oxrelocs,soxrelocs); - fo->write(oimpdlls,soimpdlls); + fo->write(oxrelocs, soxrelocs); + fo->write(oimpdlls, soimpdlls); fo->write(raw_bytes(oexport, soexport), soexport); if (!last_section_rsrc_only) - fo->write(oxrelocs,soxrelocs); + fo->write(oxrelocs, soxrelocs); if ((ic = fo->getBytesWritten() & fam1) != 0) - fo->write(ibuf,oh.filealign - ic); + fo->write(ibuf, oh.filealign - ic); - if (last_section_rsrc_only) - { - fo->write(raw_bytes(oresources, soresources) ,soresources); + if (last_section_rsrc_only) { + fo->write(raw_bytes(oresources, soresources), soresources); if ((ic = fo->getBytesWritten() & fam1) != 0) - fo->write(ibuf,oh.filealign - ic); + fo->write(ibuf, oh.filealign - ic); } #if 0 @@ -2777,9 +2557,8 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, // unpack **************************************************************************/ -void PeFile::rebuildRelocs(SPAN_S(upx_byte) & extrainfo, unsigned bits, - unsigned flags, upx_uint64_t imagebase) -{ +void PeFile::rebuildRelocs(SPAN_S(upx_byte) & extrainfo, unsigned bits, unsigned flags, + upx_uint64_t imagebase) { assert(bits == 32 || bits == 64); if (!ODADDR(PEDIR_RELOC) || !ODSIZE(PEDIR_RELOC) || (flags & RELOCS_STRIPPED)) return; @@ -2796,9 +2575,9 @@ void PeFile::rebuildRelocs(SPAN_S(upx_byte) & extrainfo, unsigned bits, extrainfo += 5; MemBuffer mb_wrkmem; - unsigned relocn = unoptimizeReloc(rdata,obuf,mb_wrkmem,true,bits); + unsigned relocn = unoptimizeReloc(rdata, obuf, mb_wrkmem, true, bits); unsigned r16 = 0; - if (big & 6) // 16 bit relocations + if (big & 6) // 16 bit relocations { SPAN_S_VAR(const LE32, q, (const LE32 *) raw_bytes(rdata, 0), obuf); while (*q++) @@ -2809,20 +2588,18 @@ void PeFile::rebuildRelocs(SPAN_S(upx_byte) & extrainfo, unsigned bits, } Reloc rel(relocn + r16); - if (big & 6) - { + if (big & 6) { SPAN_S_VAR(LE32, q, (LE32 *) raw_bytes(rdata, 0), obuf); while (*q) - rel.add(*q++ + rvamin,(big & 4) ? 2 : 1); + rel.add(*q++ + rvamin, (big & 4) ? 2 : 1); if ((big & 6) == 6) while (*++q) - rel.add(*q + rvamin,1); + rel.add(*q + rvamin, 1); // rdata = (upx_byte *) raw_bytes(q, 0); // ??? } SPAN_S_VAR(upx_byte, const wrkmem, mb_wrkmem); - for (unsigned ic = 0; ic < relocn; ic++) - { + for (unsigned ic = 0; ic < relocn; ic++) { OPTR_I(upx_byte, p, obuf + get_le32(wrkmem + 4 * ic)); if (bits == 32) set_le32(p, get_le32(p) + imagebase + rvamin); @@ -2830,34 +2607,32 @@ void PeFile::rebuildRelocs(SPAN_S(upx_byte) & extrainfo, unsigned bits, set_le64(p, get_le64(p) + imagebase + rvamin); rel.add(rvamin + get_le32(wrkmem + 4 * ic), bits == 32 ? 3 : 10); } - rel.finish (oxrelocs,soxrelocs); + rel.finish(oxrelocs, soxrelocs); omemcpy(obuf + (ODADDR(PEDIR_RELOC) - rvamin), oxrelocs, soxrelocs); - delete [] oxrelocs; oxrelocs = nullptr; + delete[] oxrelocs; + oxrelocs = nullptr; mb_wrkmem.dealloc(); ODSIZE(PEDIR_RELOC) = soxrelocs; } -void PeFile::rebuildExports() -{ +void PeFile::rebuildExports() { if (ODSIZE(PEDIR_EXPORT) == 0 || ODADDR(PEDIR_EXPORT) == IDADDR(PEDIR_EXPORT)) return; // nothing to do opt->win32_pe.compress_exports = 0; - Export xport((char*)(unsigned char*) ibuf - isection[2].vaddr); + Export xport((char *) (unsigned char *) ibuf - isection[2].vaddr); processExports(&xport); - processExports(&xport,ODADDR(PEDIR_EXPORT)); + processExports(&xport, ODADDR(PEDIR_EXPORT)); omemcpy(obuf + (ODADDR(PEDIR_EXPORT) - rvamin), oexport, soexport); } -void PeFile::rebuildTls() -{ +void PeFile::rebuildTls() { // this is an easy one : just do nothing ;-) } -void PeFile::rebuildResources(SPAN_S(upx_byte) & extrainfo, unsigned lastvaddr) -{ +void PeFile::rebuildResources(SPAN_S(upx_byte) & extrainfo, unsigned lastvaddr) { if (ODSIZE(PEDIR_RESOURCE) == 0 || IDSIZE(PEDIR_RESOURCE) == 0) return; @@ -2873,33 +2648,28 @@ void PeFile::rebuildResources(SPAN_S(upx_byte) & extrainfo, unsigned lastvaddr) const upx_byte *r = ibuf.raw_bytes(0) - lastvaddr; Resource res(r + vaddr, ibuf, ibuf + ibuf.getSize()); while (res.next()) - if (res.offs() > vaddr) - { + if (res.offs() > vaddr) { ICHECK(r + res.offs() - 4, 4); unsigned origoffs = get_le32(r + res.offs() - 4); res.newoffs() = origoffs; omemcpy(obuf + (origoffs - rvamin), r + res.offs(), res.size()); - if (icondir_count && res.itype() == RT_GROUP_ICON) - { + if (icondir_count && res.itype() == RT_GROUP_ICON) { set_le16(obuf + (origoffs - rvamin + 4), icondir_count); icondir_count = 0; } } if (res.dirsize()) { - upx_byte *p = res.build(); - OCHECK(obuf + (ODADDR(PEDIR_RESOURCE) - rvamin), 16); - // write back when the original is zeroed - if (get_le32(obuf + (ODADDR(PEDIR_RESOURCE) - rvamin + 12)) == 0) - omemcpy(obuf + (ODADDR(PEDIR_RESOURCE) - rvamin), p, res.dirsize()); + upx_byte *p = res.build(); + OCHECK(obuf + (ODADDR(PEDIR_RESOURCE) - rvamin), 16); + // write back when the original is zeroed + if (get_le32(obuf + (ODADDR(PEDIR_RESOURCE) - rvamin + 12)) == 0) + omemcpy(obuf + (ODADDR(PEDIR_RESOURCE) - rvamin), p, res.dirsize()); } } template -void PeFile::rebuildImports(SPAN_S(upx_byte) & extrainfo, - ord_mask_t ord_mask, bool set_oft) -{ - if (ODADDR(PEDIR_IMPORT) == 0 - || ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc)) +void PeFile::rebuildImports(SPAN_S(upx_byte) & extrainfo, ord_mask_t ord_mask, bool set_oft) { + if (ODADDR(PEDIR_IMPORT) == 0 || ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc)) return; OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo)); @@ -2911,8 +2681,7 @@ void PeFile::rebuildImports(SPAN_S(upx_byte) & extrainfo, IPTR_I_D(const upx_byte, import, IDADDR(PEDIR_IMPORT) - isection[2].vaddr); OPTR_I(const upx_byte, p, raw_bytes(idata, 4)); - for ( ; get_le32(p) != 0; ++p) - { + for (; get_le32(p) != 0; ++p) { const upx_byte *dname = raw_bytes(import + get_le32(p), 1); const unsigned dlen = strlen(dname); ICHECK(dname, dlen + 1); @@ -2929,7 +2698,7 @@ void PeFile::rebuildImports(SPAN_S(upx_byte) & extrainfo, sdllnames = ALIGN_UP(sdllnames, 2u); // TODO: introduce WildPtr for "virtual pointer" pointing before a buffer - upx_byte * const Obuf = obuf.raw_bytes(0) - rvamin; + upx_byte *const Obuf = obuf.raw_bytes(0) - rvamin; #if 0 import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT)); import_desc *im = im0; @@ -2944,24 +2713,20 @@ void PeFile::rebuildImports(SPAN_S(upx_byte) & extrainfo, SPAN_0_VAR(upx_byte, const importednames_start, importednames); #endif - for (p = idata; get_le32(p) != 0; ++p) - { + for (p = idata; get_le32(p) != 0; ++p) { // restore the name of the dll const upx_byte *dname = raw_bytes(import + get_le32(p), 1); const unsigned dlen = strlen(dname); ICHECK(dname, dlen + 1); const unsigned iatoffs = get_le32(p + 4) + rvamin; - if (inamespos) - { + if (inamespos) { // now I rebuild the dll names omemcpy(dllnames, dname, dlen + 1); - im->dllname = ptr_diff_bytes(dllnames,Obuf); + im->dllname = ptr_diff_bytes(dllnames, Obuf); //;;;printf("\ndll: %s:",dllnames); dllnames += dlen + 1; - } - else - { + } else { omemcpy(Obuf + im->dllname, dname, dlen + 1); } im->iat = iatoffs; @@ -2972,75 +2737,66 @@ void PeFile::rebuildImports(SPAN_S(upx_byte) & extrainfo, // restore the imported names+ordinals for (p += 8; *p; ++newiat) - if (*p == 1) - { + if (*p == 1) { const unsigned ilen = strlen(++p) + 1; - if (inamespos) - { + if (inamespos) { if (ptr_diff_bytes(importednames, importednames_start) & 1) importednames -= 1; omemcpy(importednames + 2, p, ilen); //;;;printf(" %s",importednames+2); *newiat = ptr_diff_bytes(importednames, Obuf); importednames += 2 + ilen; - } - else - { + } else { // Beware overlap! omemmove(Obuf + (*newiat + 2), p, ilen); } p += ilen; - } - else if (*p == 0xff) - { + } else if (*p == 0xff) { *newiat = get_le16(p + 1) + ord_mask; //;;;printf(" %x",(unsigned)*newiat); p += 3; - } - else - { - *newiat = * (const LEXX*) raw_bytes(import + get_le32(p + 1), sizeof(LEXX)); + } else { + *newiat = *(const LEXX *) raw_bytes(import + get_le32(p + 1), sizeof(LEXX)); assert(*newiat & ord_mask); p += 5; } *newiat = 0; im++; } - //memset(idata,0,p - idata); + // memset(idata,0,p - idata); } template -void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, - ord_mask_t ord_mask, bool set_oft) -{ - //infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs); +void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, ord_mask_t ord_mask, bool set_oft) { + // infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), + // objs); - handleStub(fi,fo,pe_offset); + handleStub(fi, fo, pe_offset); if (ih.filealign == 0) throwCantUnpack("unexpected value in the PE header"); const unsigned iobjs = ih.objects; - const unsigned overlay = file_size - ALIGN_UP(isection[iobjs - 1].rawdataptr - + isection[iobjs - 1].size, - ih.filealign); + const unsigned overlay = + file_size - + ALIGN_UP(isection[iobjs - 1].rawdataptr + isection[iobjs - 1].size, ih.filealign); checkOverlay(overlay); ibuf.alloc(ph.c_len); obuf.allocForDecompression(ph.u_len); - fi->seek(isection[1].rawdataptr - 64 + ph.buf_offset + ph.getPackHeaderSize(),SEEK_SET); - fi->readx(ibuf, ibufgood= ph.c_len); + fi->seek(isection[1].rawdataptr - 64 + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET); + fi->readx(ibuf, ibufgood = ph.c_len); // decompress - decompress(ibuf,obuf); + decompress(ibuf, obuf); unsigned skip = get_le32(obuf + ph.u_len - 4); unsigned take = sizeof(oh); SPAN_S_VAR(upx_byte, extrainfo, obuf); extrainfo = obuf.subref("bad extrainfo offset %#x", skip, take); - //upx_byte * const eistart = raw_bytes(extrainfo, 0); + // upx_byte * const eistart = raw_bytes(extrainfo, 0); memcpy(&oh, extrainfo, take); extrainfo += take; - skip += take; + skip += take; unsigned objs = oh.objects; if ((int) objs <= 0 || (iobjs > 2 && isection[2].size == 0)) @@ -3050,31 +2806,28 @@ void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, extrainfo = obuf.subref("bad extra section size at %#x", skip, take); memcpy(osection, extrainfo, take); extrainfo += take; - skip += take; + skip += take; rvamin = osection[0].vaddr; - if (iobjs > 2) - { + if (iobjs > 2) { // read the noncompressed section ibuf.dealloc(); ibuf.alloc(isection[2].size); - fi->seek(isection[2].rawdataptr,SEEK_SET); - fi->readx(ibuf, ibufgood= isection[2].size); + fi->seek(isection[2].rawdataptr, SEEK_SET); + fi->readx(ibuf, ibufgood = isection[2].size); } // unfilter - if (ph.filter) - { + if (ph.filter) { Filter ft(ph.level); - ft.init(ph.filter,oh.codebase - rvamin); + ft.init(ph.filter, oh.codebase - rvamin); ft.cto = (unsigned char) ph.filter_cto; OCHECK(obuf + (oh.codebase - rvamin), oh.codesize); ft.unfilter(obuf + (oh.codebase - rvamin), oh.codesize); } // FIXME: ih.flags is checked here because of a bug in UPX 0.92 - if (ih.flags & RELOCS_STRIPPED) - { + if (ih.flags & RELOCS_STRIPPED) { oh.flags |= RELOCS_STRIPPED; ODADDR(PEDIR_RELOC) = 0; ODSIZE(PEDIR_RELOC) = 0; @@ -3085,20 +2838,19 @@ void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, rebuildTls(); rebuildExports(); - if (iobjs > 3) - { + if (iobjs > 3) { // read the resource section if present ibuf.dealloc(); ibuf.alloc(isection[3].size); - fi->seek(isection[3].rawdataptr,SEEK_SET); - fi->readx(ibuf, ibufgood= isection[3].size); + fi->seek(isection[3].rawdataptr, SEEK_SET); + fi->readx(ibuf, ibufgood = isection[3].size); } rebuildResources(extrainfo, isection[ih.objects - 1].vaddr); - //FIXME: this does bad things if the relocation section got removed - // during compression ... - //memset(eistart, 0, ptr_udiff_bytes(extrainfo, eistart) + 4); + // FIXME: this does bad things if the relocation section got removed + // during compression ... + // memset(eistart, 0, ptr_udiff_bytes(extrainfo, eistart) + 4); // fill the data directory ODADDR(PEDIR_DEBUG) = 0; @@ -3112,8 +2864,7 @@ void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, oh.chksum = 0; // write decompressed file - if (fo) - { + if (fo) { unsigned ic; for (ic = 0; ic < objs && osection[ic].rawdataptr == 0; ic++) ; @@ -3124,40 +2875,37 @@ void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, infoHeader("[Writing uncompressed file]"); // write loader + compressed file - fo->write(&oh,sizeof(oh)); - fo->write(osection,objs * sizeof(pe_section_t)); - fo->write(ibuf,osection[ic].rawdataptr - fo->getBytesWritten()); + fo->write(&oh, sizeof(oh)); + fo->write(osection, objs * sizeof(pe_section_t)); + fo->write(ibuf, osection[ic].rawdataptr - fo->getBytesWritten()); for (ic = 0; ic < objs; ic++) if (osection[ic].rawdataptr) - fo->write(obuf + (osection[ic].vaddr - rvamin), ALIGN_UP(osection[ic].size,oh.filealign)); + fo->write(obuf + (osection[ic].vaddr - rvamin), + ALIGN_UP(osection[ic].size, oh.filealign)); copyOverlay(fo, overlay, obuf); } ibuf.dealloc(); } -int PeFile::canUnpack0(unsigned max_sections, unsigned objs, - unsigned ih_entry, unsigned ih_size) -{ +int PeFile::canUnpack0(unsigned max_sections, unsigned objs, unsigned ih_entry, unsigned ih_size) { if (!canPack()) return false; mb_isection.alloc(sizeof(pe_section_t) * objs); isection = mb_isection; // => isection now is a SPAN_S fi->seek(pe_offset + ih_size, SEEK_SET); - fi->readx(isection,sizeof(pe_section_t) * objs); + fi->readx(isection, sizeof(pe_section_t) * objs); const unsigned min_sections = isefi ? 2 : 3; if (objs < min_sections) return -1; bool is_packed = (objs >= min_sections && objs <= max_sections && (IDSIZE(15) || ih_entry > isection[1].vaddr)); bool found_ph = false; - if (memcmp(isection[0].name,"UPX",3) == 0) - { + if (memcmp(isection[0].name, "UPX", 3) == 0) { // current version fi->seek(isection[1].rawdataptr - 64, SEEK_SET); found_ph = readPackHeader(1024); - if (!found_ph) - { + if (!found_ph) { // old versions fi->seek(isection[2].rawdataptr, SEEK_SET); found_ph = readPackHeader(1024); @@ -3167,8 +2915,7 @@ int PeFile::canUnpack0(unsigned max_sections, unsigned objs, return true; if (!is_packed && !found_ph) return -1; - if (is_packed && ih_entry < isection[2].vaddr) - { + if (is_packed && ih_entry < isection[2].vaddr) { unsigned char buf[256]; bool x = false; @@ -3185,40 +2932,36 @@ int PeFile::canUnpack0(unsigned max_sections, unsigned objs, if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0) x = true; } catch (...) { - //x = true; + // x = true; } if (x) throwCantUnpack("file is modified/hacked/protected; take care!!!"); else throwCantUnpack("file is possibly modified/hacked/protected; take care!"); - return false; // not reached + return false; // not reached } // FIXME: what should we say here ? - //throwCantUnpack("file is possibly modified/hacked/protected; take care!"); + // throwCantUnpack("file is possibly modified/hacked/protected; take care!"); return false; } -upx_uint64_t PeFile::ilinkerGetAddress(const char *d, const char *n) const -{ +upx_uint64_t PeFile::ilinkerGetAddress(const char *d, const char *n) const { return ilinker->getAddress(d, n); } -PeFile::~PeFile() -{ +PeFile::~PeFile() { oimpdlls = nullptr; - delete [] oxrelocs; + delete[] oxrelocs; delete ilinker; - //delete res; + // delete res; } - /************************************************************************* // PeFile32 **************************************************************************/ -PeFile32::PeFile32(InputFile *f) : super(f) -{ +PeFile32::PeFile32(InputFile *f) : super(f) { COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 248) COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t) @@ -3226,42 +2969,32 @@ PeFile32::PeFile32(InputFile *f) : super(f) oddirs = oh.ddirs; } -PeFile32::~PeFile32() -{} +PeFile32::~PeFile32() {} -void PeFile32::readPeHeader() -{ - fi->readx(&ih,sizeof(ih)); - isefi = ((1u << ih.subsystem) & ( - (1u<readx(&ih, sizeof(ih)); + isefi = ((1u << ih.subsystem) & + ((1u << IMAGE_SUBSYSTEM_EFI_APPLICATION) | + (1u << IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) | + (1u << IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) | (1u << IMAGE_SUBSYSTEM_EFI_ROM))) != 0; isdll = !isefi && (ih.flags & DLL_FLAG) != 0; use_dep_hack &= !isefi; use_clear_dirty_stack &= !isefi; } -void PeFile32::pack0(OutputFile *fo, unsigned subsystem_mask, - upx_uint64_t default_imagebase, - bool last_section_rsrc_only) -{ - super::pack0(fo, ih, oh, subsystem_mask, - default_imagebase, last_section_rsrc_only); +void PeFile32::pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase, + bool last_section_rsrc_only) { + super::pack0(fo, ih, oh, subsystem_mask, default_imagebase, last_section_rsrc_only); infoWarning("End of PeFile32::pack0"); } -void PeFile32::unpack(OutputFile *fo) -{ +void PeFile32::unpack(OutputFile *fo) { bool set_oft = getFormat() == UPX_F_WINCE_ARM_PE; unpack0(fo, ih, oh, 1U << 31, set_oft); } -int PeFile32::canUnpack() -{ - return canUnpack0(getFormat() == UPX_F_WINCE_ARM_PE ? 4 : 3, - ih.objects, ih.entry, sizeof(ih)); +int PeFile32::canUnpack() { + return canUnpack0(getFormat() == UPX_F_WINCE_ARM_PE ? 4 : 3, ih.objects, ih.entry, sizeof(ih)); } unsigned PeFile32::processImports() // pass 1 @@ -3269,13 +3002,9 @@ unsigned PeFile32::processImports() // pass 1 return processImports0(1u << 31); } -void PeFile32::processTls(Interval *iv) -{ - processTls1(iv, ih.imagebase, ih.imagesize); -} +void PeFile32::processTls(Interval *iv) { processTls1(iv, ih.imagebase, ih.imagesize); } -void PeFile32::processTls(Reloc *r, const Interval *iv, unsigned a) -{ +void PeFile32::processTls(Reloc *r, const Interval *iv, unsigned a) { processTls2(r, iv, a, ih.imagebase); } @@ -3283,8 +3012,7 @@ void PeFile32::processTls(Reloc *r, const Interval *iv, unsigned a) // PeFile64 **************************************************************************/ -PeFile64::PeFile64(InputFile *f) : super(f) -{ +PeFile64::PeFile64(InputFile *f) : super(f) { COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 264) COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t) @@ -3292,51 +3020,35 @@ PeFile64::PeFile64(InputFile *f) : super(f) oddirs = oh.ddirs; } -PeFile64::~PeFile64() -{} +PeFile64::~PeFile64() {} -void PeFile64::readPeHeader() -{ - fi->readx(&ih,sizeof(ih)); - isefi = ((1u << ih.subsystem) & ( - (1u<readx(&ih, sizeof(ih)); + isefi = ((1u << ih.subsystem) & + ((1u << IMAGE_SUBSYSTEM_EFI_APPLICATION) | + (1u << IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) | + (1u << IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) | (1u << IMAGE_SUBSYSTEM_EFI_ROM))) != 0; isdll = !isefi && (ih.flags & DLL_FLAG) != 0; use_dep_hack &= !isefi; use_clear_dirty_stack &= !isefi; } -void PeFile64::pack0(OutputFile *fo, unsigned subsystem_mask, - upx_uint64_t default_imagebase) -{ +void PeFile64::pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase) { super::pack0(fo, ih, oh, subsystem_mask, default_imagebase, false); } -void PeFile64::unpack(OutputFile *fo) -{ - unpack0(fo, ih, oh, 1ULL << 63, false); -} +void PeFile64::unpack(OutputFile *fo) { unpack0(fo, ih, oh, 1ULL << 63, false); } -int PeFile64::canUnpack() -{ - return canUnpack0(3, ih.objects, ih.entry, sizeof(ih)); -} +int PeFile64::canUnpack() { return canUnpack0(3, ih.objects, ih.entry, sizeof(ih)); } unsigned PeFile64::processImports() // pass 1 { return processImports0(1ULL << 63); } -void PeFile64::processTls(Interval *iv) -{ - processTls1(iv, ih.imagebase, ih.imagesize); -} +void PeFile64::processTls(Interval *iv) { processTls1(iv, ih.imagebase, ih.imagesize); } -void PeFile64::processTls(Reloc *r, const Interval *iv, unsigned a) -{ +void PeFile64::processTls(Reloc *r, const Interval *iv, unsigned a) { processTls2(r, iv, a, ih.imagebase); } @@ -3353,5 +3065,4 @@ void PeFile64::processTls(Reloc *r, const Interval *iv, unsigned a) */ - /* vim:set ts=4 sw=4 et: */ diff --git a/src/pefile.h b/src/pefile.h index 15bc49b1..c697fefe 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -25,19 +25,17 @@ */ - -#ifndef __UPX_PEFILE_H -#define __UPX_PEFILE_H 1 +#pragma once +#ifndef UPX_PEFILE_H__ +#define UPX_PEFILE_H__ 1 #include "util/membuffer.h" - /************************************************************************* // general/pe handling **************************************************************************/ -class PeFile : public Packer -{ +class PeFile : public Packer { typedef Packer super; public: virtual int getVersion() const override { return 13; } @@ -53,20 +51,17 @@ protected: virtual ~PeFile(); void readSectionHeaders(unsigned objs, unsigned sizeof_ih); - unsigned readSections(unsigned objs, unsigned usize, - unsigned ih_filealign, unsigned ih_datasize); - void checkHeaderValues(unsigned subsystem, unsigned mask, - unsigned ih_entry, unsigned ih_filealign); - unsigned handleStripRelocs(upx_uint64_t ih_imagebase, - upx_uint64_t default_imagebase, + unsigned readSections(unsigned objs, unsigned usize, unsigned ih_filealign, + unsigned ih_datasize); + void checkHeaderValues(unsigned subsystem, unsigned mask, unsigned ih_entry, + unsigned ih_filealign); + unsigned handleStripRelocs(upx_uint64_t ih_imagebase, upx_uint64_t default_imagebase, LE16 &dllflags); virtual bool handleForceOption() = 0; - virtual void callCompressWithFilters(Filter &, int filter_strategy, - unsigned ih_codebase); - virtual void defineSymbols(unsigned ncsection, unsigned upxsection, - unsigned sizeof_oh, unsigned isize_isplit, - unsigned s1addr) = 0; + virtual void callCompressWithFilters(Filter &, int filter_strategy, unsigned ih_codebase); + virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh, + unsigned isize_isplit, unsigned s1addr) = 0; virtual void addNewRelocations(Reloc &, unsigned) {} void callProcessRelocs(Reloc &rel, unsigned &ic); void callProcessResources(Resource &res, unsigned &ic); @@ -75,20 +70,18 @@ protected: virtual void setOhHeaderSize(const pe_section_t *osection) = 0; template - void pack0(OutputFile *fo, ht &ih, ht &oh, - unsigned subsystem_mask, upx_uint64_t default_imagebase, - bool last_section_rsrc_only); + void pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, + upx_uint64_t default_imagebase, bool last_section_rsrc_only); template - void unpack0(OutputFile *fo, const ht &ih, ht &oh, - ord_mask_t ord_mask, bool set_oft); + void unpack0(OutputFile *fo, const ht &ih, ht &oh, ord_mask_t ord_mask, bool set_oft); // unpacker capabilities - virtual bool canUnpackVersion(int version) const override - { return (version >= 12 && version <= 13); } + virtual bool canUnpackVersion(int version) const override { + return (version >= 12 && version <= 13); + } - int canUnpack0(unsigned max_sections, unsigned objs, - unsigned ih_entry, unsigned ih_size); + int canUnpack0(unsigned max_sections, unsigned objs, unsigned ih_entry, unsigned ih_size); protected: virtual int readFileHeader(); @@ -101,8 +94,7 @@ protected: unsigned processImports0(ord_mask_t ord_mask); template - void rebuildImports(SPAN_S(upx_byte) & extrainfo, - ord_mask_t ord_mask, bool set_oft); + void rebuildImports(SPAN_S(upx_byte) & extrainfo, ord_mask_t ord_mask, bool set_oft); virtual unsigned processImports() = 0; virtual void processImports2(unsigned, unsigned); MemBuffer mb_oimport; @@ -118,8 +110,7 @@ protected: virtual void processRelocs() = 0; void processRelocs(Reloc *); - void rebuildRelocs(SPAN_S(upx_byte) &, unsigned bits, - unsigned flags, upx_uint64_t imagebase); + void rebuildRelocs(SPAN_S(upx_byte) &, unsigned bits, unsigned flags, upx_uint64_t imagebase); MemBuffer mb_orelocs; SPAN_0(upx_byte) orelocs = nullptr; unsigned sorelocs; @@ -127,7 +118,7 @@ protected: unsigned soxrelocs; void processExports(Export *); - void processExports(Export *,unsigned); + void processExports(Export *, unsigned); void rebuildExports(); MemBuffer mb_oexport; SPAN_0(upx_byte) oexport = nullptr; @@ -143,11 +134,10 @@ protected: template struct tls_traits; template - void processTls1(Interval *iv, - typename tls_traits::cb_value_t imagebase, + void processTls1(Interval *iv, typename tls_traits::cb_value_t imagebase, unsigned imagesize); // pass 1 template - void processTls2(Reloc *rel,const Interval *iv,unsigned newaddr, + void processTls2(Reloc *rel, const Interval *iv, unsigned newaddr, typename tls_traits::cb_value_t imagebase); // pass 2 virtual void processTls(Interval *iv) = 0; virtual void processTls(Reloc *r, const Interval *iv, unsigned a) = 0; @@ -175,22 +165,22 @@ protected: bool importbyordinal; bool kernel32ordinal; unsigned rvamin; - unsigned cimports; // rva of preprocessed imports - unsigned crelocs; // rva of preprocessed fixups + unsigned cimports; // rva of preprocessed imports + unsigned crelocs; // rva of preprocessed fixups int big_relocs; struct alignas(1) ddirs_t { - LE32 vaddr; - LE32 size; + LE32 vaddr; + LE32 size; }; ddirs_t *iddirs; ddirs_t *oddirs; struct alignas(1) import_desc { - LE32 oft; // orig first thunk - char _[8]; - LE32 dllname; - LE32 iat; // import address table + LE32 oft; // orig first thunk + char _[8]; + LE32 dllname; + LE32 iat; // import address table }; LE32 &IDSIZE(unsigned x); @@ -199,13 +189,13 @@ protected: LE32 &ODADDR(unsigned x); struct alignas(1) pe_section_t { - char name[8]; - LE32 vsize; - LE32 vaddr; - LE32 size; - LE32 rawdataptr; - char _[12]; - LE32 flags; + char name[8]; + LE32 vsize; + LE32 vaddr; + LE32 size; + LE32 rawdataptr; + char _[12]; + LE32 flags; }; MemBuffer mb_isection; @@ -217,105 +207,119 @@ protected: bool use_clear_dirty_stack; bool use_stub_relocs; - - static unsigned virta2objnum (unsigned, SPAN_0(pe_section_t), unsigned); - unsigned tryremove (unsigned, unsigned); + static unsigned virta2objnum(unsigned, SPAN_0(pe_section_t), unsigned); + unsigned tryremove(unsigned, unsigned); enum { - PEDIR_EXPORT = 0, - PEDIR_IMPORT = 1, - PEDIR_RESOURCE = 2, - PEDIR_EXCEPTION = 3, // Exception table - PEDIR_SEC = 4, // Certificate table (file pointer) - PEDIR_RELOC = 5, - PEDIR_DEBUG = 6, - PEDIR_COPYRIGHT = 7, // Architecture-specific data - PEDIR_GLOBALPTR = 8, // Global pointer - PEDIR_TLS = 9, - PEDIR_LOADCONF = 10, // Load Config Table - PEDIR_BOUNDIM = 11, - PEDIR_IAT = 12, - PEDIR_DELAYIMP = 13, // Delay Import Descriptor - PEDIR_COMRT = 14, // Com+ Runtime Header + PEDIR_EXPORT = 0, + PEDIR_IMPORT = 1, + PEDIR_RESOURCE = 2, + PEDIR_EXCEPTION = 3, // Exception table + PEDIR_SEC = 4, // Certificate table (file pointer) + PEDIR_RELOC = 5, + PEDIR_DEBUG = 6, + PEDIR_COPYRIGHT = 7, // Architecture-specific data + PEDIR_GLOBALPTR = 8, // Global pointer + PEDIR_TLS = 9, + PEDIR_LOADCONF = 10, // Load Config Table + PEDIR_BOUNDIM = 11, + PEDIR_IAT = 12, + PEDIR_DELAYIMP = 13, // Delay Import Descriptor + PEDIR_COMRT = 14, // Com+ Runtime Header }; enum { - PEFL_CODE = 0x20, - PEFL_DATA = 0x40, - PEFL_BSS = 0x80, - PEFL_INFO = 0x200, - PEFL_EXTRELS = 0x01000000, // extended relocations - PEFL_DISCARD = 0x02000000, - PEFL_NOCACHE = 0x04000000, - PEFL_NOPAGE = 0x08000000, - PEFL_SHARED = 0x10000000, - PEFL_EXEC = 0x20000000, - PEFL_READ = 0x40000000, - PEFL_WRITE = 0x80000000, + PEFL_CODE = 0x20, + PEFL_DATA = 0x40, + PEFL_BSS = 0x80, + PEFL_INFO = 0x200, + PEFL_EXTRELS = 0x01000000, // extended relocations + PEFL_DISCARD = 0x02000000, + PEFL_NOCACHE = 0x04000000, + PEFL_NOPAGE = 0x08000000, + PEFL_SHARED = 0x10000000, + PEFL_EXEC = 0x20000000, + PEFL_READ = 0x40000000, + PEFL_WRITE = 0x80000000, }; enum { RELOCS_STRIPPED = 0x0001, - EXECUTABLE = 0x0002, - LNUM_STRIPPED = 0x0004, - LSYMS_STRIPPED = 0x0008, + EXECUTABLE = 0x0002, + LNUM_STRIPPED = 0x0004, + LSYMS_STRIPPED = 0x0008, AGGRESSIVE_TRIM = 0x0010, - TWO_GIGS_AWARE = 0x0020, - FLITTLE_ENDIAN = 0x0080, + TWO_GIGS_AWARE = 0x0020, + FLITTLE_ENDIAN = 0x0080, BITS_32_MACHINE = 0x0100, - DEBUG_STRIPPED = 0x0200, - REMOVABLE_SWAP = 0x0400, - SYSTEM_PROGRAM = 0x1000, - DLL_FLAG = 0x2000, - FBIG_ENDIAN = 0x8000, + DEBUG_STRIPPED = 0x0200, + REMOVABLE_SWAP = 0x0400, + SYSTEM_PROGRAM = 0x1000, + DLL_FLAG = 0x2000, + FBIG_ENDIAN = 0x8000, }; - //NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann + // NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann enum { - IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, - IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, - IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, - IMAGE_DLLCHARACTERISTICS_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_CONTROL_FLOW_GUARD = 0x4000, + IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, + IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, + IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, + IMAGE_DLLCHARACTERISTICS_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_CONTROL_FLOW_GUARD = 0x4000, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000, }; enum { IMAGE_SUBSYSTEM_UNKNOWN = 0, - IMAGE_SUBSYSTEM_NATIVE = 1, - IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, // Grapical - IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, // Character-mode - IMAGE_SUBSYSTEM_WINDOWS_OS2_CUI = 5, - IMAGE_SUBSYSTEM_WINDOWS_POSIX_CUI = 7, - IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, - IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, - IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, - IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, - IMAGE_SUBSYSTEM_EFI_ROM = 13, - IMAGE_SUBSYSTEM_XBOX = 14, - IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16, + IMAGE_SUBSYSTEM_NATIVE = 1, + IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, // Grapical + IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, // Character-mode + IMAGE_SUBSYSTEM_WINDOWS_OS2_CUI = 5, + IMAGE_SUBSYSTEM_WINDOWS_POSIX_CUI = 7, + IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, + IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, + IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, + IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, + IMAGE_SUBSYSTEM_EFI_ROM = 13, + IMAGE_SUBSYSTEM_XBOX = 14, + IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16, }; // predefined resource types enum { - RT_CURSOR = 1, RT_BITMAP, RT_ICON, RT_MENU, 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 + RT_CURSOR = 1, + RT_BITMAP, + RT_ICON, + RT_MENU, + 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; void *base; public: - struct interval - { + struct interval { unsigned start, len; } *ivarr; @@ -324,9 +328,9 @@ protected: Interval(void *b); ~Interval(); - void add(unsigned start,unsigned len); - void add(const void *start,unsigned len); - void add(const void *start,const void *end); + void add(unsigned start, unsigned len); + void add(const void *start, unsigned len); + void add(const void *start, const void *end); void add(const Interval *iv); void flatten(); @@ -334,11 +338,10 @@ protected: void dump() const; 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; unsigned size; @@ -350,18 +353,17 @@ protected: unsigned counts[16]; public: - Reloc(upx_byte *,unsigned); + Reloc(upx_byte *, unsigned); Reloc(unsigned rnum); // - bool next(unsigned &pos,unsigned &type); + bool next(unsigned &pos, unsigned &type); const unsigned *getcounts() const { return counts; } // - void add(unsigned pos,unsigned type); - void finish(upx_byte* &p,unsigned &size); + void add(unsigned pos, unsigned type); + void finish(upx_byte *&p, unsigned &size); }; - class Resource : private noncopyable - { + class Resource : private noncopyable { struct res_dir_entry; struct res_dir; struct res_data; @@ -371,29 +373,28 @@ protected: MemBuffer mb_start; const upx_byte *start; - upx_byte *newstart; - upx_rnode *root; - upx_rleaf *head; - upx_rleaf *current; - unsigned dsize; - unsigned ssize; + upx_byte *newstart; + upx_rnode *root; + upx_rleaf *head; + upx_rleaf *current; + unsigned dsize; + unsigned ssize; const upx_byte *ibufstart; const upx_byte *ibufend; - void check(const res_dir*,unsigned); - upx_rnode *convert(const void *,upx_rnode *,unsigned); - void build(const upx_rnode *,unsigned &,unsigned &,unsigned); - void clear(upx_byte *,unsigned,Interval *); - void dump(const upx_rnode *,unsigned) const; - void destroy(upx_rnode *urd,unsigned level); + void check(const res_dir *, unsigned); + upx_rnode *convert(const void *, upx_rnode *, unsigned); + void build(const upx_rnode *, unsigned &, unsigned &, unsigned); + void clear(upx_byte *, unsigned, Interval *); + void dump(const upx_rnode *, unsigned) const; + void destroy(upx_rnode *urd, unsigned level); void ibufcheck(const void *m, unsigned size); public: Resource(const upx_byte *ibufstart, const upx_byte *ibufen); - Resource(const upx_byte *p, const upx_byte *ibufstart, - const upx_byte *ibufend); + Resource(const upx_byte *p, const upx_byte *ibufstart, const upx_byte *ibufend); ~Resource(); void init(const upx_byte *); @@ -418,26 +419,25 @@ protected: */ }; - class Export : private noncopyable - { + class Export : private noncopyable { struct alignas(1) export_dir_t { - char _[12]; // flags, timedate, version - LE32 name; - char __[4]; // ordinal base - LE32 functions; - LE32 names; - LE32 addrtable; - LE32 nameptrtable; - LE32 ordinaltable; + char _[12]; // flags, timedate, version + LE32 name; + char __[4]; // ordinal base + LE32 functions; + LE32 names; + LE32 addrtable; + LE32 nameptrtable; + LE32 ordinaltable; }; export_dir_t edir; - char *ename; - char *functionptrs; - char *ordinals; - char **names; + char *ename; + char *functionptrs; + char *ordinals; + char **names; - char *base; + char *base; unsigned size; Interval iv; @@ -445,21 +445,19 @@ protected: Export(char *_base); ~Export(); - void convert(unsigned eoffs,unsigned esize); - void build(char *base,unsigned newoffs); + void convert(unsigned eoffs, unsigned esize); + void build(char *base, unsigned newoffs); unsigned getsize() const { return size; } }; - }; -class PeFile32 : public PeFile -{ +class PeFile32 : public PeFile { typedef PeFile super; protected: PeFile32(InputFile *f); virtual ~PeFile32(); - void pack0(OutputFile *fo, unsigned subsystem_mask, - upx_uint64_t default_imagebase, bool last_section_rsrc_only); + void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase, + bool last_section_rsrc_only); virtual void unpack(OutputFile *fo) override; virtual int canUnpack() override; @@ -472,39 +470,39 @@ protected: struct alignas(1) pe_header_t { // 0x0 - char _[4]; // pemagic - LE16 cpu; - LE16 objects; - char __[12]; // timestamp + reserved - LE16 opthdrsize; - LE16 flags; + char _[4]; // pemagic + LE16 cpu; + LE16 objects; + char __[12]; // timestamp + reserved + LE16 opthdrsize; + LE16 flags; // optional header - LE16 coffmagic; // NEW: Stefan Widmann - char ___[2]; // linkerversion - LE32 codesize; + LE16 coffmagic; // NEW: Stefan Widmann + char ___[2]; // linkerversion + LE32 codesize; // 0x20 - LE32 datasize; - LE32 bsssize; - LE32 entry; - LE32 codebase; + LE32 datasize; + LE32 bsssize; + LE32 entry; + LE32 codebase; // 0x30 - LE32 database; + LE32 database; // nt specific fields - LE32 imagebase; - LE32 objectalign; - LE32 filealign; // should set to 0x200 ? + LE32 imagebase; + LE32 objectalign; + LE32 filealign; // should set to 0x200 ? // 0x40 - char ____[16]; // versions + char ____[16]; // versions // 0x50 - LE32 imagesize; - LE32 headersize; - LE32 chksum; // should set to 0 - LE16 subsystem; - LE16 dllflags; + LE32 imagesize; + LE32 headersize; + LE32 chksum; // should set to 0 + LE16 subsystem; + LE16 dllflags; // 0x60 - char _____[20]; // stack + heap sizes + char _____[20]; // stack + heap sizes // 0x74 - LE32 ddirsentries; // usually 16 + LE32 ddirsentries; // usually 16 ddirs_t ddirs[16]; }; @@ -512,15 +510,13 @@ protected: pe_header_t ih, oh; }; -class PeFile64 : public PeFile -{ +class PeFile64 : public PeFile { typedef PeFile super; protected: PeFile64(InputFile *f); virtual ~PeFile64(); - void pack0(OutputFile *fo, unsigned subsystem_mask, - upx_uint64_t default_imagebase); + void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase); virtual void unpack(OutputFile *fo) override; virtual int canUnpack() override; @@ -534,39 +530,39 @@ protected: struct alignas(1) pe_header_t { // 0x0 - char _[4]; // pemagic - LE16 cpu; - LE16 objects; // number of sections - char __[12]; // timestamp + reserved - LE16 opthdrsize; - LE16 flags; // characteristics + char _[4]; // pemagic + LE16 cpu; + LE16 objects; // number of sections + char __[12]; // timestamp + reserved + LE16 opthdrsize; + LE16 flags; // characteristics // optional header - LE16 coffmagic; // NEW: Stefan Widmann - char ___[2]; // linkerversion - LE32 codesize; + LE16 coffmagic; // NEW: Stefan Widmann + char ___[2]; // linkerversion + LE32 codesize; // 0x20 - LE32 datasize; - LE32 bsssize; - LE32 entry; // still a 32 bit RVA - LE32 codebase; + LE32 datasize; + LE32 bsssize; + LE32 entry; // still a 32 bit RVA + LE32 codebase; // 0x30 - //LE32 database; // field does not exist in PE+! + // LE32 database; // field does not exist in PE+! // nt specific fields - LE64 imagebase; // LE32 -> LE64 - Stefan Widmann standard is 0x0000000140000000 - LE32 objectalign; - LE32 filealign; // should set to 0x200 ? + LE64 imagebase; // LE32 -> LE64 - Stefan Widmann standard is 0x0000000140000000 + LE32 objectalign; + LE32 filealign; // should set to 0x200 ? // 0x40 - char ____[16]; // versions + char ____[16]; // versions // 0x50 - LE32 imagesize; - LE32 headersize; - LE32 chksum; // should set to 0 - LE16 subsystem; - LE16 dllflags; + LE32 imagesize; + LE32 headersize; + LE32 chksum; // should set to 0 + LE16 subsystem; + LE16 dllflags; // 0x60 - char _____[36]; // stack + heap sizes + loader flag + char _____[36]; // stack + heap sizes + loader flag // 0x84 - LE32 ddirsentries; // usually 16 + LE32 ddirsentries; // usually 16 ddirs_t ddirs[16]; };