mirror of https://github.com/upx/upx.git
32-bit ARM Android shlib: DT_INIT_ARRAY without DT_INIT
De-compressor needs to catch up. modified: p_elf_enum.h modified: p_lx_elf.cpp modified: p_lx_elf.h modified: stub/src/i386-linux.elf-so_main.c
This commit is contained in:
parent
5b113a5041
commit
06fae05910
|
@ -229,6 +229,12 @@
|
|||
#undef WANT_REL_ENUM
|
||||
static inline unsigned ELF32_R_TYPE(unsigned x) { return 0xff & x; }
|
||||
static inline unsigned ELF64_R_TYPE(upx_uint64_t x) { return 0xffffffff & (unsigned)x; }
|
||||
static inline unsigned ELF32_R_SYM(unsigned x) { return x >> 8; }
|
||||
static inline unsigned ELF64_R_SYM(upx_uint64_t x) { return x >> 32; }
|
||||
static inline unsigned ELF32_R_INFO(unsigned sym, unsigned type)
|
||||
{ return (sym << 8) + (type & 0xff); }
|
||||
static inline upx_int64_t ELF64_R_INFO(unsigned sym, unsigned type)
|
||||
{ return ((upx_uint64_t)sym << 32) + type; }
|
||||
|
||||
# undef R_PPC_RELATIVE
|
||||
# undef R_PPC64_RELATIVE
|
||||
|
|
125
src/p_lx_elf.cpp
125
src/p_lx_elf.cpp
|
@ -252,6 +252,7 @@ PackLinuxElf::PackLinuxElf(InputFile *f)
|
|||
{
|
||||
memset(dt_table, 0, sizeof(dt_table));
|
||||
symnum_end = 0;
|
||||
user_init_rp = nullptr;
|
||||
}
|
||||
|
||||
PackLinuxElf::~PackLinuxElf()
|
||||
|
@ -346,7 +347,7 @@ PackLinuxElf32::PackLinuxElf32help1(InputFile *f)
|
|||
for (int j = e_phnum; --j>=0; ++phdr)
|
||||
if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
||||
unsigned offset = check_pt_dynamic(phdr);
|
||||
dynseg= (Elf32_Dyn const *)(offset + file_image);
|
||||
dynseg= (Elf32_Dyn *)(offset + file_image);
|
||||
invert_pt_dynamic(dynseg,
|
||||
umin(get_te32(&phdr->p_filesz), file_size - offset));
|
||||
}
|
||||
|
@ -426,7 +427,6 @@ off_t PackLinuxElf::pack3(OutputFile *fo, Filter &ft) // return length of output
|
|||
super::pack3(fo, ft); // append the decompressor
|
||||
set_te16(&linfo.l_lsize, up4( // MATCH03: up4
|
||||
get_te16(&linfo.l_lsize) + len - sz_pack2a));
|
||||
|
||||
total_out = fpad4(fo, total_out); // MATCH03
|
||||
return total_out;
|
||||
}
|
||||
|
@ -525,10 +525,13 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||
elfout.phdr[C_TEXT].p_paddr = elfout.phdr[C_TEXT].p_vaddr;
|
||||
set_te32(&elfout.ehdr.e_entry, abrk + get_te32(&elfout.ehdr.e_entry) - vbase);
|
||||
}
|
||||
if (0!=xct_off) { // shared library
|
||||
if (0!=xct_off) { // shared library
|
||||
unsigned word = (Elf32_Ehdr::EM_ARM==e_machine) + load_va + sz_pack2; // Thumb mode
|
||||
set_te32(&file_image[user_init_off], word); // set the hook
|
||||
|
||||
Elf32_Dyn *dynp = (Elf32_Dyn *)elf_find_dynptr(Elf32_Dyn::DT_NULL);
|
||||
set_te32(&dynp->d_val, (char *)user_init_rp - (char *)&file_image[0]);
|
||||
|
||||
Elf32_Phdr *const phdr0 = (Elf32_Phdr *)lowmem.subref(
|
||||
"bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
|
||||
Elf32_Phdr *phdr = phdr0;
|
||||
|
@ -584,6 +587,13 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||
fo->write(&file_image[ioff], len);
|
||||
off += len;
|
||||
total_out = off;
|
||||
|
||||
if ((user_init_off - ioff) < len) {
|
||||
fo->seek(user_init_off + so_slide, SEEK_SET);
|
||||
set_te32(&word, word);
|
||||
fo->rewrite(&word, sizeof(word));
|
||||
fo->seek(0, SEEK_END);
|
||||
}
|
||||
}
|
||||
continue; // all done with this PT_LOAD
|
||||
}
|
||||
|
@ -617,7 +627,7 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||
fo->seek(new_off, SEEK_SET);
|
||||
fo->rewrite(&file_image[old_off], n_jmp_slot * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fo->seek(total_out, SEEK_SET);
|
||||
if (xct_off < e_shoff) {
|
||||
|
@ -975,7 +985,7 @@ PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
|
|||
for (int j = e_phnum; --j>=0; ++phdr)
|
||||
if (Elf64_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
||||
upx_uint64_t offset = check_pt_dynamic(phdr);
|
||||
dynseg= (Elf64_Dyn const *)(offset + file_image);
|
||||
dynseg= (Elf64_Dyn *)(offset + file_image);
|
||||
invert_pt_dynamic(dynseg,
|
||||
umin(get_te64(&phdr->p_filesz), file_size - offset));
|
||||
}
|
||||
|
@ -2530,6 +2540,7 @@ bool PackLinuxElf32::canPack()
|
|||
sec_strndx = nullptr;
|
||||
shstrtab = nullptr;
|
||||
if (e_shnum) {
|
||||
e_shstrndx = get_te16(&ehdr->e_shstrndx);
|
||||
if (e_shstrndx) {
|
||||
if (e_shnum <= e_shstrndx) {
|
||||
char msg[40]; snprintf(msg, sizeof(msg),
|
||||
|
@ -2573,7 +2584,7 @@ bool PackLinuxElf32::canPack()
|
|||
for (int j= e_phnum; --j>=0; ++phdr)
|
||||
if (Elf32_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
||||
unsigned offset = check_pt_dynamic(phdr);
|
||||
dynseg= (Elf32_Dyn const *)(offset + file_image);
|
||||
dynseg= (Elf32_Dyn *)(offset + file_image);
|
||||
invert_pt_dynamic(dynseg,
|
||||
umin(get_te32(&phdr->p_filesz), file_size - offset));
|
||||
}
|
||||
|
@ -2651,10 +2662,11 @@ bool PackLinuxElf32::canPack()
|
|||
xct_va = umin(xct_va, get_te32(&shdr->sh_addr));
|
||||
}
|
||||
// Hook the first slot of DT_PREINIT_ARRAY or DT_INIT_ARRAY.
|
||||
if (( Elf32_Dyn::DT_PREINIT_ARRAY==upx_dt_init
|
||||
if (!user_init_rp && (
|
||||
( Elf32_Dyn::DT_PREINIT_ARRAY==upx_dt_init
|
||||
&& Elf32_Shdr::SHT_PREINIT_ARRAY==sh_type)
|
||||
|| ( Elf32_Dyn::DT_INIT_ARRAY ==upx_dt_init
|
||||
&& Elf32_Shdr::SHT_INIT_ARRAY ==sh_type) ) {
|
||||
&& Elf32_Shdr::SHT_INIT_ARRAY ==sh_type) )) {
|
||||
unsigned user_init_ava = get_te32(&shdr->sh_addr);
|
||||
user_init_off = get_te32(&shdr->sh_offset);
|
||||
if ((u32_t)file_size <= user_init_off) {
|
||||
|
@ -2664,7 +2676,7 @@ bool PackLinuxElf32::canPack()
|
|||
throwCantPack(msg);
|
||||
}
|
||||
// Check that &file_image[user_init_off] has
|
||||
// *_RELATIVE relocation, and fetch user_init_va.
|
||||
// *_RELATIVE or *_ABS* relocation, and fetch user_init_va.
|
||||
// If Elf32_Rela then the actual value is in Rela.r_addend.
|
||||
int z_rel = dt_table[Elf32_Dyn::DT_REL];
|
||||
int z_rsz = dt_table[Elf32_Dyn::DT_RELSZ];
|
||||
|
@ -2688,13 +2700,39 @@ bool PackLinuxElf32::canPack()
|
|||
for (; rp < last; ++rp) {
|
||||
unsigned r_va = get_te32(&rp->r_offset);
|
||||
if (r_va == user_init_ava) { // found the Elf32_Rel
|
||||
user_init_rp = rp;
|
||||
unsigned r_info = get_te32(&rp->r_info);
|
||||
unsigned r_type = ELF32_R_TYPE(r_info);
|
||||
if ((Elf32_Ehdr::EM_ARM == e_machine && R_ARM_RELATIVE == r_type)
|
||||
|| (Elf32_Ehdr::EM_386 == e_machine && R_386_RELATIVE == r_type) ) {
|
||||
user_init_va = get_te32(&file_image[user_init_off]);
|
||||
if (Elf32_Ehdr::EM_ARM == e_machine) {
|
||||
if (R_ARM_RELATIVE == r_type) {
|
||||
user_init_va = get_te32(&file_image[user_init_off]);
|
||||
}
|
||||
else if (R_ARM_ABS32 == r_type) {
|
||||
unsigned symj = ELF32_R_SYM(r_info);
|
||||
user_init_va = get_te32(&dynsym[symj].st_value);
|
||||
set_te32(&rp->r_info, ELF32_R_INFO(0, R_ARM_RELATIVE));
|
||||
// pack3() will set &file_image[user_init_off]
|
||||
}
|
||||
else {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
else if (Elf32_Ehdr::EM_386 == e_machine) {
|
||||
if (R_386_RELATIVE == r_type) {
|
||||
user_init_va = get_te32(&file_image[user_init_off]);
|
||||
}
|
||||
else if (R_386_32 == r_type) {
|
||||
unsigned symj = ELF32_R_SYM(r_info);
|
||||
user_init_va = get_te32(&dynsym[symj].st_value);
|
||||
set_te32(&rp->r_info, ELF32_R_INFO(0, R_386_RELATIVE));
|
||||
// pack3() will set &file_image[user_init_off]
|
||||
}
|
||||
else {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bad:
|
||||
char msg[50]; snprintf(msg, sizeof(msg),
|
||||
"bad relocation %#x DT_INIT_ARRAY[0]",
|
||||
r_info);
|
||||
|
@ -2847,9 +2885,6 @@ PackLinuxElf64::canPack()
|
|||
} u;
|
||||
COMPILE_TIME_ASSERT(sizeof(u) <= (2*1024))
|
||||
|
||||
// See explanation at PackLinuxElf32::canPack
|
||||
opt->o_unix.android_shlib = 0;
|
||||
|
||||
fi->readx(u.buf, sizeof(u.buf));
|
||||
fi->seek(0, SEEK_SET);
|
||||
Elf64_Ehdr const *const ehdr = (Elf64_Ehdr *) u.buf;
|
||||
|
@ -2972,7 +3007,7 @@ PackLinuxElf64::canPack()
|
|||
for (int j= e_phnum; --j>=0; ++phdr)
|
||||
if (Elf64_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) {
|
||||
upx_uint64_t offset = check_pt_dynamic(phdr);
|
||||
dynseg= (Elf64_Dyn const *)(offset + file_image);
|
||||
dynseg= (Elf64_Dyn *)(offset + file_image);
|
||||
invert_pt_dynamic(dynseg,
|
||||
umin(get_te64(&phdr->p_filesz), file_size - offset));
|
||||
}
|
||||
|
@ -4901,14 +4936,26 @@ int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft)
|
|||
}
|
||||
else { // Just copy up to xct_off
|
||||
x.size = umin(x.size, xct_off - x.offset);
|
||||
fi->seek(x.offset, SEEK_SET);
|
||||
fi->readx(ibuf, x.size);
|
||||
total_in += x.size;
|
||||
if (0) { // DEBUG paranoia
|
||||
fi->seek(x.offset, SEEK_SET);
|
||||
fi->readx(ibuf, x.size);
|
||||
total_in += x.size;
|
||||
unsigned const *fip = (unsigned const *)file_image.getVoidPtr();
|
||||
unsigned const *ibp = (unsigned const *)ibuf.getVoidPtr();
|
||||
for (unsigned j = 0; j < x.size>>2; ++j) {
|
||||
if (fip[j] != ibp[j]) {
|
||||
printf("[%#x]: file_image %#x ibuf %#x\n", j, fip[j], ibp[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: adler2 ?
|
||||
fo->seek(x.offset, SEEK_SET);
|
||||
fo->write(ibuf, x.size);
|
||||
fo->write(&file_image[x.offset], x.size);
|
||||
total_out += x.size;
|
||||
// Kepp the input side in sync
|
||||
total_in += x.size;
|
||||
fi->seek(x.size + x.offset, SEEK_SET);
|
||||
}
|
||||
if (hdr_u_len) { // first time
|
||||
linfo.l_checksum = 0; // preliminary
|
||||
|
@ -5537,7 +5584,7 @@ void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
|
|||
fo->rewrite(&tmp, sizeof(tmp));
|
||||
}
|
||||
}
|
||||
else {
|
||||
else { // not shlib
|
||||
Elf32_Phdr *phdr = &elfout.phdr[C_NOTE];
|
||||
if (PT_NOTE32== get_te32(&phdr->p_type)) {
|
||||
upx_uint32_t const reloc = get_te32(&elfout.phdr[C_TEXT].p_vaddr);
|
||||
|
@ -5851,6 +5898,8 @@ PackLinuxElf32::un_asl_dynsym( // ibuf has the input
|
|||
// overlay_offset:
|
||||
// 5. p_info (12 bytes)
|
||||
// 6. compressed original Elf headers (prefixed by b_info as usual)
|
||||
// 6a. un-compressed copy of input after Elf headers until xct_off.
|
||||
// *user_init_rp has been modified if no DT_INIT
|
||||
// 7. compressed remainder of PT_LOAD above xct_off
|
||||
// 8. compressed read-only PT_LOAD above xct_off (if any) // FIXME: check decompressor
|
||||
// 9. uncompressed Read-Write PT_LOAD (slide down N pages)
|
||||
|
@ -7035,18 +7084,32 @@ PackLinuxElf32::check_pt_dynamic(Elf32_Phdr const *const phdr)
|
|||
return t;
|
||||
}
|
||||
|
||||
void const *
|
||||
Elf32_Dyn *PackLinuxElf32::elf_find_dynptr(unsigned int key) const
|
||||
{
|
||||
Elf32_Dyn *dynp= dynseg;
|
||||
if (dynp) {
|
||||
Elf32_Dyn *const last = (Elf32_Dyn *)(sz_dynseg + (char *)dynseg);
|
||||
for (; dynp < last; ++dynp) {
|
||||
if (get_te32(&dynp->d_tag)==key) {
|
||||
return dynp;
|
||||
}
|
||||
if (Elf32_Dyn::DT_NULL == dynp->d_tag) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *
|
||||
PackLinuxElf32::elf_find_dynamic(unsigned int key) const
|
||||
{
|
||||
Elf32_Dyn const *dynp= dynseg;
|
||||
if (dynp)
|
||||
for (; (unsigned)((char const *)dynp - (char const *)dynseg) < sz_dynseg
|
||||
&& Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) {
|
||||
Elf32_Dyn const *dynp= elf_find_dynptr(key);
|
||||
if (dynp) {
|
||||
unsigned const t= elf_get_offset_from_address(get_te32(&dynp->d_val));
|
||||
if (t && t < (unsigned)file_size) {
|
||||
return t + file_image;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -7054,10 +7117,8 @@ PackLinuxElf32::elf_find_dynamic(unsigned int key) const
|
|||
upx_uint64_t
|
||||
PackLinuxElf32::elf_unsigned_dynamic(unsigned int key) const
|
||||
{
|
||||
Elf32_Dyn const *dynp= dynseg;
|
||||
if (dynp)
|
||||
for (; (unsigned)((char const *)dynp - (char const *)dynseg) < sz_dynseg
|
||||
&& Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) {
|
||||
Elf32_Dyn const *dynp= elf_find_dynptr(key);
|
||||
if (dynp) {
|
||||
return get_te32(&dynp->d_val);
|
||||
}
|
||||
return 0;
|
||||
|
@ -7396,7 +7457,7 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
|
|||
}
|
||||
}
|
||||
|
||||
void const *
|
||||
void *
|
||||
PackLinuxElf64::elf_find_dynamic(unsigned int key) const
|
||||
{
|
||||
Elf64_Dyn const *dynp= dynseg;
|
||||
|
|
|
@ -104,6 +104,7 @@ protected:
|
|||
upx_uint64_t xct_va; // minimum SHT_EXECINSTR virtual address
|
||||
upx_uint64_t jni_onload_va; // runtime &JNI_OnLoad
|
||||
upx_uint64_t user_init_va;
|
||||
void *user_init_rp; // Elf32_Rel *, Elf64_Rela *, ...
|
||||
upx_uint64_t plt_va, plt_off;
|
||||
unsigned user_init_off; // within file_image
|
||||
unsigned linfo_off;
|
||||
|
@ -200,6 +201,7 @@ protected:
|
|||
Elf32_Phdr const *elf_find_ptype(unsigned type, Elf32_Phdr const *phdr0, unsigned phnum);
|
||||
Elf32_Shdr const *elf_find_section_name(char const *) const;
|
||||
Elf32_Shdr *elf_find_section_type(unsigned) const;
|
||||
Elf32_Dyn *elf_find_dynptr(unsigned) const;
|
||||
unsigned elf_find_table_size(unsigned dt_type, unsigned sh_type);
|
||||
void sort_DT32_offsets(Elf32_Dyn const *const dynp0);
|
||||
|
||||
|
@ -207,7 +209,7 @@ protected:
|
|||
unsigned check_pt_load(Elf32_Phdr const *);
|
||||
unsigned check_pt_dynamic(Elf32_Phdr const *);
|
||||
void invert_pt_dynamic(Elf32_Dyn const *, unsigned dt_filesz);
|
||||
void const *elf_find_dynamic(unsigned) const;
|
||||
void *elf_find_dynamic(unsigned) const;
|
||||
Elf32_Dyn const *elf_has_dynamic(unsigned) const;
|
||||
virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const override;
|
||||
unsigned find_dt_ndx(unsigned rva);
|
||||
|
@ -228,7 +230,7 @@ protected:
|
|||
unsigned plt_off;
|
||||
unsigned page_mask; // AND clears the offset-within-page
|
||||
|
||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
||||
Elf32_Dyn *dynseg; // from PT_DYNAMIC
|
||||
unsigned int const *hashtab, *hashend; // from DT_HASH
|
||||
unsigned int const *gashtab, *gashend; // from DT_GNU_HASH
|
||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||
|
@ -360,7 +362,7 @@ protected:
|
|||
upx_uint64_t check_pt_load(Elf64_Phdr const *);
|
||||
upx_uint64_t check_pt_dynamic(Elf64_Phdr const *);
|
||||
void invert_pt_dynamic(Elf64_Dyn const *, upx_uint64_t dt_filesz);
|
||||
void const *elf_find_dynamic(unsigned) const;
|
||||
void *elf_find_dynamic(unsigned) const;
|
||||
Elf64_Dyn const *elf_has_dynamic(unsigned) const;
|
||||
virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const override;
|
||||
unsigned find_dt_ndx(u64_t rva);
|
||||
|
@ -380,7 +382,7 @@ protected:
|
|||
unsigned n_jmp_slot;
|
||||
upx_uint64_t page_mask; // AND clears the offset-within-page
|
||||
|
||||
Elf64_Dyn const *dynseg; // from PT_DYNAMIC
|
||||
Elf64_Dyn *dynseg; // from PT_DYNAMIC
|
||||
unsigned int const *hashtab, *hashend; // from DT_HASH
|
||||
unsigned int const *gashtab, *gashend; // from DT_GNU_HASH
|
||||
Elf64_Sym const *dynsym; // from DT_SYMTAB
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
extern void my_bkpt(void const *arg1, ...);
|
||||
|
||||
#define DEBUG 0
|
||||
#define DEBUG 1
|
||||
|
||||
void *mmap(void *, size_t, int, int, int, off_t);
|
||||
#if defined(__i386__) || defined(__mips__) || defined(__powerpc__) //{
|
||||
|
@ -525,37 +525,26 @@ upx_so_main( // returns &escape_hatch
|
|||
Extent x0 = {binfo->sz_cpr + sizeof(*binfo), (char *)binfo}; // source
|
||||
unpackExtent(&x0, &x1); // de-compress Elf headers; x0.buf is updated
|
||||
|
||||
// Count PT_LOAD; n_LOAD < 3 is special (old binutils PT_LOAD layout)
|
||||
unsigned n_phdr;
|
||||
Elf32_Phdr const *phdr;
|
||||
n_phdr = ((Elf32_Ehdr *)(void *)va_load)->e_phnum;
|
||||
phdr = (Elf32_Phdr *)(1+ (Elf32_Ehdr *)(void *)va_load);
|
||||
unsigned n_LOAD = 0;
|
||||
for (; n_phdr > 0; --n_phdr, ++phdr) {
|
||||
n_LOAD += (PT_LOAD == phdr->p_type);
|
||||
}
|
||||
// Old-style binutils with only 2 PT_LOAD: (r-x) and (rw-)
|
||||
// has xct_off in middle of first PT_LOAD.
|
||||
// New-style binutils has xct-off at beginning of 2nd PT_LOAD.
|
||||
Elf32_Addr pfx = (n_LOAD <= 2) ? so_infc.off_xct_off : 0;
|
||||
|
||||
// Process each read-only PT_LOAD.
|
||||
// A read+write PT_LOAD might be relocated by rtld before de-compression,
|
||||
// so it cannot be compressed.
|
||||
struct b_info al_bi; // for aligned data from binfo
|
||||
void *hatch = nullptr;
|
||||
unsigned not_first = 0;
|
||||
|
||||
n_phdr = ((Elf32_Ehdr *)(void *)va_load)->e_phnum;
|
||||
phdr = (Elf32_Phdr *)(1+ (Elf32_Ehdr *)(void *)va_load);
|
||||
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ (Elf32_Ehdr *)(void *)va_load);
|
||||
unsigned n_phdr = ((Elf32_Ehdr *)(void *)va_load)->e_phnum;
|
||||
for (; n_phdr > 0; --n_phdr, ++phdr)
|
||||
if ( phdr->p_type == PT_LOAD
|
||||
&& !(phdr->p_flags & PF_W)
|
||||
&& (not_first++ || n_LOAD < 3)
|
||||
) {
|
||||
DPRINTF("phdr@%%p .p_vaddr=%%p .p_filesz=%%p .p_memsz=%%p n_LOAD=%%p binfo=%%p\\n",
|
||||
phdr, phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz, n_LOAD, x0.buf);
|
||||
if ( phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_W)) {
|
||||
DPRINTF("phdr@%%p p_offset=%%p p_vaddr=%%p p_filesz=%%p p_memsz=%%p binfo=%%p\\n",
|
||||
phdr, phdr->p_offset, phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz, x0.buf);
|
||||
|
||||
if ((phdr->p_filesz + phdr->p_offset) <= so_infc.off_xct_off) {
|
||||
continue; // below compressed region
|
||||
}
|
||||
Elf32_Addr pfx = so_infc.off_xct_off - phdr->p_offset;
|
||||
if ( so_infc.off_xct_off < phdr->p_offset) {
|
||||
pfx = 0; // no more partially-compressed PT_LOAD
|
||||
}
|
||||
x0.size = sizeof(struct b_info);
|
||||
xread(&x0, (char *)&al_bi, x0.size); // aligned binfo
|
||||
x0.buf -= sizeof(al_bi); // back up (the xread() was a peek)
|
||||
|
@ -563,9 +552,11 @@ upx_so_main( // returns &escape_hatch
|
|||
al_bi.sz_unc, al_bi.sz_cpr, *(unsigned *)(void *)&al_bi.b_method);
|
||||
|
||||
// Using .p_memsz implicitly handles .bss via MAP_ANONYMOUS.
|
||||
// Omit any not-compressed prefix (below xct_off)
|
||||
x1.buf = phdr->p_vaddr + pfx + va_load;
|
||||
x1.size = phdr->p_memsz - pfx;
|
||||
pfx = (phdr->p_vaddr + pfx) & ~PAGE_MASK;
|
||||
|
||||
pfx = (phdr->p_vaddr + pfx) & ~PAGE_MASK; // lo fragment on page
|
||||
x1.buf -= pfx;
|
||||
x1.size += pfx;
|
||||
DPRINTF("mmap(%%p %%p) xct_off=%%x pfx=%%x\\n", x1.buf, x1.size, xct_off, pfx);
|
||||
|
@ -575,7 +566,6 @@ upx_so_main( // returns &escape_hatch
|
|||
x1.size = al_bi.sz_unc;
|
||||
x0.size = al_bi.sz_cpr + sizeof(struct b_info);
|
||||
unpackExtent(&x0, &x1); // updates x0 and x1
|
||||
pfx = 0; // consider xct_off at most once
|
||||
|
||||
if (!hatch && phdr->p_flags & PF_X) {
|
||||
//#define PAGE_MASK ~0xFFFull
|
||||
|
@ -587,8 +577,9 @@ upx_so_main( // returns &escape_hatch
|
|||
hatch = make_hatch_i386(phdr, (Elf32_Addr)va_load);
|
||||
#endif //}
|
||||
}
|
||||
DPRINTF("mprotect %%p (%%p %%p)\\n", phdr, phdr->p_vaddr + va_load, phdr->p_memsz);
|
||||
mprotect(phdr->p_vaddr + va_load, phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
|
||||
DPRINTF("mprotect %%p (%%p %%p %%x)\\n",
|
||||
phdr, phdr->p_vaddr + va_load, phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
|
||||
mprotect( phdr->p_vaddr + va_load, phdr->p_memsz, PF_TO_PROT(phdr->p_flags));
|
||||
}
|
||||
|
||||
typedef void (*Dt_init)(int argc, char *argv[], char *envp[]);
|
||||
|
|
Loading…
Reference in New Issue