mirror of https://github.com/upx/upx.git
src/stub: fix ET_DYN with non-zero PT_LOAD[0].p_vaddr
This commit is contained in:
parent
e29e73a4e4
commit
23c70ec447
|
@ -502,18 +502,14 @@ do_xmap(
|
|||
ElfW(Addr) reloc = 0;
|
||||
if (xi) { // compressed main program:
|
||||
// C_BASE space reservation, C_TEXT compressed data and stub
|
||||
ElfW(Addr) ehdr0 = *p_reloc; // the 'hi' copy!
|
||||
ElfW(Addr) ehdr0 = *p_reloc;
|
||||
ElfW(Phdr) *phdr0 = (ElfW(Phdr) *)(1+ (ElfW(Ehdr) *)ehdr0); // cheats .e_phoff
|
||||
// Clear the 'lo' space reservation for use by PT_LOADs
|
||||
ehdr0 -= phdr0[1].p_vaddr; // the 'lo' copy
|
||||
if (ET_EXEC == ehdr->e_type) {
|
||||
ehdr0 = phdr0[0].p_vaddr;
|
||||
v_brk = ehdr0 + phdr0->p_vaddr + phdr0->p_memsz;
|
||||
if (ET_DYN == ehdr->e_type) {
|
||||
reloc = ehdr0 - phdr0[1].p_vaddr;
|
||||
}
|
||||
else {
|
||||
reloc = ehdr0;
|
||||
}
|
||||
v_brk = phdr0->p_memsz + ehdr0;
|
||||
munmap((void *)ehdr0, phdr0->p_memsz);
|
||||
// paranoia: prevent "hangover" from VMA for C_BASE
|
||||
munmap((void *)(reloc + phdr0->p_vaddr), phdr0->p_memsz);
|
||||
}
|
||||
else { // PT_INTERP
|
||||
DPRINTF("INTERP\\n", 0);
|
||||
|
|
|
@ -237,6 +237,13 @@ mfd .req old_sp
|
|||
call f_expand
|
||||
add sp,sp,#2*NBPW @ P_02, P_01 remove 5th param
|
||||
|
||||
|
||||
// faster than clearcache + msync; also avoids msync() bug
|
||||
ldr arg3,[sp,#F_LENU]
|
||||
ldr arg2,[sp,#F_ADRU]
|
||||
mov arg1,mfd
|
||||
do_sys __NR_write
|
||||
|
||||
mov r5,#0
|
||||
mov r4,mfd
|
||||
mov r3,#MAP_PRIVATE|MAP_FIXED
|
||||
|
|
|
@ -603,18 +603,14 @@ do_xmap(
|
|||
ElfW(Addr) reloc = 0;
|
||||
if (xi) { // compressed main program:
|
||||
// C_BASE space reservation, C_TEXT compressed data and stub
|
||||
ElfW(Addr) ehdr0 = *p_reloc; // the 'hi' copy!
|
||||
ElfW(Addr) ehdr0 = *p_reloc;
|
||||
ElfW(Phdr) *phdr0 = (ElfW(Phdr) *)(1+ (ElfW(Ehdr) *)ehdr0); // cheats .e_phoff
|
||||
// Clear the 'lo' space reservation for use by PT_LOADs
|
||||
ehdr0 -= phdr0[1].p_vaddr; // the 'lo' copy
|
||||
if (ET_EXEC == ehdr->e_type) {
|
||||
ehdr0 = phdr0[0].p_vaddr;
|
||||
v_brk = ehdr0 + phdr0->p_vaddr + phdr0->p_memsz;
|
||||
if (ET_DYN == ehdr->e_type) {
|
||||
reloc = ehdr0 - phdr0[1].p_vaddr;
|
||||
}
|
||||
else {
|
||||
reloc = ehdr0;
|
||||
}
|
||||
v_brk = phdr0->p_memsz + ehdr0;
|
||||
munmap((void *)ehdr0, phdr0->p_memsz);
|
||||
// paranoia: prevent "hangover" from VMA for C_BASE
|
||||
munmap((void *)(reloc + phdr0->p_vaddr), phdr0->p_memsz);
|
||||
}
|
||||
else { // PT_INTERP
|
||||
DPRINTF("INTERP ehdr=%%p av=%%p\\n", ehdr, av);
|
||||
|
@ -662,8 +658,8 @@ do_xmap(
|
|||
DPRINTF(" mlen=%%p\\n", mlen);
|
||||
#endif
|
||||
|
||||
DPRINTF("mmap addr=%%p mlen=%%p offset=%%p frag=%%p prot=%%x\\n",
|
||||
addr, mlen, phdr->p_offset - frag, frag, prot);
|
||||
DPRINTF("mmap addr=%%p mlen=%%p phdr=%%p offset=%%p frag=%%p prot=%%x\\n",
|
||||
addr, mlen, phdr, phdr->p_offset - frag, frag, prot);
|
||||
int mfd = 0;
|
||||
if (xi && phdr->p_flags & PF_X) { // SELinux
|
||||
// Cannot set PROT_EXEC except via mmap() into a region (Linux "vma")
|
||||
|
|
Loading…
Reference in New Issue