diff --git a/src/p_w32pe_i386.cpp b/src/p_w32pe_i386.cpp index 646bdcbd..89abf6f0 100644 --- a/src/p_w32pe_i386.cpp +++ b/src/p_w32pe_i386.cpp @@ -76,7 +76,10 @@ int PackW32PeI386::readFileHeader() { **************************************************************************/ bool PackW32PeI386::canPack() { - if (!readFileHeader() || ih.cpu < IMAGE_FILE_MACHINE_I386 || ih.cpu > 0x150) + if (!readFileHeader()) + return false; + checkMachine(ih.cpu); + if (ih.cpu < IMAGE_FILE_MACHINE_I386 || ih.cpu > 0x150) return false; return true; } diff --git a/src/p_w64pe_amd64.cpp b/src/p_w64pe_amd64.cpp index 486e33cc..2d5a5d87 100644 --- a/src/p_w64pe_amd64.cpp +++ b/src/p_w64pe_amd64.cpp @@ -66,8 +66,10 @@ Linker *PackW64PeAmd64::newLinker() const { return new ElfLinkerAMD64; } **************************************************************************/ bool PackW64PeAmd64::canPack() { - // just check if machine type is 0x8664 - if (!readFileHeader() || ih.cpu != IMAGE_FILE_MACHINE_AMD64) + if (!readFileHeader()) + return false; + checkMachine(ih.cpu); + if (ih.cpu != IMAGE_FILE_MACHINE_AMD64) return false; return true; } diff --git a/src/p_w64pe_arm64.cpp b/src/p_w64pe_arm64.cpp index 920e4b34..7f005a5f 100644 --- a/src/p_w64pe_arm64.cpp +++ b/src/p_w64pe_arm64.cpp @@ -60,7 +60,10 @@ const int *PackW64PeArm64::getFilters() const { return nullptr; } **************************************************************************/ bool PackW64PeArm64::canPack() { - if (!readFileHeader() || ih.cpu != IMAGE_FILE_MACHINE_ARM64) + if (!readFileHeader()) + return false; + checkMachine(ih.cpu); + if (ih.cpu != IMAGE_FILE_MACHINE_ARM64) return false; throwCantPack("not yet implemented"); return true; diff --git a/src/p_wince_arm.cpp b/src/p_wince_arm.cpp index f4d97eff..d8d0042a 100644 --- a/src/p_wince_arm.cpp +++ b/src/p_wince_arm.cpp @@ -114,6 +114,7 @@ void PackWinCeArm::processTls(Interval *) // pass 1 bool PackWinCeArm::canPack() { if (!readFileHeader()) return false; + checkMachine(ih.cpu); if (ih.cpu != IMAGE_FILE_MACHINE_ARM && ih.cpu != IMAGE_FILE_MACHINE_THUMB) return false; use_thumb_stub |= ih.cpu == IMAGE_FILE_MACHINE_THUMB || (ih.entry & 1) == 1; diff --git a/src/packmast.cpp b/src/packmast.cpp index 4fa7d61e..3e9d75fb 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -158,12 +158,12 @@ Packer *PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const optio D(PackDjgpp2); D(PackTmt); D(PackWcle); + // D(PackW64PeArm64EC); // NOT YET IMPLEMENTED + // D(PackW64PeArm64); // NOT YET IMPLEMENTED D(PackW64PeAmd64); D(PackW32PeI386); } D(PackWinCeArm); - // D(PackW64PeArm64EC); // NOT YET IMPLEMENTED - // D(PackW64PeArm64); // NOT YET IMPLEMENTED D(PackExe); // diff --git a/src/pefile.cpp b/src/pefile.cpp index 31f1df00..16878347 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -117,6 +117,34 @@ bool PeFile::testUnpackVersion(int version) const { // util **************************************************************************/ +// early check of machine to generate a helpful error message +// FIXME/TODO: proper check for ARM64EC +// FIXME/TODO: proper check for ARM64X "universal" binary +// CHPE Compiled Hybrid PE: Microsoft internal only? +// CHPEV2 Compiled Hybrid PE: ARM64EC, ARM64X +/*static*/ int PeFile::checkMachine(unsigned cpu) { + // known but not supported + if (cpu == IMAGE_FILE_MACHINE_ARMNT) + throwCantPack("win32/arm32 is not supported"); // obsolete + if (cpu == IMAGE_FILE_MACHINE_ARM64) + throwCantPack("win64/arm64 is not supported"); + // FIXME: it seems that arm64ec actually uses MACHINE_AMD64 ??? + if (cpu == IMAGE_FILE_MACHINE_ARM64EC) + throwCantPack("win64/arm64ec is not supported"); + + // supported + if (cpu == IMAGE_FILE_MACHINE_AMD64) + return UPX_F_W64PE_AMD64; + if (cpu == IMAGE_FILE_MACHINE_ARM || cpu == IMAGE_FILE_MACHINE_THUMB) + return UPX_F_WINCE_ARM; + if (cpu >= IMAGE_FILE_MACHINE_I386 && cpu <= 0x150) // what is this 0x150 ??? + return UPX_F_W32PE_I386; + + // other or unkown (alpha, mips, etc.) + throwCantPack("pefile: unsupported machine %#x", cpu); + return 0; // pacify msvc +} + int PeFile::readFileHeader() { struct alignas(1) exe_header_t { LE16 mz; diff --git a/src/pefile.h b/src/pefile.h index 22c51735..383dbaff 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -82,6 +82,7 @@ protected: int canUnpack0(unsigned max_sections, unsigned objs, unsigned ih_entry, unsigned ih_size); protected: + static int checkMachine(unsigned cpu); virtual int readFileHeader(); virtual bool testUnpackVersion(int version) const override; virtual void readPeHeader() = 0;