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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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);

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

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

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

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

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);

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