mirror of https://github.com/upx/upx.git
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:
parent
27de5f42bb
commit
982e732b74
|
@ -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);
|
||||
|
|
|
@ -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,$@)
|
||||
|
|
|
@ -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:
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.section HUMF_A, "ax"
|
||||
b upx_mmap_and_fd_android
|
||||
|
||||
.section HUMF_L, "ax"
|
||||
b upx_mmap_and_fd_linux
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "arm.v4a-linux.elf-help_umf.S"
|
|
@ -0,0 +1,5 @@
|
|||
.section HUMF_A, "ax"
|
||||
b upx_mmap_and_fd_android
|
||||
|
||||
.section HUMF_L, "ax"
|
||||
b upx_mmap_and_fd_linux
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "arm.v4a-linux.elf-help_umf.S"
|
|
@ -0,0 +1,5 @@
|
|||
.section HUMF_A, "ax"
|
||||
jmp upx_mmap_and_fd_android
|
||||
|
||||
.section HUMF_L, "ax"
|
||||
jmp upx_mmap_and_fd_linux
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "mipsel.r3000-linux.elf-help_umf.S"
|
|
@ -0,0 +1,5 @@
|
|||
.section HUMF_A, "ax"
|
||||
j upx_mmap_and_fd_android
|
||||
|
||||
.section HUMF_L, "ax"
|
||||
j upx_mmap_and_fd_linux
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue