1
0
mirror of https://github.com/upx/upx synced 2025-10-05 19:20:23 +08:00

arm64 stub for shared library uses AT_PAGESZ

modified:   stub/src/arm64-linux.shlib-init.S
	also .h .bin.dump
This commit is contained in:
John Reiser 2017-10-23 18:55:28 -07:00
parent 8e42e17bbf
commit 4869142034
3 changed files with 642 additions and 597 deletions

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
* <jreiser@users.sourceforge.net> * <jreiser@users.sourceforge.net>
*/ */
NBPW= 8
#include "arch/arm64/v8/macros.S" #include "arch/arm64/v8/macros.S"
sz_Elf64_Ehdr = 16 + 2*2 + 4 + 3*8 + 4 + 6*2 sz_Elf64_Ehdr = 16 + 2*2 + 4 + 3*8 + 4 + 6*2
@ -53,6 +54,11 @@ PAGE_SHIFT= 12
PAGE_MASK= (~0<<PAGE_SHIFT) PAGE_MASK= (~0<<PAGE_SHIFT)
PAGE_SIZE= -PAGE_MASK PAGE_SIZE= -PAGE_MASK
a_type = 0*NBPW
a_val = 1*NBPW
AT_NULL= 0
AT_PAGESZ= 6
__NR_exit = 93 __NR_exit = 93
__NR_write = 64 __NR_write = 64
__NR_mmap64 = 0xde // 222 __NR_mmap64 = 0xde // 222
@ -63,6 +69,7 @@ __ARM_NR_cacheflush = (1<<31) // FIXME
#define arg1 x0 #define arg1 x0
#define arg2 x1 #define arg2 x1
# define arg2w w1
#define arg3 x2 #define arg3 x2
#define arg4 x3 #define arg4 x3
#define arg5 x4 #define arg5 x4
@ -83,7 +90,6 @@ __ARM_NR_cacheflush = (1<<31) // FIXME
#define rcx x5 #define rcx x5
#define lr x30 #define lr x30
#define fp x29
#define src x0 #define src x0
#define len w1 #define len w1
@ -99,20 +105,49 @@ __ARM_NR_cacheflush = (1<<31) // FIXME
#define tmp2w w6 #define tmp2w w6
#define tmp2x x6 #define tmp2x x6
N_SLOT= 0
sp_frame = 30 * NBPW
.macro slot symbol, n
\symbol = N_SLOT*NBPW
.ifnb n
N_SLOT = \n + N_SLOT
.else
N_SLOT = 1 + N_SLOT
.endif
.endm
section ELFMAINX section ELFMAINX
// .long offset(.) // detect relocation // .long offset(.) // detect relocation
// .long offset(user DT_INIT) // .long offset(user DT_INIT)
// .long offset(escape_hatch) // .long offset(escape_hatch)
// .long offset({l_info; p_info; b_info; compressed data}) // .long offset({l_info; p_info; b_info; compressed data})
_start: .globl _start slot f_argc // 0
// brk #0 // debugging slot f_argv // 1
PUSH2(lr,x0) // x0= placeholder for user DT_INIT slot f_envp // 2
PUSH4(arg1,arg2,arg3,fp) slot f_uinit // 3 user DT_INIT
mov fp,sp slot f_PMASK // 4 PAGE_MASK
o_uinit= 5*8 // pc slot f_my_ra // 5
bl main // push &f_decompress _start: .globl _start
// brk #0 // debugging
stp arg1,arg2,[sp,#f_argc - sp_frame]! // f_argv
stp arg3,x0, [sp,#f_envp] // %f_uinit
// Calculate PAGE_MASK
0: // Advance envp to auxp
ldr x3,[arg3],#NBPW; cbnz x3,0b
mov x3,#1<<PAGE_SHIFT // default
0: // Find AT_PAGESZ
ldp x0,x1,[arg3],#2*NBPW; cbz x0,5f // AT_NULL==.a_type; use default
cmp x0,#AT_PAGESZ; bne 0b
5: // auxp cannot be empty (must have AT_UID), so 'cmp' above sets nzvc
csel x1,x1,x3,eq // x1 if found, else x3
neg x1,x1
stp x1,lr,[sp,#f_PMASK] // f_my_ra
bl main // ra= &f_decompress
f_decompress: f_decompress:
#define LINUX_ARM_CACHEFLUSH 1 #define LINUX_ARM_CACHEFLUSH 1
@ -172,28 +207,30 @@ main:
add rsi,rdx,# _start - f_decompress - 4*4 add rsi,rdx,# _start - f_decompress - 4*4
mov rcx,rsi mov rcx,rsi
lodsl; sub rcx,rcx,rax; //str ecx,[fp,#o_reloc] lodsl; sub rcx,rcx,rax; //str ecx,[sp,#o_reloc]
lodsl; add rax,rcx,rax; str rax,[fp,#o_uinit] // reloc DT_INIT for step 12 lodsl; add rax,rcx,rax; str rax,[sp,#f_uinit] // reloc DT_INIT for step 12
lodsl; add rax,rcx,rax; PUSH1(rax) // reloc &hatch for step 10 slot o_hatch // 6
o_hatch= -2*8 // HOLE lodsl; add rax,rcx,rax; str rax,[sp,#o_hatch] // reloc &hatch for step 10
lodsl; add rdi,rcx,rax // &l_info; also destination for decompress lodsl; add rdi,rcx,rax // &l_info; also destination for decompress
add rsi,rdi,#sz_l_info + sz_p_info // &b_info add rsi,rdi,#sz_l_info + sz_p_info // &b_info
sub sp,sp,#2*8 // param space: munmap temp pages step 9 slot p_unmap,2 // 7
p_unmap= -4*8
ldr eax,[rsi,#4]; add rsi,rsi,#3*4 // sz_cpr ldr eax,[rsi,#sz_cpr]; add rsi,rsi,#sz_b_info // sz_cpr
add rsi,rsi,rax // skip unpack helper block add rsi,rsi,rax // skip unpack helper block
ldr ecx,[sp,#f_PMASK]
lodslu // eax=dstlen lodslu // eax=dstlen
lsl ecx,edi,# (32-PAGE_SHIFT) bic ecx,edi,ecx // ecx= fragment
lsr ecx,ecx,#2+(32-PAGE_SHIFT) // ecx= w_fragment add ecx,ecx,#3
add eax,eax,ecx,lsl #2 bic ecx,ecx,#3 // w_frag [can be PAGE_SIZE !]
sub rdi,rdi,rcx,lsl #2
PUSH2(rdi,rax) // params: mprotect restored pages step 8 add eax,eax,ecx // dstlen + fragment
p_mprot= -6*8 sub rdi,rdi,ecx,uxtw // page boundary
sub eax,eax,ecx,lsl #2 // dstlen slot p_mprot,2 // 9
add rdi,rdi,rcx,lsl #2 // dst stp rdi,rax,[sp,#p_mprot] // params: mprotect restored pages step 8
add rdi,rdi,ecx,uxtw // restore dst
sub eax,eax,ecx // restore dstlen
bl L610 bl L610
f_unfilter: // (char *ptr, uint len, uint cto, uint fid) f_unfilter: // (char *ptr, uint len, uint cto, uint fid)
@ -222,26 +259,30 @@ unfret:
ret ret
L610: L610:
PUSH2(lr,rcx) // f_unf, w_frag
o_wfrag = -7*8 lsr ecx,ecx,#2 // w_frag
o_unflt= -8*8 slot o_unflt // 11
slot o_wfrag // 12
stp lr,rcx,[sp,#o_unflt] // o_wfrag
ldrb tmp1w,[rsi,# b_method-4+1] // ftid ldrb tmp1w,[rsi,# b_method-4+1] // ftid
ldrb tmp2w,[rsi,# b_method-4+2] // cto8 ldrb tmp2w,[rsi,# b_method-4+2] // cto8
PUSH4(rdi,rax,tmp2x,tmp1x) // dst, dstlen, cto8, ftid for unfilter step 7 slot p_unflt,4 // 13
p_unflt= -12*8 stp rdi,rax,[sp,#0*NBPW + p_unflt] // dst, dstlen
stp tmp2x,tmp1x,[sp,2*NBPW + p_unflt] // cto8, ftid for unfilter step 7
lodslu; mov ecx,eax // ecx= srclen lodslu; mov ecx,eax // ecx= srclen
lodslu lodslu
PUSH2(rdx,rax) // &decompress, {method,filter,cto,junk} slot o_uncpr,2 // 17
o_uncpr= -14*8 stp rdx,rax,[sp,#o_uncpr] // &decompress, {method,filter,cto,junk}
add tmpx,fp,#p_unflt+1*8 add tmpx,sp,#1* NBPW + p_unflt // &dstlen
PUSH4(rsi,rcx,rdi,tmpx) // src,srclen,dst,&dstlen arglist ready for decompress step 6 slot p_uncpr,4 // 19
p_uncpr= -18*8 stp rsi,rcx, [sp,#0*NBPW + p_uncpr] // src, srclen
stp rdi,tmpx,[sp,#2*NBPW + p_uncpr] // dst, &dstlen arglist ready for decompress step 6
add rcx,rcx,#3 // allow suffix alignment add rcx,rcx,#3 // allow suffix alignment
ldr tmp,[fp,#o_wfrag]; add rdx,tmpx,rcx,lsr #2 // w_srclen + w_frag ldr tmp,[sp,#o_wfrag]; add rdx,tmpx,rcx,lsr #2 // w_srclen + w_frag
ldr tmpx,[fp,#o_uncpr]; bl wlen_subr ldr tmpx,[sp,#o_uncpr]; bl wlen_subr
ldr tmpx,[fp,#o_unflt]; bl wlen_subr ldr tmpx,[sp,#o_unflt]; bl wlen_subr
bl L220 bl L220
supervise: supervise:
@ -251,50 +292,52 @@ supervise:
mov arg5,#-1 // cater to *BSD for fd of MAP_ANON mov arg5,#-1 // cater to *BSD for fd of MAP_ANON
mov arg4,#MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED mov arg4,#MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED
mov arg3,#PROT_READ|PROT_WRITE mov arg3,#PROT_READ|PROT_WRITE
ldr arg2,[fp,#p_mprot+8] // dstlen ldp arg1,arg2,[sp,#p_mprot] // dst, dstlen
ldr arg1,[fp,#p_mprot ] // dst
mov x6,arg1 // required result mov x6,arg1 // required result
do_sys __NR_mmap64; cmp x0,x6; beq 0f; brk #0; 0: do_sys __NR_mmap64; cmp x0,x6; beq 0f; brk #0; 0:
// Restore fragment of page below dst // Restore fragment of page below dst
ldr ecx,[fp,#o_wfrag] ldr ecx,[sp,#o_wfrag]
//mov edi,r0 // NOP: edi==r0 //mov edi,r0 // NOP: edi==r0
ldr rsi,[fp,#p_unmap] ldr rsi,[sp,#0*NBPW + p_unmap]
bl movsl bl movsl
//p_uncpr //p_uncpr
POP4(arg1,arg2,arg3,arg4) ldr rax,[sp,#o_uncpr]
POP1(rax) ldp arg1,arg2,[sp,#0*NBPW + p_uncpr]
ldp arg3,arg4,[sp,#2*NBPW + p_uncpr]
blr rax // decompress blr rax // decompress
bl L620 bl L620
//hatch: //hatch: IN: lr= f_my_ra; {arg1,arg2}= p_unmap; arg3= f_envp; arg4= f_uinit
do_sys __NR_munmap // 2 instr svc #0 // munmap(arg1,arg2)
POP4(arg1,arg2,arg3,fp) // 2 instr ldp arg1,arg2,[sp],#sp_frame // f_argc, f_argv
POP2(lr,arg4) // 1 instr; arg4= user DT_INIT
br arg4 br arg4
L620: // Implant escape hatch at end of .text L620: // Implant escape hatch at end of .text
ldr rax,[fp,#o_hatch] ldr rax,[sp,#o_hatch]
ldp arg1,arg2,[lr] // 4 instr ldp arg1,arg2,[lr] // 4 instr
stp arg1,arg2,[rax] str arg1, [rax] // 2 instr
ldr arg1,[lr,#2*8] // 2 instr str arg2w,[rax,#2*4] // 1 instr
str arg1,[rax,#2*8]
//p_unflt //p_unflt
POP4(arg1,arg2,arg3,arg4) ldr rax,[sp,#o_unflt]
POP1(rax) // f_unf ldp arg3,arg4,[sp,#2*NBPW + p_unflt]
ldp arg1,arg2,[sp,#0*NBPW + p_unflt]
cbz arg4,0f // 0==ftid ==> no filter cbz arg4,0f // 0==ftid ==> no filter
blr rax // unfilter blr rax // unfilter
0: 0:
//p_mprot //p_mprot
POP2(arg1,arg2) ldp arg1,arg2,[sp,#p_mprot] // dst, dstlen
mov arg3,#PROT_READ|PROT_EXEC mov arg3,#PROT_READ|PROT_EXEC
do_sys __NR_mprotect do_sys __NR_mprotect
//p_unmap //p_unmap
POP3(arg1,arg2,lr) ldp lr,arg5,[sp,#f_my_ra] // lr= f_my_ra; arg5= o_hatch
br lr // goto hatch ldp arg1,arg2,[sp,#0*NBPW + p_unmap]
mov w8,#__NR_munmap
ldp arg3,arg4,[sp,#2*NBPW + f_argc] // f_uinit
br arg5 // goto hatch
movsl_subr: movsl_subr:
ldr ecx,[rsi,#-4] // 'bl <over>' instruction word ldr ecx,[rsi,#-4] // 'bl <over>' instruction word
@ -312,8 +355,8 @@ movsl: // rdi= 4-byte aligned dst; rsi= 4-byte aligned src; ecx= word count
ret ret
L220: L220:
PUSH1(lr) // &supervise slot f_super // 23
o_super= -20*8 // HOLE str lr,[sp,#f_super]
mov tmpx,lr; bl wlen_subr // wlen_supervise mov tmpx,lr; bl wlen_subr // wlen_supervise
lsl arg2,rdx,#2 // convert to bytes lsl arg2,rdx,#2 // convert to bytes
@ -322,41 +365,41 @@ o_super= -20*8 // HOLE
mov arg5,#-1 // cater to *BSD for fd of MAP_ANON mov arg5,#-1 // cater to *BSD for fd of MAP_ANON
mov arg4,#MAP_PRIVATE|MAP_ANONYMOUS mov arg4,#MAP_PRIVATE|MAP_ANONYMOUS
mov arg3,#PROT_READ|PROT_WRITE // some OS prohibit PROT_WRITE && PROT_EXEC mov arg3,#PROT_READ|PROT_WRITE // some OS prohibit PROT_WRITE && PROT_EXEC
str arg2,[fp,#p_unmap+1*8] // length to unmap str arg2,[sp,#1*NBPW + p_unmap] // length to unmap
mov arg1,#0 // any addr mov arg1,#0 // any addr
do_sys __NR_mmap64; cmn x0,#4096; bcc 0f; brk #0; 0: do_sys __NR_mmap64; cmn x0,#4096; bcc 0f; brk #0; 0:
str x0,[fp,#p_unmap+0*8] // address to unmap str x0,[sp,#0*NBPW + p_unmap] // address to unmap
ldr rsi,[fp,#p_mprot] ldr rsi,[sp,#p_mprot] // dst
//mov edi,r0 // edi= dst NOP: edi==r0 //mov edi,r0 // edi= dst NOP: edi==r0
ldr ecx,[fp,#o_wfrag] // w_fragment ldr ecx,[sp,#o_wfrag] // w_fragment
bl movsl // copy the fragment bl movsl // copy the fragment
ldr rsi,[fp,#p_uncpr] // src ldp rsi,rcx,[sp,#p_uncpr] // src, len
ldr ecx,[fp,#p_uncpr+1*8] // len str rdi, [sp,#p_uncpr] // relocated src
str rdi,[fp,#p_uncpr]
add ecx,ecx,#3; lsr ecx,ecx,#2 add ecx,ecx,#3; lsr ecx,ecx,#2
bl movsl // copy compressed data bl movsl // copy compressed data
mov rdx,rdi // lo(dst) of copied code mov rdx,rdi // lo(dst) of copied code
ldr rsi,[fp,#o_uncpr] ldr rsi,[sp,#o_uncpr]
str rdi,[fp,#o_uncpr] str rdi,[sp,#o_uncpr]
bl movsl_subr // copy decompressor bl movsl_subr // copy decompressor
ldr rsi,[fp,#o_unflt] ldr rsi,[sp,#o_unflt]
str rdi,[fp,#o_unflt] str rdi,[sp,#o_unflt]
bl movsl_subr // copy unfilter bl movsl_subr // copy unfilter
POP1(rsi) // &supervise ldr rsi,[sp,#f_super]
PUSH1(rdi) // &copied str rdi,[sp,#f_super]
bl movsl_subr // copy supervisor bl movsl_subr // copy supervisor
ldp arg1,arg2,[fp,#p_unmap+0*8] ldp arg1,arg2,[sp,#0*NBPW + p_unmap] // PROT_EXEC for supervise
mov arg3,#PROT_READ|PROT_EXEC // some OS prohibit PROT_WRITE && PROT_EXEC mov arg3,#PROT_READ|PROT_EXEC // some OS prohibit PROT_WRITE && PROT_EXEC
do_sys __NR_mprotect; cmn x0,#4096; bcc 0f; brk #0; 0: do_sys __NR_mprotect; cmn x0,#4096; bcc 0f; brk #0; 0:
POP1(lr); br lr // goto copied supervisor ldr lr,[sp,#f_super]
br lr // goto copied supervisor
wlen_subr: // rdx+= nwords of inline subr at *tmp wlen_subr: // rdx+= nwords of inline subr at *tmp
ldr tmp,[tmpx,#-4] // 'bl <over>' instruction word ldr tmp,[tmpx,#-4] // 'bl <over>' instruction word

View File

@ -2,18 +2,18 @@ file format elf64-littleaarch64
Sections: Sections:
Idx Name Size VMA LMA File off Algn Flags Idx Name Size VMA LMA File off Algn Flags
0 ELFMAINX 00000014 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY 0 ELFMAINX 00000034 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY
1 NRV_HEAD 00000000 0000000000000000 0000000000000000 00000054 2**0 CONTENTS, READONLY 1 NRV_HEAD 00000000 0000000000000000 0000000000000000 00000074 2**0 CONTENTS, READONLY
2 NRV_TAIL 00000000 0000000000000000 0000000000000000 00000054 2**0 CONTENTS, READONLY 2 NRV_TAIL 00000000 0000000000000000 0000000000000000 00000074 2**0 CONTENTS, READONLY
3 NRV2E 00000128 0000000000000000 0000000000000000 00000054 2**0 CONTENTS, READONLY 3 NRV2E 00000128 0000000000000000 0000000000000000 00000074 2**0 CONTENTS, READONLY
4 NRV2D 0000011c 0000000000000000 0000000000000000 0000017c 2**0 CONTENTS, READONLY 4 NRV2D 0000011c 0000000000000000 0000000000000000 0000019c 2**0 CONTENTS, READONLY
5 NRV2B 000000f0 0000000000000000 0000000000000000 00000298 2**0 CONTENTS, READONLY 5 NRV2B 000000f0 0000000000000000 0000000000000000 000002b8 2**0 CONTENTS, READONLY
6 LZMA_ELF00 000000d0 0000000000000000 0000000000000000 00000388 2**0 CONTENTS, RELOC, READONLY 6 LZMA_ELF00 000000d0 0000000000000000 0000000000000000 000003a8 2**0 CONTENTS, RELOC, READONLY
7 LZMA_DEC20 00000968 0000000000000000 0000000000000000 00000458 2**0 CONTENTS, READONLY 7 LZMA_DEC20 00000968 0000000000000000 0000000000000000 00000478 2**0 CONTENTS, READONLY
8 LZMA_DEC10 0000049c 0000000000000000 0000000000000000 00000dc0 2**0 CONTENTS, READONLY 8 LZMA_DEC10 0000049c 0000000000000000 0000000000000000 00000de0 2**0 CONTENTS, READONLY
9 LZMA_DEC30 00000000 0000000000000000 0000000000000000 0000125c 2**0 CONTENTS, READONLY 9 LZMA_DEC30 00000000 0000000000000000 0000000000000000 0000127c 2**0 CONTENTS, READONLY
10 ELFMAINY 0000003e 0000000000000000 0000000000000000 0000125c 2**0 CONTENTS, READONLY 10 ELFMAINY 0000003e 0000000000000000 0000000000000000 0000127c 2**0 CONTENTS, READONLY
11 ELFMAINZ 00000298 0000000000000000 0000000000000000 0000129a 2**0 CONTENTS, READONLY 11 ELFMAINZ 00000290 0000000000000000 0000000000000000 000012ba 2**0 CONTENTS, READONLY
SYMBOL TABLE: SYMBOL TABLE:
0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30 0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30
0000000000000000 l d ELFMAINZ 0000000000000000 ELFMAINZ 0000000000000000 l d ELFMAINZ 0000000000000000 ELFMAINZ
@ -36,7 +36,7 @@ SYMBOL TABLE:
RELOCATION RECORDS FOR [ELFMAINX]: RELOCATION RECORDS FOR [ELFMAINX]:
OFFSET TYPE VALUE OFFSET TYPE VALUE
0000000000000010 R_AARCH64_CALL26 ELFMAINZ 0000000000000030 R_AARCH64_CALL26 ELFMAINZ
RELOCATION RECORDS FOR [LZMA_ELF00]: RELOCATION RECORDS FOR [LZMA_ELF00]:
OFFSET TYPE VALUE OFFSET TYPE VALUE