From 854988bc5fc2e3bc52d5509ebc655a7cde696ec5 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Thu, 21 Sep 2023 14:12:18 -0700 Subject: [PATCH] Detect AlreadyPacked even when trailing PackHeader has been lopped. This is heuristic, but strong. https://github.com/upx/upx/issues/712 modified: p_lx_elf.cpp modified: p_unix.h --- src/p_lx_elf.cpp | 14 ++++++++++++-- src/p_unix.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 0ed4d7ee..8b76e3ec 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -2595,6 +2595,11 @@ tribool PackLinuxElf32::canPack() if (canUnpack()) { throwAlreadyPacked(); } + // Heuristic for lopped trailing PackHeader (packed and "hacked"!) + if (3 == e_phnum // not shlib: PT_LOAD.C_BASE, PT_LOAD.C_TEXT, PT_GNU_STACK + && UPX_MAGIC_LE32 == get_le32(&((l_info *)&phdri[e_phnum])->l_magic)) { + throwAlreadyPacked(); + } // We want to compress position-independent executable (gcc -pie) // main programs, but compressing a shared library must be avoided // because the result is no longer usable. In theory, there is no way @@ -3030,6 +3035,11 @@ PackLinuxElf64::canPack() if (canUnpack()) { throwAlreadyPacked(); } + // Heuristic for lopped trailing PackHeader (packed and "hacked"!) + if (3 == e_phnum // not shlib: PT_LOAD.C_BASE, PT_LOAD.C_TEXT, PT_GNU_STACK + && UPX_MAGIC_LE32 == get_le32(&((l_info *)&phdri[e_phnum])->l_magic)) { + throwAlreadyPacked(); + } // We want to compress position-independent executable (gcc -pie) // main programs, but compressing a shared library must be avoided // because the result is no longer usable. In theory, there is no way @@ -7640,7 +7650,7 @@ PackLinuxElf32::check_pt_load(Elf32_Phdr const *const phdr) if ((-1+ align) & (paddr ^ vaddr) || (u32_t)file_size <= (u32_t)offset || (u32_t)file_size < (u32_t)offend - || (u32_t)file_size <= (u32_t)filesz) { + || (u32_t)file_size < (u32_t)filesz) { char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]", (unsigned)(phdr - phdri)); throwCantPack(msg); @@ -7797,7 +7807,7 @@ PackLinuxElf64::check_pt_load(Elf64_Phdr const *const phdr) if ((-1+ align) & (paddr ^ vaddr) || (u64_t)file_size <= (u64_t)offset || (u64_t)file_size < (u64_t)offend - || (u64_t)file_size <= (u64_t)filesz) { + || (u64_t)file_size < (u64_t)filesz) { char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]", (unsigned)(phdr - phdri)); throwCantPack(msg); diff --git a/src/p_unix.h b/src/p_unix.h index a492afc8..5b8dd722 100644 --- a/src/p_unix.h +++ b/src/p_unix.h @@ -90,7 +90,7 @@ protected: ); unsigned total_in, total_out; // unpack - int exetype; + int exetype; // 0: unknown; 1: ELF; 2: pre-ELF; -1: /bin/sh; -2: Java unsigned blocksize; unsigned progid; // program id unsigned overlay_offset; // used when decompressing