From 19c2c1edcf7390dac5ad32b134ba3c0443824251 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Tue, 7 Nov 2017 11:12:23 -0800 Subject: [PATCH] Android 8.0 (Oreo) wants 0!=.e_shstrndx in a shared library https://github.com/upx/upx/issues/142 It should not matter what the .sh_name is; only the .sh_type matters. modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 3cf42b46..8cd256c9 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -3107,13 +3107,18 @@ void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft) unsigned arm_attr_size = 0; for (unsigned j = 0; j < k; ++j) { // forward .sh_link Elf32_Shdr *const sptr = j + (Elf32_Shdr *)(void *)snew; + unsigned const type = get_te32(&sptr->sh_type); // work-around for https://bugs.launchpad.net/bugs/1712938 - if (Elf32_Shdr::SHT_ARM_ATTRIBUTES == get_te32(&sptr->sh_type)) { + if (Elf32_Shdr::SHT_ARM_ATTRIBUTES == type) { arm_attr_offset = get_te32(&sptr->sh_offset); arm_attr_size = get_te32(&sptr->sh_size); set_te32(&sptr->sh_offset, xtra_off); xtra_off += get_te32(&sptr->sh_size); } + if (Elf32_Shdr::SHT_STRTAB == type) { // any SHT_STRTAB should work + set_te16(&elfout.ehdr.e_shstrndx, 1+ j); // 1+: shdr_undef + set_te16( &ehdri.e_shstrndx, 1+ j); // 1+: shdr_undef + } unsigned sh_offset = get_te32(&sptr->sh_offset); if (xct_off <= sh_offset) { set_te32(&sptr->sh_offset, so_slide + sh_offset); @@ -3240,13 +3245,18 @@ void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft) unsigned long arm_attr_size = 0; for (unsigned j = 0; j < k; ++j) { // forward .sh_link Elf64_Shdr *const sptr = j + (Elf64_Shdr *)(void *)snew; + unsigned const type = get_te32(&sptr->sh_type); // work-around for https://bugs.launchpad.net/bugs/1712938 - if (Elf64_Shdr::SHT_ARM_ATTRIBUTES == get_te32(&sptr->sh_type)) { + if (Elf64_Shdr::SHT_ARM_ATTRIBUTES == type) { arm_attr_offset = get_te64(&sptr->sh_offset); arm_attr_size = get_te64(&sptr->sh_size); set_te64(&sptr->sh_offset, xtra_off); xtra_off += get_te64(&sptr->sh_size); } + if (Elf64_Shdr::SHT_STRTAB == type) { // any SHT_STRTAB should work + set_te16(&elfout.ehdr.e_shstrndx, 1+ j); // 1+: shdr_undef + set_te16( &ehdri.e_shstrndx, 1+ j); // 1+: shdr_undef + } upx_uint64_t sh_offset = get_te64(&sptr->sh_offset); if (xct_off <= sh_offset) { set_te64(&sptr->sh_offset, so_slide + sh_offset);