Fix use of memfd_create for shlib stubs, espcially Android

Also relocation of init_array[0] for Elf32 shlib.
        https://github.com/upx/upx/issues/220
        https://github.com/upx/upx/issues/609
        https://github.com/upx/upx/issues/680

	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   p_lx_elf.cpp

	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/src/arm64-linux.elf-so_entry.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
	modified:   stub/src/i386-linux.elf-so_fold.S

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_entry.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
This commit is contained in:
John Reiser
2023-07-24 16:35:21 -07:00
committed by Markus F.X.J. Oberhumer
parent efbc93229a
commit 2684e815e0
14 changed files with 6172 additions and 6126 deletions
+4 -5
View File
@@ -502,6 +502,7 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
total_out = super::pack3(fo, ft); // loader follows compressed PT_LOADs
if (fo && xct_off && Elf32_Dyn::DT_INIT != upx_dt_init) { // patch user_init_rp
// init_array[0] must have R_$(ARCH)_RELATIVE relocation.
fo->seek((char *)user_init_rp - (char *)&file_image[0], SEEK_SET);
Elf32_Rel rel(*(Elf32_Rel const *)user_init_rp);
u32_t r_info = get_te32(&((Elf32_Rel const *)user_init_rp)->r_info);
@@ -512,12 +513,10 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
: 0;
set_te32(&rel.r_info, ELF32_R_INFO(ELF32_R_SYM(r_info), r_type));
fo->rewrite(&rel, sizeof(rel));
fo->seek((char *)user_init_rp - (char *)&file_image[0], SEEK_SET);
u32_t disp; set_te32(&disp, sz_pack2); // entry to decompressor
fo->rewrite(&disp, sizeof(disp));
fo->seek(0, SEEK_END);
// Value of init_array[0] will be changed later.
// See write() of 'cpr_entry' below.
}
// NOTE: PackLinuxElf::pack3 adjusted xct_off for the extra page
+1077 -1062
View File
File diff suppressed because it is too large Load Diff
+1563 -1555
View File
File diff suppressed because it is too large Load Diff
+1569 -1561
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -32,15 +32,15 @@
#define STUB_ARM64_LINUX_ELF_SO_ENTRY_SIZE 1891
#define STUB_ARM64_LINUX_ELF_SO_ENTRY_ADLER32 0x75cc7776
#define STUB_ARM64_LINUX_ELF_SO_ENTRY_CRC32 0x9c79c3e7
#define STUB_ARM64_LINUX_ELF_SO_ENTRY_ADLER32 0x7bdd7753
#define STUB_ARM64_LINUX_ELF_SO_ENTRY_CRC32 0x9ab682dd
unsigned char stub_arm64_linux_elf_so_entry[1891] = {
/* 0x0000 */ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x0010 */ 1, 0,183, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0,
/* 0x0030 */ 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 7, 0, 4, 0,
/* 0x0040 */ 31, 32, 3,213,224, 7,190,169,226,123, 1,169,255, 67, 0,209,
/* 0x0040 */ 0, 0, 32,212,224, 7,190,169,226,123, 1,169,255, 67, 0,209,
/* 0x0050 */ 0, 0, 0,148,238, 3, 0,145,192, 3, 64,185,192, 5, 0,249,
/* 0x0060 */ 224, 99, 32,203, 31,236,124,146,195, 33, 0,145,226, 3, 0,145,
/* 0x0070 */ 193, 7, 64,185,192, 51, 0,145, 28, 0, 0,148, 1, 0,128, 82,
+972 -958
View File
File diff suppressed because it is too large Load Diff
+860 -841
View File
File diff suppressed because it is too large Load Diff
+41 -54
View File
@@ -33,9 +33,11 @@
#include "include/linux.h"
// Pprotect is mprotect, but page-aligned on the lo end (Linux requirement)
unsigned Pprotect(void *, size_t, unsigned);
void *Pmap(void *, size_t, unsigned, unsigned, int, size_t);
int Punmap(void *, size_t);
extern unsigned Pprotect(void *, size_t, unsigned);
extern void *Pmap(void *, size_t, unsigned, unsigned, int, size_t);
extern int Punmap(void *, size_t);
extern size_t Pwrite(unsigned, void const *, size_t);
extern int ftruncate(int fd, off_t length);
extern void f_int3(int arg);
@@ -245,29 +247,26 @@ extern int memfd_create(const char *name, unsigned int flags);
static char *
make_hatch_x86_64(
Elf64_Phdr const *const phdr,
char *base,
char *next_unc,
char *mfd_addr,
unsigned frag_mask
)
{
char *hatch = 0;
DPRINTF("make_hatch %%p %%p %%p %%p %%x\\n", phdr, base, next_unc, mfd_addr, frag_mask);
DPRINTF("make_hatch %%p %%p %%x\\n", phdr, next_unc, frag_mask);
if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {
next_unc += phdr->p_memsz - phdr->p_filesz; // Skip over local .bss
frag_mask &= -(long)next_unc; // bytes left on pge
frag_mask &= -(long)next_unc; // bytes left on page
if (6 <= frag_mask) {
hatch = next_unc;
(( long *)hatch)[0] = 0x5e5f050f; // syscall; pop %arg1{%rdi}; pop %arg2{%rsi}
((short *)hatch)[2] = 0xc35a; // pop %arg3{%rdx}; ret
hatch += phdr->p_vaddr + (base - mfd_addr); // relocate to eventual address
}
else { // Does not fit at hi end of .text, so must use a new page "permanently"
int mfd = memfd_create(addr_string("upx"), 0); // the directory entry
write(mfd, addr_string("\x0f\x05\x5f\x5e\x5a\xc3"), 6);
mfd_addr = mmap(0, 6, PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
ftruncate(mfd, 6);
Pwrite(mfd, addr_string("\x0f\x05\x5f\x5e\x5a\xc3"), 6);
hatch = Pmap(0, 6, PROT_READ|PROT_EXEC, MAP_SHARED, mfd, 0);
close(mfd);
hatch = mfd_addr;
}
}
DPRINTF("hatch=%%p\\n", hatch);
@@ -283,9 +282,7 @@ ORRX(unsigned ra, unsigned rs, unsigned rb) // or ra,rs,rb
static char *
make_hatch_ppc64(
Elf64_Phdr const *const phdr,
char *base,
char *next_unc,
char *mfd_addr,
unsigned frag_mask
)
{
@@ -296,25 +293,23 @@ make_hatch_ppc64(
0x4e800020, // blr
};
unsigned *hatch = 0;
DPRINTF("make_hatch %%p %%p %%p %%p %%x\\n", phdr, base, next_unc, mfd_addr, frag_mask);
DPRINTF("make_hatch %%p %%p %%x\\n", phdr, next_unc, frag_mask);
if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {
next_unc += phdr->p_memsz - phdr->p_filesz; // Skip over local .bss
frag_mask &= -(long)next_unc; // bytes left on pge
frag_mask &= -(long)next_unc; // bytes left on page
if (4*4 <= frag_mask) {
hatch = (unsigned *)(void *)next_unc;
hatch = (unsigned *)(void *)(~3ul & (long)(3+ next_unc);
hatch[0]= code[0];
hatch[1]= code[1];
hatch[2]= code[2];
hatch[3]= code[3];
char *t = (phdr->p_vaddr + base) + ((char *)hatch - mfd_addr);
hatch = (unsigned *)(void *)t;
}
else { // Does not fit at hi end of .text, so must use a new page "permanently"
int mfd = memfd_create(addr_string("upx"), 0); // the directory entry
write(mfd, code, sizeof(code));
mfd_addr = mmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
ftruncate(mfd,sizeof(code));
Pwrite(mfd, code, sizeof(code));
hatch = Pmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_SHARED, mfd, 0);
close(mfd);
hatch = mfd_addr;
}
}
DPRINTF("hatch=%%p\\n", hatch);
@@ -324,9 +319,7 @@ make_hatch_ppc64(
static char *
make_hatch_arm64(
Elf64_Phdr const *const phdr,
char *base,
char *next_unc,
char *mfd_addr,
unsigned frag_mask
)
{
@@ -337,25 +330,26 @@ make_hatch_arm64(
0xd61f03c0, // br x30
};
unsigned *hatch = 0;
DPRINTF("make_hatch %%p %%p %%p %%p %%x\\n", phdr, base, next_unc, mfd_addr, frag_mask);
DPRINTF("make_hatch phdr=%%p next_unc=%%p frag_mask= %%x\\n",
phdr, next_unc, frag_mask);
if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {
next_unc += phdr->p_memsz - phdr->p_filesz; // Skip over local .bss
frag_mask &= -(long)next_unc; // bytes left on pge
frag_mask &= -(long)next_unc; // bytes left on page
if (4*4 <= frag_mask) {
hatch = (unsigned *)(void *)next_unc;
hatch = (unsigned *)(void *)(~3ul & (long)(3+ next_unc));
hatch[0]= code[0];
hatch[1]= code[1];
hatch[2]= code[2];
hatch[3]= code[3];
char *t = (phdr->p_vaddr + base) + ((char *)hatch - mfd_addr);
hatch = (unsigned *)(void *)t;
hatch = (unsigned *)&hatch[0];
}
else { // Does not fit at hi end of .text, so must use a new page "permanently"
int mfd = memfd_create(addr_string("upx"), 0); // the directory entry
write(mfd, code, sizeof(code));
mfd_addr = mmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
ftruncate(mfd, sizeof(code));
Pwrite(mfd, code, sizeof(code));
void *mfd_addr = Pmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_SHARED, mfd, 0);
close(mfd);
hatch = (unsigned *)(void *)mfd_addr;
hatch = (unsigned *)mfd_addr;
}
}
DPRINTF("hatch=%%p\\n", hatch);
@@ -418,8 +412,6 @@ extern void
underlay(unsigned size, char *ptr, unsigned len);
#endif //}
extern int ftruncate(int fd, off_t length);
// Exchange the bits with values 4 (PF_R, PROT_EXEC) and 1 (PF_X, PROT_READ)
// Use table lookup into a PIC-string that pre-computes the result.
unsigned PF_to_PROT(Elf64_Phdr const *phdr)
@@ -506,12 +498,13 @@ upx_so_main( // returns &escape_hatch
if (phdr->p_flags & PF_X) {
int mfd = memfd_create(addr_string("upx"), 0);
unsigned mfd_len = 0ul - PAGE_MASK;
write(mfd, elf_tmp, binfo->sz_unc); // de-compressed Elf_Ehdr and Elf_Phdrs
write(mfd, binfo->sz_unc + va_load, mfd_len - binfo->sz_unc); // rest of 1st page
ftruncate(mfd, mfd_len);
Pwrite(mfd, elf_tmp, binfo->sz_unc); // de-compressed Elf_Ehdr and Elf_Phdrs
Pwrite(mfd, binfo->sz_unc + va_load, mfd_len - binfo->sz_unc); // rest of 1st page
munmap(va_load, mfd_len); // make SELinux forget any previous protection
Elf64_Addr va_mfd = (Elf64_Addr)mmap(va_load, mfd_len, PF_to_PROT(phdr),
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, mfd, 0); (void)va_mfd;
Punmap(va_load, mfd_len); // make SELinux forget any previous protection
Elf64_Addr va_mfd = (Elf64_Addr)Pmap(va_load, mfd_len, PF_to_PROT(phdr),
MAP_FIXED|MAP_SHARED, mfd, 0); (void)va_mfd;
close(mfd);
}
@@ -556,16 +549,10 @@ upx_so_main( // returns &escape_hatch
// to hold the contents.
mfd = memfd_create(addr_string("upx"), 0); // the directory entry
ftruncate(mfd, x1.size); // Allocate the pages in the file.
write(mfd, x1.buf, frag); // Save lo fragment of contents on first page.
mfd_addr = mmap(0, x1.size, PROT_READ|PROT_WRITE, MAP_SHARED, mfd, 0);
DPRINTF("mfd_addr= %%p\\n", mfd_addr); // Now "somewhere" in RAM,
// and ready to receive de-compressed bytes, and remember them in the
// file (MAP_SHARED) so that they can be mmap() according to *phdr.
// Must keep the original compressed data until now, in order to
// prevent the mmap(0, ...) from stealing that address range.
Punmap(x1.buf, x1.size); // Discard original page frames in RAM.
x1.buf = mfd_addr; // will add frag soon
Pwrite(mfd, x1.buf, frag); // Save lo fragment of contents on first page.
Punmap(x1.buf, x1.size);
mfd_addr = Pmap(x1.buf, x1.size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, mfd, 0);
DPRINTF("mfd_addr= %%p\\n", mfd_addr); // Re-use the address space
}
else {
underlay(x1.size, x1.buf, frag); // also makes PROT_WRITE
@@ -580,20 +567,20 @@ upx_so_main( // returns &escape_hatch
if (!hatch && phdr->p_flags & PF_X) {
#if defined(__x86_64) //{
hatch = make_hatch_x86_64(phdr, (char *)base, x1.buf, mfd_addr, ~PAGE_MASK);
hatch = make_hatch_x86_64(phdr, x1.buf, ~PAGE_MASK);
#elif defined(__powerpc64__) //}{
hatch = make_hatch_ppc64(phdr, (char *)base, x1.buf, mfd_addr, ~PAGE_MASK);
hatch = make_hatch_ppc64(phdr, x1.buf, ~PAGE_MASK);
#elif defined(__aarch64__) //}{
hatch = make_hatch_arm64(phdr, (char *)base, x1.buf, mfd_addr, ~PAGE_MASK);
hatch = make_hatch_arm64(phdr, x1.buf, ~PAGE_MASK);
#endif //}
}
if (phdr->p_flags & PF_X) { // SELinux
// Map the contents of mfd as per *phdr.
DPRINTF("mfd mmap addr=%%p len=%%p\\n", (phdr->p_vaddr + base + pfx), al_bi.sz_unc);
munmap(mfd_addr, frag + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
Punmap(mfd_addr, frag + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
Pmap((char *)(phdr->p_vaddr + base + pfx), al_bi.sz_unc, PF_to_PROT(phdr),
MAP_FIXED|MAP_PRIVATE, mfd, 0);
MAP_FIXED|MAP_SHARED, mfd, 0);
close(mfd);
}
else { // easy
@@ -601,7 +588,7 @@ upx_so_main( // returns &escape_hatch
}
}
munmap(sideaddr, cpr_len);
Punmap(sideaddr, cpr_len);
DPRINTF("calling user DT_INIT %%p\\n", dt_init);
dt_init(so_args->argc, so_args->argv, so_args->envp);
+3 -2
View File
@@ -154,8 +154,9 @@ exit:
read:
do_sys __NR_read; ret
.globl write
write:
Pwrite: .globl Pwrite
//int3
write: .globl write
do_sys __NR_write; ret
.globl open
+1 -1
View File
@@ -93,7 +93,7 @@ arg6w .req w5
.balign 4
_start: .globl _start
nop // bkpt // DEBUG
bkpt // DEBUG
PUSH4 (x0,x1,x2,lr) // MATCH_00
sub sp,sp,#2*NBPW // space for ADRU, LENU
+1
View File
@@ -118,6 +118,7 @@ memfd_create: .globl memfd_create; do_sys __NR_memfd_create; ret
read:
do_sys __NR_read; ret
Pwrite: .globl Pwrite
.globl write
write:
do_sys __NR_write; ret
+1 -1
View File
@@ -183,7 +183,6 @@ Punmap: .globl Punmap // from C
ret
memfd_create: .globl memfd_create
int3
push $__NR_memfd_create; 5: jmp 5f
mprotect: .globl mprotect
mov %ebx,%eax; and $-1+ (1<<12),%eax
@@ -196,6 +195,7 @@ close: .globl close
push $__NR_close; 5: jmp 5f
munmap: .globl munmap
push $ __NR_munmap; 5: jmp 5f
Pwrite: .globl Pwrite
write: .globl write
push $__NR_write; 5:
pop %eax
+28 -37
View File
@@ -49,6 +49,7 @@ int Punmap(void *, size_t);
void *mmap_privanon(void *, size_t, int, int);
#endif //}
ssize_t write(int, void const *, size_t);
ssize_t Pwrite(int, void const *, size_t);
/*************************************************************************
@@ -270,29 +271,26 @@ ERR_LAB
static char *
make_hatch_i386(
Elf32_Phdr const *const phdr,
char *base,
char *next_unc,
char *mfd_addr,
unsigned frag_mask
)
{
char *hatch = 0;
DPRINTF("make_hatch %%p %%p %%p %%p %%x\\n", phdr, base, next_unc, mfd_addr, frag_mask);
DPRINTF("make_hatch %%p %%p %%x\\n", phdr, next_unc, frag_mask);
if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {
next_unc += phdr->p_memsz - phdr->p_filesz; // Skip over local .bss
frag_mask &= -(long)next_unc; // bytes left on pge
frag_mask &= -(long)next_unc; // bytes left on page
unsigned /*const*/ escape = 0xc36180cd; // "int $0x80; popa; ret"
if (4 <= frag_mask) {
hatch = next_unc;
*(long *)&hatch[0] = escape;
hatch += phdr->p_vaddr + (base - mfd_addr); // relocate to eventual address
}
else { // Does not fit at hi end of .text, so must use a new page "permanently"
int mfd = memfd_create(addr_string("upx"), 0); // the directory entry
//ftruncate(mfd, 4);
write(mfd, &escape, 4);
mfd_addr = mmap(0, 4, PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
hatch = mmap(0, 4, PROT_READ|PROT_EXEC, MAP_SHARED, mfd, 0);
close(mfd);
hatch = mfd_addr;
}
}
DPRINTF("hatch=%%p\\n", hatch);
@@ -304,9 +302,7 @@ extern unsigned get_sys_munmap(void);
static void *
make_hatch_arm32(
Elf32_Phdr const *const phdr,
char *base,
char *next_unc,
char *mfd_addr,
unsigned frag_mask
)
{
@@ -316,25 +312,23 @@ make_hatch_arm32(
0xe8bd80ff, // ldmia sp!,{r0,r1,r2,r3,r4,r5,r6,r7,pc}
};
unsigned *hatch = 0;
DPRINTF("make_hatch %%p %%p %%p %%p %%x\\n", phdr, base, next_unc, mfd_addr, frag_mask);
DPRINTF("make_hatch %%p %%p %%x\\n", phdr, next_unc, frag_mask);
if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {
next_unc += phdr->p_memsz - phdr->p_filesz; // Skip over local .bss
frag_mask &= -(long)next_unc; // bytes left on pge
frag_mask &= -(long)next_unc; // bytes left on page
if (2*4 <= frag_mask) {
hatch = (unsigned *)(void *)next_unc;
hatch = (unsigned *)(void *)(~3ul & (long)(3+ next_unc));
hatch[0]= code[0];
hatch[1]= code[1];
char *t = (phdr->p_vaddr + base) + ((char *)hatch - mfd_addr);
__clear_cache(&hatch[0], &hatch[2]);
hatch = (unsigned *)(void *)t;
}
else { // Does not fit at hi end of .text, so must use a new page "permanently"
int mfd = memfd_create(addr_string("upx"), 0); // the directory entry
//ftruncate(mfd, 2*4);
write(mfd, &code, 2*4);
mfd_addr = mmap(0, 2*4, PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
hatch = Pmap(0, 2*4, PROT_READ|PROT_EXEC, MAP_SHARED, mfd, 0);
close(mfd);
hatch = (unsigned *)(void *)mfd_addr;
}
}
DPRINTF("hatch=%%p\\n", hatch);
@@ -561,12 +555,14 @@ upx_so_main( // returns &escape_hatch
if (phdr->p_flags & PF_X) {
int mfd = memfd_create(addr_string("upx"), 0);
unsigned mfd_len = 0ul - page_mask;
write(mfd, elf_tmp, binfo->sz_unc); // de-compressed Elf_Ehdr and Elf_Phdrs
write(mfd, binfo->sz_unc + va_load, mfd_len - binfo->sz_unc); // rest of 1st page
ftruncate(mfd, mfd_len);
Pwrite(mfd, elf_tmp, binfo->sz_unc); // de-compressed Elf_Ehdr and Elf_Phdrs
Pwrite(mfd, binfo->sz_unc + va_load, mfd_len - binfo->sz_unc); // rest of 1st page
Punmap(va_load, mfd_len); // make SELinux forget any previous protection
Elf32_Addr va_mfd = (Elf32_Addr)Pmap(va_load, mfd_len, PF_to_PROT(phdr),
MAP_FIXED|MAP_SHARED, mfd, 0); (void)va_mfd;
munmap(va_load, mfd_len); // make SELinux forget any previous protection
Elf32_Addr va_mfd = (Elf32_Addr)mmap(va_load, mfd_len, PF_to_PROT(phdr),
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, mfd, 0); (void)va_mfd;
close(mfd);
}
@@ -595,7 +591,7 @@ upx_so_main( // returns &escape_hatch
// Using .p_memsz implicitly handles .bss via MAP_ANONYMOUS.
// Omit any non-tcompressed prefix (below xct_off)
x1.buf = (char *)(phdr->p_vaddr + pfx + base);
x1.buf = (char *)(pfx + phdr->p_vaddr + base);
x1.size = phdr->p_memsz - pfx;
unsigned const frag = (phdr->p_vaddr + pfx) & ~page_mask; // lo fragment on page
@@ -611,16 +607,11 @@ upx_so_main( // returns &escape_hatch
// to hold the contents.
mfd = memfd_create(addr_string("upx"), 0); // the directory entry
ftruncate(mfd, x1.size); // Allocate the pages in the file.
write(mfd, x1.buf, frag); // Save lo fragment of contents on first page.
mfd_addr = mmap(0, x1.size, PROT_READ|PROT_WRITE, MAP_SHARED, mfd, 0);
DPRINTF("mfd_addr= %%p\\n", mfd_addr); // Now "somewhere" in RAM,
// and ready to receive de-compressed bytes, and remember them in the
// file (MAP_SHARED) so that they can be mmap() according to *phdr.
Pwrite(mfd, x1.buf, frag); // Save lo fragment of contents on first page.
Punmap(x1.buf, x1.size);
mfd_addr = Pmap(x1.buf, x1.size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, mfd, 0);
DPRINTF("mfd_addr= %%p\\n", mfd_addr); // Re-use the address space
// Must keep the original compressed data until now, in order to
// prevent the mmap(0, ...) from stealing that address range.
munmap(x1.buf, x1.size); // Discard original page frames in RAM.
x1.buf = mfd_addr; // will add pfx soon
}
else {
underlay(x1.size, x1.buf, frag, phdr->p_flags); // also makes PROT_WRITE
@@ -635,21 +626,21 @@ upx_so_main( // returns &escape_hatch
if (!hatch && phdr->p_flags & PF_X) {
#if defined(__i386__) //{
hatch = make_hatch_i386(phdr, (char *)base, x1.buf, mfd_addr, ~page_mask);
hatch = make_hatch_i386(phdr, x1.buf, ~page_mask);
#elif defined(__arm__) //}{
hatch = make_hatch_arm32(phdr, (char *)base, x1.buf, mfd_addr, ~page_mask);
hatch = make_hatch_arm32(phdr, x1.buf, ~page_mask);
#elif defined(__powerpc32__) //}{
hatch = make_hatch_ppc32(phdr, (char *)base, x1.buf, mfd_addr, ~page_mask);
hatch = make_hatch_ppc32(phdr, x1.buf, ~page_mask);
#endif //}
}
if (phdr->p_flags & PF_X) { // SELinux
// Map the contents of mfd as per *phdr.
DPRINTF("mfd mmap addr=%%p len=%%p\\n", (phdr->p_vaddr + base + pfx), al_bi.sz_unc);
munmap(mfd_addr, pfx + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
Punmap(mfd_addr, frag + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
Pmap((char *)(phdr->p_vaddr + base + pfx), al_bi.sz_unc, PF_to_PROT(phdr),
MAP_FIXED|MAP_PRIVATE, mfd, 0);
MAP_FIXED|MAP_SHARED, mfd, 0);
close(mfd);
}
else { // easy
@@ -657,7 +648,7 @@ upx_so_main( // returns &escape_hatch
}
}
munmap(sideaddr, cpr_len);
Punmap(sideaddr, cpr_len);
DPRINTF("calling user DT_INIT %%p\\n", dt_init);
dt_init(so_args->argc, so_args->argv, so_args->envp);
+49 -46
View File
@@ -2,19 +2,19 @@ file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 SO_MAIN 07b2 0 0 040 2**4 CONTENTS
1 EXP_HEAD 0e0 0 0 07f2 2**0 CONTENTS
2 NRV2E 0e5 0 0 08d2 2**0 CONTENTS
3 NRV2D 0d7 0 0 09b7 2**0 CONTENTS
4 NRV2B 0c1 0 0 0a8e 2**0 CONTENTS
5 SO_HEAD 02c 0 0 0b4f 2**0 CONTENTS
6 ptr_NEXT 0 0 0 0b7b 2**0 CONTENTS
7 SO_TAIL 098 0 0 0b7b 2**0 CONTENTS
8 LZMA_ELF00 064 0 0 0c13 2**0 CONTENTS
9 LZMA_DEC10 09f7 0 0 0c77 2**0 CONTENTS
10 LZMA_DEC20 09f7 0 0 0166e 2**0 CONTENTS
11 LZMA_DEC30 018 0 0 02065 2**0 CONTENTS
12 EXP_TAIL 0c 0 0 0207d 2**0 CONTENTS
0 SO_MAIN 07a0 0 0 040 2**4 CONTENTS
1 EXP_HEAD 0e0 0 0 07e0 2**0 CONTENTS
2 NRV2E 0e5 0 0 08c0 2**0 CONTENTS
3 NRV2D 0d7 0 0 09a5 2**0 CONTENTS
4 NRV2B 0c1 0 0 0a7c 2**0 CONTENTS
5 SO_HEAD 02c 0 0 0b3d 2**0 CONTENTS
6 ptr_NEXT 0 0 0 0b69 2**0 CONTENTS
7 SO_TAIL 098 0 0 0b69 2**0 CONTENTS
8 LZMA_ELF00 064 0 0 0c01 2**0 CONTENTS
9 LZMA_DEC10 09f7 0 0 0c65 2**0 CONTENTS
10 LZMA_DEC20 09f7 0 0 0165c 2**0 CONTENTS
11 LZMA_DEC30 018 0 0 02053 2**0 CONTENTS
12 EXP_TAIL 0c 0 0 0206b 2**0 CONTENTS
SYMBOL TABLE:
0000000000000000 l d EXP_HEAD 0 EXP_HEAD
0000000000000000 l d LZMA_DEC30 0 LZMA_DEC30
@@ -38,18 +38,19 @@ SYMBOL TABLE:
000000000000003f g SO_TAIL 0 mmap
0000000000000000 g F SO_TAIL 0 eof
000000000000007d g SO_TAIL 0 write
000000000000038e g F SO_MAIN 01d PF_to_PROT
0000000000000380 g F SO_MAIN 01d PF_to_PROT
000000000000006b g SO_TAIL 0 memfd_create
0000000000000081 g SO_TAIL 0 read
0000000000000013 g SO_TAIL 0 memset
0000000000000011 g SO_TAIL 0 my_bkpt
0000000000000085 g SO_TAIL 0 Pprotect
0000000000000000 *UND* 0 Pwrite
0000000000000051 g SO_TAIL 0 Punmap
0000000000000063 g SO_TAIL 0 exit
0000000000000076 g SO_TAIL 0 openat
0000000000000094 g SO_TAIL 0 mprotect
0000000000000072 g SO_TAIL 0 close
00000000000003ab g F SO_MAIN 0407 upx_so_main
000000000000039d g F SO_MAIN 0403 upx_so_main
RELOCATION RECORDS FOR [SO_MAIN]:
OFFSET TYPE VALUE
@@ -57,37 +58,39 @@ OFFSET TYPE VALUE
0000000000000017 R_X86_64_PLT32 exit+0xfffffffffffffffc
000000000000002e R_X86_64_PLT32 exit+0xfffffffffffffffc
000000000000010e R_X86_64_PLT32 f_expand+0xfffffffffffffffc
00000000000001e9 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
0000000000000204 R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000226 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000230 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000291 R_X86_64_PLT32 openat+0xfffffffffffffffc
00000000000002a9 R_X86_64_PLT32 read+0xfffffffffffffffc
00000000000002b7 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000333 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
0000000000000354 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000362 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
000000000000042e R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000441 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
00000000000004e3 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
00000000000004fc R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000510 R_X86_64_PLT32 write+0xfffffffffffffffc
000000000000051f R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000000527 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000542 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000549 R_X86_64_PLT32 close+0xfffffffffffffffc
000000000000062d R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
000000000000063d R_X86_64_PLT32 ftruncate+0xfffffffffffffffc
000000000000064e R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000672 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000684 R_X86_64_PLT32 Punmap+0xfffffffffffffffc
000000000000070f R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000000717 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
000000000000073f R_X86_64_PLT32 Pmap+0xfffffffffffffffc
0000000000000748 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000752 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000768 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
0000000000000783 R_X86_64_PLT32 munmap+0xfffffffffffffffc
00000000000001d2 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
00000000000001e0 R_X86_64_PLT32 ftruncate+0xfffffffffffffffc
00000000000001f9 R_X86_64_PLT32 Pwrite+0xfffffffffffffffc
000000000000021b R_X86_64_PLT32 Pmap+0xfffffffffffffffc
0000000000000225 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000283 R_X86_64_PLT32 openat+0xfffffffffffffffc
000000000000029b R_X86_64_PLT32 read+0xfffffffffffffffc
00000000000002a9 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000325 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
0000000000000346 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000354 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
0000000000000425 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000438 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
00000000000004de R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
00000000000004f7 R_X86_64_PLT32 ftruncate+0xfffffffffffffffc
0000000000000505 R_X86_64_PLT32 Pwrite+0xfffffffffffffffc
000000000000051d R_X86_64_PLT32 Pwrite+0xfffffffffffffffc
000000000000052a R_X86_64_PLT32 Punmap+0xfffffffffffffffc
0000000000000532 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
000000000000054f R_X86_64_PLT32 Pmap+0xfffffffffffffffc
0000000000000556 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000633 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
0000000000000642 R_X86_64_PLT32 ftruncate+0xfffffffffffffffc
0000000000000652 R_X86_64_PLT32 Pwrite+0xfffffffffffffffc
0000000000000661 R_X86_64_PLT32 Punmap+0xfffffffffffffffc
0000000000000683 R_X86_64_PLT32 Pmap+0xfffffffffffffffc
0000000000000703 R_X86_64_PLT32 Punmap+0xfffffffffffffffc
000000000000070b R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000730 R_X86_64_PLT32 Pmap+0xfffffffffffffffc
0000000000000738 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000742 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000756 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
0000000000000771 R_X86_64_PLT32 Punmap+0xfffffffffffffffc
RELOCATION RECORDS FOR [NRV2E]:
OFFSET TYPE VALUE