Allow re-ordering of functions in upxfd_android.c and upxfd_linux.c

Compiler has a mind of its own.
	modified:   p_lx_elf.cpp
	modified:   stub/Makefile
	new file:   stub/src/amd64-linux.elf-help_umf.S
	modified:   stub/src/arm.v4a-expand.S
	new file:   stub/src/arm.v4a-linux.elf-help_umf.S
	modified:   stub/src/arm.v4a-linux.elf-so_entry.S
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	new file:   stub/src/arm.v5a-linux.elf-help_umf.S
	new file:   stub/src/arm64-linux.elf-help_umf.S
	modified:   stub/src/arm64-linux.elf-so_entry.S
	new file:   stub/src/armeb.v4a-linux.elf-help_umf.S
	new file:   stub/src/i386-linux.elf-help_umf.S
	modified:   stub/src/i386-linux.elf-so_main.c
	new file:   stub/src/mips.r3000-linux.elf-help_umf.S
	new file:   stub/src/mipsel.r3000-linux.elf-help_umf.S
	modified:   stub/src/upxfd_android.c
This commit is contained in:
John Reiser 2024-12-04 17:00:37 -08:00
parent 27de5f42bb
commit 982e732b74
16 changed files with 144 additions and 60 deletions

View File

@ -1489,8 +1489,8 @@ PackLinuxElf32::buildLinuxLoader(
len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
(sec_arm_attr || is_asl || opt->o_unix.android_shlib)
? "UMF_ANDROID"
: "UMF_LINUX");
? "HUMF_A,UMF_ANDROID"
: "HUMF_L,UMF_LINUX");
if (hasLoaderSection("STRCON")) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "STRCON");
}
@ -1536,8 +1536,8 @@ PackLinuxElf32::buildLinuxLoader(
// $ARCH-linux.elf-main2.c calls upx_mmap_and_fd, not direct memfd_create
len += snprintf(&sec[len], sizeof(sec) - len, ",%s",
(sec_arm_attr || is_asl || opt->o_unix.android_shlib)
? "UMF_ANDROID"
: "UMF_LINUX");
? "HUMF_A,UMF_ANDROID"
: "HUMF_L,UMF_LINUX");
if (hasLoaderSection("SYSCALLS")) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "SYSCALLS");
}
@ -1600,8 +1600,8 @@ PackLinuxElf32::buildLinuxLoader(
) { // shlib with ELF2 de-compressor
addLoader("ELFMAINX");
addLoader((sec_arm_attr || is_asl || opt->o_unix.android_shlib)
? "UMF_ANDROID"
: "UMF_LINUX");
? "HUMF_A,UMF_ANDROID"
: "HUMF_L,UMF_LINUX");
addLoader("ELFMAINZ,FOLDEXEC,IDENTSTR");
}
else if (this->e_machine==Elf32_Ehdr::EM_NONE
@ -1615,8 +1615,8 @@ PackLinuxElf32::buildLinuxLoader(
// Only if $ARCH-linux.elf-entry.S calls upx_mmap_and_fd instead of memfd_create
if (this->e_machine != Elf32_Ehdr::EM_PPC) // FIXME: also MIPS?
addLoader((sec_arm_attr || is_asl || opt->o_unix.android_shlib)
? "UMF_ANDROID"
: "UMF_LINUX");
? "HUMF_A,UMF_ANDROID"
: "HUMF_L,UMF_LINUX");
addLoader("ELFMAINZ,FOLDEXEC,IDENTSTR");
defineSymbols(ft);
}
@ -1680,7 +1680,7 @@ PackLinuxElf64::buildLinuxLoader(
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "EXP_TAIL");
// End of daisy-chain fall-through.
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "UMF_LINUX");
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "HUMF_L,UMF_LINUX");
if (hasLoaderSection("STRCON")) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "STRCON");
}
@ -5288,7 +5288,7 @@ unsigned PackLinuxElf::pack2_shlib_overlay_write(OutputFile *fo, MemBuffer &mb,
memset(&tmp, 0, sizeof(tmp));
set_te32(&tmp.sz_unc, u_len);
set_te32(&tmp.sz_cpr, c_len);
tmp.b_method = M_NRV2B_LE32;
tmp.b_method = (EM_ARM == e_machine) ? M_NRV2B_8 : M_NRV2B_LE32;
tmp.b_extra = 0;
fo->write(&tmp, sizeof(tmp)); total_out += sizeof(tmp);
b_len += sizeof(b_info);

View File

@ -578,12 +578,14 @@ tc.arm.v4a-linux.elf.gcc += -Wall -W -Wcast-align -Wcast-qual -Wstrict-prototype
arm.v4a-linux.elf-entry.h : $(srcdir)/src/arm.v4a-linux.elf-entry.lds \
$(srcdir)/src/$$T.S \
tmp/arm.v4a-linux.elf-help_umf.o \
tmp/arm.v4a-linux.elf-upxfd_android.o \
tmp/arm.v4a-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r --format=elf32-littlearm -Map tmp/$T.map -o tmp/$T.bin \
-T src/arm.v4a-linux.elf-entry.lds \
tmp/$T.o \
tmp/arm.v4a-linux.elf-help_umf.o \
tmp/arm.v4a-linux.elf-upxfd_android.o \
tmp/arm.v4a-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -591,12 +593,14 @@ arm.v4a-linux.elf-entry.h : $(srcdir)/src/arm.v4a-linux.elf-entry.lds \
arm.v4a-linux.elf-so_entry.h : src/arm.v4a-linux.elf-so_entry.lds \
$(srcdir)/src/$$T.S \
tmp/arm.v4a-linux.elf-help_umf.o \
tmp/arm.v4a-linux.elf-upxfd_android.o \
tmp/arm.v4a-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r --format=elf32-littlearm -Map tmp/$T.map -o tmp/$T.bin \
-T src/arm.v4a-linux.elf-so_entry.lds \
tmp/$T.o \
tmp/arm.v4a-linux.elf-help_umf.o \
tmp/arm.v4a-linux.elf-upxfd_android.o \
tmp/arm.v4a-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -614,6 +618,7 @@ tmp/arm.v4a-linux.elf-upxfd_linux.o : $(srcdir)/src/upxfd_linux.c
arm.v4a-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/arm.v4a-linux.elf-help_umf.o \
tmp/arm.v4a-linux.elf-upxfd_android.o \
tmp/arm.v4a-linux.elf-upxfd_linux.o \
tmp/arm.v4a-expand.o \
@ -624,6 +629,7 @@ arm.v4a-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
arm.v4a-linux.elf-so_fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/arm.v4a-linux.elf-help_umf.o \
tmp/arm.v4a-linux.elf-upxfd_android.o \
tmp/arm.v4a-linux.elf-upxfd_linux.o \
tmp/arm.v4a-expand.o \
@ -635,6 +641,9 @@ arm.v4a-linux.elf-so_fold.h : $(srcdir)/src/$$T.lds \
tmp/arm.v4a-expand.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/arm.v4a-linux.elf-help_umf.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/arm.v4a-linux.elf-fold.o : $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
$(call tc,f-objstrip,$@)
@ -694,12 +703,14 @@ tc.arm.v5a-linux.elf.gcc += -Wall -W -Wcast-align -Wcast-qual -Wstrict-prototype
arm.v5a-linux.elf-entry.h : $(srcdir)/src/arm.v5a-linux.elf-entry.lds \
$(srcdir)/src/$$T.S \
tmp/arm.v5a-linux.elf-help_umf.o \
tmp/arm.v5a-linux.elf-upxfd_android.o \
tmp/arm.v5a-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r --format=elf32-littlearm -Map tmp/$T.map -o tmp/$T.bin \
-T src/arm.v5a-linux.elf-entry.lds \
tmp/$T.o \
tmp/arm.v5a-linux.elf-help_umf.o \
tmp/arm.v5a-linux.elf-upxfd_android.o \
tmp/arm.v5a-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -707,12 +718,14 @@ arm.v5a-linux.elf-entry.h : $(srcdir)/src/arm.v5a-linux.elf-entry.lds \
arm.v5a-linux.elf-so_entry.h : src/arm.v5a-linux.elf-so_entry.lds \
$(srcdir)/src/$$T.S \
tmp/arm.v5a-linux.elf-help_umf.o \
tmp/arm.v5a-linux.elf-upxfd_android.o \
tmp/arm.v5a-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r --format=elf32-littlearm -Map tmp/$T.map -o tmp/$T.bin \
-T src/arm.v5a-linux.elf-so_entry.lds \
tmp/$T.o \
tmp/arm.v5a-linux.elf-help_umf.o \
tmp/arm.v5a-linux.elf-upxfd_android.o \
tmp/arm.v5a-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -730,6 +743,7 @@ tmp/arm.v5a-linux.elf-upxfd_linux.o : $(srcdir)/src/upxfd_linux.c
arm.v5a-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/arm.v5a-linux.elf-help_umf.o \
tmp/arm.v5a-linux.elf-upxfd_android.o \
tmp/arm.v5a-linux.elf-upxfd_linux.o \
tmp/arm.v5a-expand.o \
@ -740,6 +754,7 @@ arm.v5a-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
arm.v5a-linux.elf-so_fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/arm.v5a-linux.elf-help_umf.o \
tmp/arm.v5a-linux.elf-upxfd_android.o \
tmp/arm.v5a-linux.elf-upxfd_linux.o \
tmp/arm.v5a-expand.o \
@ -751,6 +766,9 @@ arm.v5a-linux.elf-so_fold.h : $(srcdir)/src/$$T.lds \
tmp/arm.v5a-expand.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/arm.v5a-linux.elf-help_umf.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/arm.v5a-linux.elf-fold.o : $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
$(call tc,f-objstrip,$@)
@ -935,12 +953,14 @@ tc.armeb.v4a-linux.elf.gcc = $(tc.arm.v4a-linux.elf.gcc) -mbig-endian -DBIG_ENDI
armeb.v4a-linux.elf-entry.h : $(srcdir)/src/armeb.v4a-linux.elf-entry.lds \
$(srcdir)/src/$$T.S \
tmp/armeb.v4a-linux.elf-help_umf.o \
tmp/armeb.v4a-linux.elf-upxfd_android.o \
tmp/armeb.v4a-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r --format=elf32-bigarm -Map tmp/$T.map -o tmp/$T.bin \
-T src/armeb.v4a-linux.elf-entry.lds \
tmp/$T.o \
tmp/armeb.v4a-linux.elf-help_umf.o \
tmp/armeb.v4a-linux.elf-upxfd_android.o \
tmp/armeb.v4a-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -948,6 +968,7 @@ armeb.v4a-linux.elf-entry.h : $(srcdir)/src/armeb.v4a-linux.elf-entry.lds \
armeb.v4a-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/armeb.v4a-linux.elf-help_umf.o \
tmp/armeb.v4a-linux.elf-upxfd_android.o \
tmp/armeb.v4a-linux.elf-upxfd_linux.o \
tmp/armeb.v4a-expand.o \
@ -969,6 +990,9 @@ tmp/armeb.v4a-linux.elf-upxfd_linux.o : $(srcdir)/src/upxfd_linux.c
tmp/armeb.v4a-expand.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/armeb.v4a-linux.elf-help_umf.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/armeb.v4a-linux.elf-fold.o : $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
$(call tc,f-objstrip,$@)
@ -1315,12 +1339,14 @@ tc.i386-linux.elf.gcc += -fweb
i386-linux.elf-entry.h : $(srcdir)/src/i386-linux.elf-entry.lds \
$(srcdir)/src/$$T.S \
tmp/i386-linux.elf-help_umf.o \
tmp/i386-linux.elf-upxfd_android.o \
tmp/i386-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r -Map tmp/$T.map -o tmp/$T.bin \
-T src/i386-linux.elf-entry.lds \
tmp/$T.o \
tmp/i386-linux.elf-help_umf.o \
tmp/i386-linux.elf-upxfd_android.o \
tmp/i386-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -1328,12 +1354,14 @@ i386-linux.elf-entry.h : $(srcdir)/src/i386-linux.elf-entry.lds \
i386-linux.elf-so_entry.h : $(srcdir)/src/i386-linux.elf-so_entry.lds \
$(srcdir)/src/$$T.S \
tmp/i386-linux.elf-help_umf.o \
tmp/i386-linux.elf-upxfd_android.o \
tmp/i386-linux.elf-upxfd_linux.o
$(call tc,gcc) -c $(srcdir)/src/$T.S -o tmp/$T.o
multiarch-ld-2.17 -r -Map tmp/$T.map -o tmp/$T.bin \
-T src/i386-linux.elf-so_entry.lds \
tmp/$T.o \
tmp/i386-linux.elf-help_umf.o \
tmp/i386-linux.elf-upxfd_android.o \
tmp/i386-linux.elf-upxfd_linux.o
$(call tc,f-embed_objinfo_without_xstrip,tmp/$T.bin)
@ -1351,6 +1379,7 @@ tmp/i386-linux.elf-upxfd_linux.o : $(srcdir)/src/upxfd_linux.c
i386-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/i386-linux.elf-help_umf.o \
tmp/i386-linux.elf-upxfd_android.o \
tmp/i386-linux.elf-upxfd_linux.o \
tmp/i386-expand.o \
@ -1362,6 +1391,7 @@ i386-linux.elf-fold.h : $(srcdir)/src/$$T.lds \
i386-linux.elf-so_fold.h : $(srcdir)/src/$$T.lds \
tmp/$$T.o \
tmp/i386-linux.elf-help_umf.o \
tmp/i386-linux.elf-upxfd_android.o \
tmp/i386-linux.elf-upxfd_linux.o \
tmp/i386-expand.o \
@ -1383,6 +1413,9 @@ tmp/i386-linux.elf-so_fold.o : $(srcdir)/src/$$T.S
tmp/i386-expand.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/i386-linux.elf-help_umf.o: $(srcdir)/src/$$T.S
$(call tc,gcc) -c $< -o $@
tmp/i386-linux.elf-main2.o : $(srcdir)/src/$$T.c
$(call tc,gcc) -c $< -o $@
$(call tc,f-objstrip,$@)

View File

@ -0,0 +1,11 @@
// "jmp undef" gets R_X86_64_PLT32; we want R_X86_64_PC32
.section HUMF_A, "ax"
.byte 0xe9 // 5-byte jmp opcode
.int upx_mmap_and_fd_android - 0f // force R_X86_64_PC32 relocation
0:
.section HUMF_L, "ax"
.byte 0xe9
.int upx_mmap_and_fd_linux - 0f
0:

View File

@ -169,7 +169,8 @@ decompress: // (src *, cpr_len, dst *, &dstlen);
.globl eof
eof: // end of a compressed extent
POP {tmp} // &input_eof
mov r0,src; SUB2 r0,tmp // src -= eof; // return 0: good; else: bad
mov r0,src; SUB2S r0,tmp // src -= eof
beq 0f; bkpt; 0: // return 0: good; else: bad
POP {tmp} // original dst
POP {r1}; SUB2 dst,tmp // dst -= original dst
POP {tmp}; str dst,[tmp] // actual length used at dst XXX: 4GB

View File

@ -0,0 +1,5 @@
.section HUMF_A, "ax"
b upx_mmap_and_fd_android
.section HUMF_L, "ax"
b upx_mmap_and_fd_linux

View File

@ -245,6 +245,14 @@ f_decompress:
// MATCH_01 argv
// MATCH_07 envp
// get_page_mask should never be called by so_entry, because the 1st arg
// (the pointer) to upx_mmap_and_fd is 0. But in the general case
// there must be a get_page_mask subroutine. Return something plausible.
get_page_mask: .globl get_page_mask
mvn r0,#0
mov r0,r0,lsl #12
ret
upx_mmap_and_fd: .globl upx_mmap_and_fd
// UMF_LINX or UMF_ANDROID goes here

View File

@ -303,48 +303,50 @@ mmap_privanon: .globl mmap_privanon
mvn r4,#0 @ fd= -1
b mmap_do
tmp .req r3
size .req r4
ptr .req r5
ulen .req r6
pflg .req r7
underlay: .globl underlay // (unsigned size, char *ptr, unsigned ulen, unsigned p_flags) // ulen <= PAGE_SIZE
underlay: .globl underlay // (unsigned size, char *ptr, unsigned page_mask);
stmdb sp!,{r0,r1,r2,r3,r4,r5,r6,r7, lr}
ldmia sp!, {r4,r5,r6,r7} // r4= r0; r5= r1; r6= r2; r7= r3;
mov r0,sp
sub tmp,sp,ulen
size .req r4
ptr .req r5
pmsk .req r6
frag .req r7
tmp .req r3
mov r0,sp // old sp
bics frag,ptr,pmsk; beq 3f // page fragment
sub tmp,sp,frag
and sp,tmp,#-2*NBPW
str r0,[sp,#-NBPW]! // save sp for pop at return
str r0,[sp,#-NBPW]! // save old sp for pop at return
add r0,sp,#NBPW
// mov r1,ptr // not yet overwritten
// mov r2,ulen // not yet overwritten
mov r2,frag
and r1,ptr,pmsk // beginning of page
add r0,sp,#NBPW // &saved_area
bl memcpy
3:
mov r0,ptr
mov r1,size
and r0,ptr,pmsk // beginning of page
add r1,size,frag // include fragment
mov r2,#PROT_WRITE|PROT_READ
tst pflg,#PF_X // if eventually PROT_EXEC,
orrne r2,r2,#PROT_EXEC // ... then Linux ARM wants it now, too
mov r3,#MAP_FIXED
bl mmap_privanon // r0= ptr because MAP_FIXED
mov ptr,r0
add r1,sp,#NBPW
mov r2,ulen
cmp frag,#0; beq 3f
mov r0,ptr // mapped address
add r1,sp,#NBPW // &saved_area
mov r2,frag
bl memcpy
ldr sp,[sp]
ldr sp,[sp] // original sp
3:
mov r0,ptr // start of mapped region
ldmia sp!,{r4,r5,r6,r7, pc}
.unreq tmp
.unreq size
.unreq ptr
.unreq ulen
.unreq pflg
.unreq pmsk
.unreq frag
my_alloca: .globl my_alloca
sub r0,sp,r0

View File

@ -0,0 +1 @@
#include "arm.v4a-linux.elf-help_umf.S"

View File

@ -0,0 +1,5 @@
.section HUMF_A, "ax"
b upx_mmap_and_fd_android
.section HUMF_L, "ax"
b upx_mmap_and_fd_linux

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

@ -0,0 +1 @@
#include "arm.v4a-linux.elf-help_umf.S"

View File

@ -0,0 +1,5 @@
.section HUMF_A, "ax"
jmp upx_mmap_and_fd_android
.section HUMF_L, "ax"
jmp upx_mmap_and_fd_linux

View File

@ -34,7 +34,7 @@
extern void my_bkpt(void const *arg1, ...);
#define DEBUG 0
#define DEBUG 1
// Pprotect is mprotect, but page-aligned on the lo end (Linux requirement)
unsigned Pprotect(void *, size_t, unsigned);
@ -223,6 +223,7 @@ ERR_LAB
if (h.sz_cpr < h.sz_unc) { // Decompress block
size_t out_len = h.sz_unc; // EOF for lzma
//my_bkpt((void const *)0x1204, &xi, &xo, out_len);
int const j = f_expand((unsigned char *)xi->buf - sizeof(h),
(unsigned char *)xo->buf, &out_len);
if (j != 0 || out_len != (nrv_uint)h.sz_unc) {
@ -239,6 +240,7 @@ ERR_LAB
xo->buf += h.sz_unc;
xo->size -= h.sz_unc;
}
DPRINTF(" end unpackExtent\\n", 0);
}
#if defined(__i386__) //}{
@ -474,6 +476,8 @@ fini_SELinux(
ElfW(Addr) base
)
{
DPRINTF("fini_SELinux size=%%p ptr=%%p phdr=%%p mfd=%%p base=%%p\\n",
size, ptr, phdr, mfd, base);
if (phdr->p_flags & PF_X) {
// Map the contents of mfd as per *phdr.
Punmap(ptr, size);
@ -492,6 +496,7 @@ prep_SELinux(unsigned size, char *ptr, unsigned len) // returns mfd
// Cannot set PROT_EXEC except via mmap() into a region (Linux "vma")
// that has never had PROT_WRITE. So use a Linux-only "memory file"
// to hold the contents.
DPRINTF("prep_SELinux size=%%p ptr=%%p len=%%p\\n", size, ptr,len);
char *val = upx_mmap_and_fd(ptr, size, nullptr);
unsigned mfd = 0xfff & (unsigned)val;
val -= mfd; --mfd;
@ -581,6 +586,10 @@ upx_so_main( // returns &escape_hatch
for (; phdr < phdrN; ++phdr)
if (phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_W)) {
if (!base) {
base = (ElfW(Addr))va_load - phdr->p_vaddr;
DPRINTF("base=%%p\\n", base);
}
unsigned hi_offset = phdr->p_filesz + phdr->p_offset;
struct b_info al_bi; // for aligned data from binfo
// Need un-aligned read of b_info to determine compression sizes.
@ -591,10 +600,6 @@ upx_so_main( // returns &escape_hatch
x1.buf = (void *)(hi_offset + base - al_bi.sz_unc);
x0.size = al_bi.sz_cpr;
if (!base) {
base = (ElfW(Addr))va_load - phdr->p_vaddr;
DPRINTF("base=%%p\\n", base);
}
DPRINTF("phdr@%%p p_offset=%%p p_vaddr=%%p p_filesz=%%p p_memsz=%%p\\n",
phdr, phdr->p_offset, phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz);
DPRINTF("x0=%%p x1=%%p\\n", &x0, &x1);
@ -612,12 +617,13 @@ upx_so_main( // returns &escape_hatch
else {
underlay(x1.size, x1.buf, page_mask); // also makes PROT_WRITE
}
Extent const xt = x1;
unpackExtent(&x0, &x1);
if (!hatch && phdr->p_flags & PF_X) {
hatch = make_hatch(phdr, x1.buf, ~page_mask);
}
my_bkpt((void const *)0x1235, &x1);
fini_SELinux(x1.size, x1.buf, phdr, mfd, base); // FIXME: x1 changed!
//my_bkpt((void const *)0x1235, &x1);
fini_SELinux(xt.size, xt.buf, phdr, mfd, base);
}
}
else { // 2nd and later PT_LOADs

View File

@ -0,0 +1 @@
#include "mipsel.r3000-linux.elf-help_umf.S"

View File

@ -0,0 +1,5 @@
.section HUMF_A, "ax"
j upx_mmap_and_fd_android
.section HUMF_L, "ax"
j upx_mmap_and_fd_linux

View File

@ -183,6 +183,7 @@ extern int stat(char const *path, struct stat *statbuf);
extern int mkdir(char const *path, unsigned mode);
extern int uname(struct utsname *);
extern char * get_upxfn_path(void);
extern long get_page_mask(void);
unsigned long upx_mmap_and_fd_android( // returns (mapped_addr | (1+ fd))
void *ptr // desired address
@ -190,9 +191,6 @@ unsigned long upx_mmap_and_fd_android( // returns (mapped_addr | (1+ fd))
, char *pathname // 0 ==> get_upxfn_path()
)
{
// This used to be a parameter, but was always 0
unsigned const frag_mask = 0u;
unsigned long addr = 0; // for result
// Early 32-bit Android did not implement memfd_create
int fd = -ENOSYS;
@ -256,9 +254,13 @@ unsigned long upx_mmap_and_fd_android( // returns (mapped_addr | (1+ fd))
#endif //}
// Set the file length
unsigned const frag = frag_mask & (unsigned)(long)ptr;
ptr -= frag; // page-aligned
datlen += frag;
my_bkpt((void const *)0x1302, ptr, datlen);
if (ptr) {
unsigned const page_mask = get_page_mask();
unsigned const frag = ~page_mask & (unsigned)(long)ptr;
ptr -= frag; // becomes page-aligned
datlen += frag;
}
if (datlen) {
if (not_android) { // Linux ftruncate() is well-behaved
int rv = ftruncate(fd, datlen);
@ -268,21 +270,19 @@ unsigned long upx_mmap_and_fd_android( // returns (mapped_addr | (1+ fd))
}
#if ANDROID_FRIEND //{
else { // !not_android: ftruncate has varying system call number on 32-bit
memset(u.buf, 0, BUFLEN);
unsigned wlen = datlen;
while (0 < wlen) {
int x = (wlen < BUFLEN) ? wlen : BUFLEN;
if (x != write(fd, u.buf, x)) {
return -ENOSPC;
}
wlen -= x;
}
lseek(fd, -1+ datlen, SEEK_SET); // last byte
char zero = 0;
write(fd, &zero, 1); // force allocation
lseek(fd, 0, SEEK_SET); // go back to the beginning
}
#endif //}
}
if (frag_mask && ptr) { // Preserve entire page that contains *ptr
write(fd, ptr, 1+ frag_mask);
if (ptr) {
unsigned const page_mask = get_page_mask();
if (~page_mask & (unsigned)(long)ptr) {
// Preserve entire page that contains *ptr
write(fd, ptr, -page_mask);
}
}
addr = (unsigned long)mmap(ptr, datlen , PROT_WRITE | PROT_READ,
MAP_SHARED | (ptr ? MAP_FIXED : 0), fd, 0);