mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
204 lines
5.1 KiB
ArmAsm
204 lines
5.1 KiB
ArmAsm
/* arm64-linux.elf-so_entry.S -- Linux DT_INIT & decompressor (Elf shared lib)
|
|
*
|
|
* This file is part of the UPX executable compressor.
|
|
*
|
|
* Copyright (C) 1996-2021 Markus Franz Xaver Johannes Oberhumer
|
|
* Copyright (C) 1996-2021 Laszlo Molnar
|
|
* Copyright (C) 2000-2025 John F. Reiser
|
|
* All Rights Reserved.
|
|
*
|
|
* UPX and the UCL library are free software; you can redistribute them
|
|
* and/or modify them under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file COPYING.
|
|
* If not, write to the Free Software Foundation, Inc.,
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* Markus F.X.J. Oberhumer Laszlo Molnar
|
|
* <markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
*
|
|
* John F. Reiser
|
|
* <jreiser@users.sourceforge.net>
|
|
*/
|
|
|
|
NBPW= 8
|
|
#include "arch/arm64/v8/macros.S"
|
|
lr .req x30
|
|
|
|
#define DEBUG 0
|
|
|
|
sz_Elf64_Ehdr = 8*NBPW
|
|
sz_Elf64_Phdr = 7*NBPW
|
|
|
|
sz_b_info= 12
|
|
sz_unc= 0
|
|
sz_cpr= 4
|
|
b_method= 8
|
|
sz_l_info= 12
|
|
sz_p_info= 12
|
|
|
|
PROT_READ= 1
|
|
PROT_WRITE= 2
|
|
PROT_EXEC= 4
|
|
|
|
MAP_PRIVATE= 2
|
|
MAP_FIXED= 0x10
|
|
MAP_ANONYMOUS= 0x20
|
|
|
|
// /usr/include/asm-generic/unistd.h
|
|
__NR_close = 0x39 // 57
|
|
__NR_exit = 0x5d // 93
|
|
__NR_memfd_create = 0x117 // 279
|
|
__NR_mmap = 0xde // 222
|
|
__NR_mprotect = 0xe2 // 226
|
|
__NR_munmap = 0xd7 // 215
|
|
__NR_openat = 0x38 // 56
|
|
__NR_read = 0x3f // 63
|
|
__NR_write = 0x40 // 64
|
|
|
|
arg1 .req x0
|
|
arg1w .req w0
|
|
arg2 .req x1
|
|
arg2w .req w1
|
|
arg3 .req x2
|
|
arg3w .req w2
|
|
arg4 .req x3
|
|
arg4w .req w3
|
|
arg5 .req x4
|
|
arg5w .req w4
|
|
arg6 .req x5
|
|
arg6w .req w5
|
|
|
|
#define bkpt brk #0
|
|
#define call bl
|
|
|
|
section ELFMAINX
|
|
// .long offset(b_info)|(asl_delta>>12) src for f_exp FIXME: really?
|
|
//SO_INFO:
|
|
// .word offset(.) // detect relocation
|
|
// .word offset(user DT_INIT)
|
|
// .word offset(escape_hatch) // override with round_up(2, PT_LOAD[0]{.p_memsz + .p_vaddr})
|
|
// .word offset(dst for f_exp)
|
|
|
|
.balign 4
|
|
_start: .globl _start
|
|
// bkpt // DEBUG
|
|
PUSH4 (x0,x1,x2,lr) // MATCH_00
|
|
|
|
sub sp,sp,#2*NBPW // space for ADRU, LENU
|
|
F_ADRU= 0 * NBPW
|
|
F_LENU= 1 * NBPW
|
|
F_ARGC= 2 * NBPW
|
|
|
|
adr x30,fold_info // assembler bug: 'lr' not an integer register
|
|
foldi .req x30
|
|
old_sp .req x14 // busy: lr,x14
|
|
mov old_sp,sp
|
|
ldr w0,[foldi,#sz_unc]
|
|
str x0,[old_sp,#F_LENU]
|
|
sub x0,sp,x0 // alloca
|
|
and sp,x0,#-2*NBPW // align stack
|
|
|
|
psa_fd .req w5
|
|
aux_end .req x4
|
|
page_m .req x7
|
|
|
|
AT_PAGESZ= 6
|
|
O_RDONLY= 0
|
|
mov w2,#O_RDONLY
|
|
adr x1,str_psa
|
|
mov w0,#0
|
|
do_sys __NR_openat; mov psa_fd,w0
|
|
mov x1,sp // buffer
|
|
mov x2,#512 // len
|
|
do_sys __NR_read; add aux_end,x1,x0 // end
|
|
mov w0,psa_fd; do_sys __NR_close
|
|
.unreq psa_fd
|
|
0:
|
|
ldr x0,[x1,#NBPW] // value
|
|
ldr x2,[x1],#2*NBPW // tag
|
|
cmp x2,#AT_PAGESZ; beq 1f
|
|
cmp x1,aux_end; blo 0b; mov x0,#1<<12 // default 4KiB
|
|
.unreq aux_end
|
|
1:
|
|
sub page_m,xzr,x0 // PAGE_MASK
|
|
|
|
add arg4,old_sp,#F_LENU // &dstlen
|
|
mov arg3,sp // dst for decompress
|
|
ldr arg2w,[foldi,#sz_cpr] // srclen
|
|
add arg1,foldi,#sz_b_info // src
|
|
.unreq foldi // busy: x14
|
|
bl f_decompress
|
|
|
|
mov arg2w,#0
|
|
adr arg1,str_upx
|
|
mfd .req w15 // busy: x15,x14
|
|
do_sys __NR_memfd_create; mov mfd, w0
|
|
|
|
str page_m, [sp,#0]
|
|
mov arg2,sp
|
|
ldr arg3,[old_sp,#F_LENU]
|
|
do_sys __NR_write
|
|
mov sp,old_sp // de-alloca
|
|
.unreq old_sp // busy: x15
|
|
|
|
mov arg6,#0 // beginning of file
|
|
mov arg5w,mfd
|
|
mov arg4w,#MAP_PRIVATE // modes
|
|
mov arg3w,#PROT_READ|PROT_EXEC // prot
|
|
ldr arg2,[sp,#F_LENU]
|
|
mov arg1,#0 // addr (kernel chooses)
|
|
do_sys __NR_mmap; str x0,[sp,#F_ADRU]
|
|
u_ptr .req x14 // busy: x15,x14
|
|
mov u_ptr,x0
|
|
|
|
mov arg1w,mfd
|
|
.unreq mfd // busy: x14
|
|
do_sys __NR_close
|
|
|
|
adr arg1,_start - 4*4 // &SO_INFO
|
|
add arg2,sp,#F_ARGC // &{argc, argv, envp}
|
|
add u_ptr,u_ptr,2*NBPW
|
|
br u_ptr
|
|
.unreq u_ptr
|
|
|
|
str_upx:
|
|
.asciz "upx"
|
|
str_psa:
|
|
.asciz "/proc/self/auxv"
|
|
.balign 4
|
|
|
|
//%esp:
|
|
// MATCH_04 ptr unfolded_code
|
|
// MATCH_10 len unfolded_code
|
|
// MATCH_00 argc,argv,envp,lr(_start)
|
|
|
|
f_decompress:
|
|
// nrv2b code is hard-wired here
|
|
#define NO_METHOD_CHECK 1
|
|
|
|
// only one de-compressor; build 'eof' return
|
|
#undef DAISY_CHAIN
|
|
|
|
// use of mmap() forces implcit cache sync
|
|
#define NO_SYNC_CACHE 1
|
|
|
|
off .req w5
|
|
#include "arch/arm64/v8/nrv2b_d32.S"
|
|
|
|
// IDENTSTR goes here
|
|
|
|
section ELFMAINZ
|
|
fold_info:
|
|
// b_info (sz_unc, sz_cpr, method) of folded code (C-language, etc.)
|
|
|
|
/* vim:set ts=8 sw=8 et: */
|