From b361b91ec7bb4576f3d7a442b1846279f465c413 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 26 Mar 2023 10:53:30 -0700 Subject: [PATCH] Try to appease Android runtime loader; _Shdr vs _Phdr offsets JNI FalalError called: Unable to load library: [dlopen failed: "/lib/arm/libunity.so" .dynamic section has invalid offset: 0x6d3e58, expected to match PT_DYNAMIC offset: 0x441e58] https://github.com/upx/upx/issues/609 modified: p_elf_enum.h modified: p_lx_elf.cpp --- src/p_elf_enum.h | 7 +++++-- src/p_lx_elf.cpp | 30 +++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/p_elf_enum.h b/src/p_elf_enum.h index d9fef5a1..6545546a 100644 --- a/src/p_elf_enum.h +++ b/src/p_elf_enum.h @@ -127,9 +127,12 @@ SHT_FINI_ARRAY = 15, /* Array of destructors */ SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */ SHT_GROUP = 17, /* Section group */ - SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */ + SHT_SYMTAB_SHNDX = 18, /* Extended section indices */ + SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */ SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */ - SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */ + SHT_GNU_verdef = 0x6ffffffd, /* Version definition section. */ + SHT_GNU_verneed = 0x6ffffffe, /* Version needs section. */ + SHT_GNU_versym = 0x6fffffff, /* Version symbol table. */ SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */ SHT_LOPROC = 0x70000000, /* Start of processor-specific */ diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 1a2a4252..b0118646 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -1660,6 +1660,7 @@ static const #define WANT_NHDR_ENUM #include "p_elf_enum.h" +#undef WANT_NHDR_ENUM void PackNetBSDElf32x86::buildLoader(const Filter *ft) @@ -5477,6 +5478,10 @@ void PackLinuxElf32mipsel::defineSymbols(Filter const *ft) PackLinuxElf32::defineSymbols(ft); } +#define WANT_SHDR_ENUM +#include "p_elf_enum.h" +#undef WANT_SHDR_ENUM + void PackLinuxElf32::forward_Shdrs(OutputFile *fo) { if (saved_opt_android_shlib) { // Forward select _Shdr @@ -5485,6 +5490,21 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo) // Keep _Shdr for SHF_WRITE. // Discard _Shdr with (0==sh_addr), except _Shdr[0] // Keep ARM_ATTRIBUTES + unsigned const want_types_mask = + 1<e_shnum)); memset(mb_ask_for, 0, mb_ask_for.getSize()); @@ -5501,7 +5521,8 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo) for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) { unsigned sh_offset = get_te32(&sh_in->sh_offset); unsigned sh_flags = get_te32(&sh_in->sh_flags); - unsigned sh_info = get_te16(&sh_in->sh_info); + unsigned sh_info = get_te32(&sh_in->sh_info); + unsigned sh_type = get_te32(&sh_in->sh_type); if (ask_for[j]) { // Some previous _Shdr requested me // Tell them my new index set_te16(&sh_out0[ask_for[j]].sh_info, n_sh_out); @@ -5511,6 +5532,7 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo) || (Elf32_Shdr::SHF_WRITE & sh_flags) || (j == e_shstrndx) || (sec_arm_attr == sh_in) + || (want_types_mask & (1<<(0x1f & sh_type))) ) { *sh_out = *sh_in; if (sec_arm_attr == sh_in) { @@ -5530,8 +5552,10 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo) fo->write(ibuf, len); total_out += len; } - if (Elf32_Shdr::SHF_WRITE & sh_flags) { - set_te32(&sh_out->sh_offset, so_slide + get_te32(&sh_out->sh_offset)); + if (Elf32_Shdr::SHF_WRITE & sh_flags || SHT_NOTE == sh_type) { + if (sh_offset > xct_off) { + set_te32(&sh_out->sh_offset, so_slide + sh_offset); + } } ++sh_out; ++n_sh_out; }