diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 59f1c2bc..83602668 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -312,6 +312,9 @@ PackLinuxElf32::PackLinuxElf32help1(InputFile *f) dynsym = (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB); gashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH); hashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH); + if (3& ((uintptr_t)dynsym | (uintptr_t)gashtab | (uintptr_t)hashtab)) { + throwCantPack("unaligned DT_SYMTAB, DT_GNU_HASH, or DT_HASH/n"); + } jni_onload_sym = elf_lookup("JNI_OnLoad"); if (jni_onload_sym) { jni_onload_va = get_te32(&jni_onload_sym->st_value); @@ -807,6 +810,9 @@ PackLinuxElf64::PackLinuxElf64help1(InputFile *f) dynsym = (Elf64_Sym const *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB); gashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH); hashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH); + if (3& ((uintptr_t)dynsym | (uintptr_t)gashtab | (uintptr_t)hashtab)) { + throwCantPack("unaligned DT_SYMTAB, DT_GNU_HASH, or DT_HASH/n"); + } jni_onload_sym = elf_lookup("JNI_OnLoad"); if (jni_onload_sym) { jni_onload_va = get_te64(&jni_onload_sym->st_value); @@ -1686,6 +1692,12 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp) unsigned const *const bitmask = (unsigned const *)(void const *)&gashtab[4]; unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; (void)hasharr; + if (!n_bucket || (1u<<31) <= n_bucket /* fie on fuzzers */ + || (void const *)&file_image[file_size] <= (void const *)hasharr) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bucket %#x\n", n_bucket); + throwCantPack(msg); + } //unsigned const *const gashend = &hasharr[n_bucket]; // minimum, except: // Rust and Android trim unused zeroes from high end of hasharr[] unsigned bmax = 0; @@ -5243,6 +5255,12 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp) upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4]; unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; (void)hasharr; + if (!n_bucket || (1u<<31) <= n_bucket /* fie on fuzzers */ + || (void const *)&file_image[file_size] <= (void const *)hasharr) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bucket %#x\n", n_bucket); + throwCantPack(msg); + } //unsigned const *const gashend = &hasharr[n_bucket]; // minimum, except: // Rust and Android trim unused zeroes from high end of hasharr[] unsigned bmax = 0; @@ -5356,6 +5374,13 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const unsigned const *const buckets = &hashtab[2]; unsigned const *const chains = &buckets[nbucket]; unsigned const m = elf_hash(name) % nbucket; + if (!nbucket + || (unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image)) + <= sizeof(unsigned)*nbucket ) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad nbucket %#x\n", nbucket); + throwCantPack(msg); + } unsigned si; for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) { char const *const p= get_dynsym_name(si, (unsigned)-1); @@ -5372,6 +5397,19 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const unsigned const *const bitmask = &gashtab[4]; unsigned const *const buckets = &bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; + if (!n_bucket + || (void const *)&file_image[file_size] <= (void const *)hasharr) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bucket %#x\n", n_bucket); + throwCantPack(msg); + } + if (!n_bitmask + || (unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image)) + <= sizeof(unsigned)*n_bitmask ) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bitmask %#x\n", n_bitmask); + throwCantPack(msg); + } unsigned const h = gnu_hash(name); unsigned const hbit1 = 037& h; @@ -5396,7 +5434,9 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const if (0==strcmp(name, p)) { return dsp; } - } while (++dsp, 0==(1u& get_te32(hp++))); + } while (++dsp, + (char const *)hp < (char const *)&file_image[file_size] + && 0==(1u& get_te32(hp++))); } } } @@ -5411,6 +5451,13 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const unsigned const *const buckets = &hashtab[2]; unsigned const *const chains = &buckets[nbucket]; unsigned const m = elf_hash(name) % nbucket; + if (!nbucket + || (unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image)) + <= sizeof(unsigned)*nbucket ) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad nbucket %#x\n", nbucket); + throwCantPack(msg); + } unsigned si; for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) { char const *const p= get_dynsym_name(si, (unsigned)-1); @@ -5427,6 +5474,19 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4]; unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; + if (!n_bucket + || (void const *)&file_image[file_size] <= (void const *)hasharr) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bucket %#x\n", n_bucket); + throwCantPack(msg); + } + if (!n_bitmask + || (unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image)) + <= sizeof(unsigned)*n_bitmask ) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bitmask %#x\n", n_bitmask); + throwCantPack(msg); + } unsigned const h = gnu_hash(name); unsigned const hbit1 = 077& h; @@ -5451,7 +5511,9 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const if (0==strcmp(name, p)) { return dsp; } - } while (++dsp, 0==(1u& get_te32(hp++))); + } while (++dsp, + (char const *)hp < (char const *)&file_image[file_size] + && 0==(1u& get_te32(hp++))); } } } diff --git a/src/p_lx_sh.cpp b/src/p_lx_sh.cpp index 70e6fdc3..30c60dcc 100644 --- a/src/p_lx_sh.cpp +++ b/src/p_lx_sh.cpp @@ -114,7 +114,7 @@ bool PackLinuxI386sh::getShellName(char *buf) buf[l_shname] = 0; static char const *const shname[] = { // known shells that accept "-c" arg "ash", "bash", "bsh", "csh", "ksh", "pdksh", "sh", "tcsh", "zsh", - "python", + "python", "python2", "python3", NULL }; const char *bname = strrchr(buf, '/'); diff --git a/src/pefile.cpp b/src/pefile.cpp index 571c3529..1988321f 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -2693,15 +2693,7 @@ void PeFile::rebuildRelocs(upx_byte *& extrainfo, unsigned bits, } rel.finish (oxrelocs,soxrelocs); - if (opt->win32_pe.strip_relocs && !isdll) - { - obuf.clear(ODADDR(PEDIR_RELOC) - rvamin, ODSIZE(PEDIR_RELOC)); - ODADDR(PEDIR_RELOC) = 0; - soxrelocs = 0; - // FIXME: try to remove the original relocation section somehow - } - else - omemcpy(obuf + ODADDR(PEDIR_RELOC) - rvamin,oxrelocs,soxrelocs); + omemcpy(obuf + ODADDR(PEDIR_RELOC) - rvamin,oxrelocs,soxrelocs); delete [] oxrelocs; oxrelocs = NULL; wrkmem.dealloc(); @@ -2933,12 +2925,8 @@ void PeFile::unpack0(OutputFile *fo, const ht &ih, ht &oh, ft.unfilter(obuf + oh.codebase - rvamin, oh.codesize); } - //NEW: disable reloc stripping if ASLR is enabled - if(ih.dllflags & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE) - opt->win32_pe.strip_relocs = false; - // FIXME: ih.flags is checked here because of a bug in UPX 0.92 - if ((opt->win32_pe.strip_relocs && !isdll) || (ih.flags & RELOCS_STRIPPED)) + if (ih.flags & RELOCS_STRIPPED) { oh.flags |= RELOCS_STRIPPED; ODADDR(PEDIR_RELOC) = 0; diff --git a/src/stub/Makefile b/src/stub/Makefile index 0add5541..134e0b2c 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -206,7 +206,7 @@ tc_objdump_disasm_options = ECHO_e = /bin/echo -e ECHO_E = /bin/echo -E PERL = perl -PYTHON = python +PYTHON = python2 UNIX2DOS := $(PERL) -i -pe 's/$$/\r/;' # trim (strip) trailing whitespace diff --git a/src/stub/scripts/bin2h.py b/src/stub/scripts/bin2h.py index d47e73d5..b30e3c89 100644 --- a/src/stub/scripts/bin2h.py +++ b/src/stub/scripts/bin2h.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python2 ## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*- # # bin2h.py -- diff --git a/src/stub/scripts/brandelf.py b/src/stub/scripts/brandelf.py index 508ee5f2..bcafb111 100644 --- a/src/stub/scripts/brandelf.py +++ b/src/stub/scripts/brandelf.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python2 ## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*- # # brandelf.py -- diff --git a/src/stub/scripts/gpp_inc.py b/src/stub/scripts/gpp_inc.py index f183fa51..3c0a9083 100644 --- a/src/stub/scripts/gpp_inc.py +++ b/src/stub/scripts/gpp_inc.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python2 ## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*- # # gpp_inc.py -- Generic PreProcessor: include diff --git a/src/stub/scripts/xstrip.py b/src/stub/scripts/xstrip.py index 29d2169f..2d8c07c3 100644 --- a/src/stub/scripts/xstrip.py +++ b/src/stub/scripts/xstrip.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python2 ## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*- # # xstrip.py -- truncate ELF objects created by multiarch-objcopy-2.17 diff --git a/src/stub/src/arch/i086/cleanasm.py b/src/stub/src/arch/i086/cleanasm.py index c10f2f87..605b4db4 100644 --- a/src/stub/src/arch/i086/cleanasm.py +++ b/src/stub/src/arch/i086/cleanasm.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python2 ## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*- # # cleanasm.py -- diff --git a/src/stub/src/arch/i086/wdis2gas.py b/src/stub/src/arch/i086/wdis2gas.py index b0a377d8..e99c7530 100644 --- a/src/stub/src/arch/i086/wdis2gas.py +++ b/src/stub/src/arch/i086/wdis2gas.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python2 ## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*- # # wdis2gas.py --