Merge branch 'devel' of https://github.com/upx/upx into jreiser-pageholes

This commit is contained in:
John Reiser
2020-05-28 15:45:46 -07:00
10 changed files with 74 additions and 24 deletions
+64 -2
View File
@@ -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++)));
}
}
}