221 lines
5.7 KiB
ArmAsm
221 lines
5.7 KiB
ArmAsm
@ fold_elfarm.asm -- linkage to C code to process Elf binary
|
|
@
|
|
@ This file is part of the UPX executable compressor.
|
|
@
|
|
@ Copyright (C) 2000-2006 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
|
|
@ <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
|
@
|
|
@ John F. Reiser
|
|
@ <jreiser@users.sourceforge.net>
|
|
@
|
|
|
|
sz_Elf32_Ehdr = 13*4
|
|
sz_Elf32_Phdr = 8*4
|
|
sz_l_info = 12
|
|
sz_p_info = 12
|
|
sz_b_info = 12
|
|
sz_unc= 0
|
|
sz_cpr= 4
|
|
b_method= 8
|
|
|
|
@@ control just falls through, after this part and compiled C code
|
|
@@ are uncompressed.
|
|
|
|
#define OVERHEAD 2048
|
|
#define MAX_ELF_HDR 512
|
|
|
|
fold_begin:
|
|
/* In:
|
|
r10= &b_info of first compressed block (after move)
|
|
r9= total size of compressed data
|
|
r5= f_decompress
|
|
sp/ ADRU,LENU,sz_unc,argc,argv...
|
|
*/
|
|
ldr r3,[sp,#3*4] @ argc
|
|
add r3,sp,r3,lsl #2 @ skip argv
|
|
add r3,r3,#3*4 +4 +4 @ skip ADRU,LENU,sz_unc, argc, env_end
|
|
.Lenv:
|
|
ldr r0,[r3],#4 @ skip env
|
|
cmp r0,#0
|
|
bne .Lenv
|
|
/* r3= &Elf32_auxv_t */
|
|
mov r2,r3
|
|
.Laux:
|
|
ldr r0,[r2],#2*4 @ .a_type
|
|
cmp r0,#0
|
|
bne .Laux
|
|
str r2,[sp,#2*4] @ clobber sz_unc with 1+ &Elf32_auxv_t[AT_NULL@.a_type]
|
|
|
|
sub sp,sp,#MAX_ELF_HDR + OVERHEAD @ alloca
|
|
mov r4,r9 @ total size of compressed data
|
|
ldr r9,[r10,#sz_cpr] @ xi.size of ELF headers
|
|
mov r8,sp @ xo.ptr
|
|
ldr r7,[r10,#sz_unc] @ xo.size
|
|
adr r6,f_unfilter
|
|
add r9,r9,#sz_b_info @ for unpackExtent
|
|
mov r11,#0 @ dynbase for ET_EXEC; FIXME for ET_DYN
|
|
stmdb sp!,{r3,r4,r5,r6,r7,r8,r9,r10,r11}
|
|
ldmia sp!,{r0,r1,r2,r3}
|
|
bl upx_main
|
|
mov lr,r0 @ entry address
|
|
add sp,sp,#(9-4)*4
|
|
add sp,sp,#MAX_ELF_HDR + OVERHEAD @ un-alloca
|
|
ldmia sp!,{r0,r1,r2} @ ADRU,LENU,1+ &Elf32_auxv_t[AT_NULL@.a_type]
|
|
ldr pc,[r2,#4 -2*4] @ Elf32_auxv_t[AT_NULL@.a_type].a_val
|
|
|
|
f_unfilter: @ (char *ptr, uint len, uint cto, uint fid)
|
|
ptr .req r0
|
|
len .req r1
|
|
cto .req r2 @ unused
|
|
fid .req r3
|
|
|
|
t1 .req r2
|
|
t2 .req r3
|
|
|
|
and fid,fid,#0xff
|
|
cmp fid,#0x50 @ last use of fid
|
|
movne pc,lr @ no-op if not filter 0x50
|
|
|
|
movs len,len,lsr #2 @ word count
|
|
cmpne ptr,#0
|
|
moveq pc,lr @ no-op if either len or ptr is 0
|
|
|
|
top_unf:
|
|
sub len,len,#1
|
|
ldr t1,[ptr,len,lsl #2]
|
|
and t2,t1,#0x0f<<24
|
|
cmp t2, #0x0b<<24; bne tst_unf @ not 'bl' subroutine call
|
|
and t2,t1,#0xff<<24 @ all the non-displacement bits
|
|
sub t1,t1,len @ convert to word-relative displacement
|
|
bic t1,t1,#0xff<<24 @ restrict to displacement field
|
|
orr t1,t1,t2 @ re-combine
|
|
str t1,[ptr,len,lsl #2]
|
|
tst_unf:
|
|
cmp len,#0
|
|
bne top_unf
|
|
mov pc,lr
|
|
|
|
.unreq ptr
|
|
.unreq len
|
|
.unreq cto
|
|
.unreq fid
|
|
|
|
.globl exit
|
|
exit:
|
|
swi 0x00900001
|
|
|
|
.globl read
|
|
read:
|
|
swi 0x00900003; mov pc,lr
|
|
|
|
.globl write
|
|
write:
|
|
swi 0x00900004; mov pc,lr
|
|
|
|
.globl open
|
|
open:
|
|
swi 0x00900005; mov pc,lr
|
|
|
|
.globl close
|
|
close:
|
|
swi 0x00900006; mov pc,lr
|
|
|
|
.globl brk
|
|
brk:
|
|
swi 0x0090002d; mov pc,lr
|
|
|
|
.globl munmap
|
|
munmap:
|
|
swi 0x0090005b; mov pc,lr
|
|
|
|
.globl mprotect
|
|
mprotect:
|
|
swi 0x0090007d; mov pc,lr
|
|
|
|
.globl mmap
|
|
mmap:
|
|
str r5,[sp,#-4]!; ldr r5,[sp,#4+4]
|
|
str r4,[sp,#-4]!; ldr r4,[sp,#4+4]
|
|
mov r5,r5,lsr #12 @ convert to page number
|
|
swi 0x009000c0 @ mmap64
|
|
ldr r4,[sp],#4
|
|
ldr r5,[sp],#4
|
|
mov pc,lr
|
|
|
|
#if 0 /*{ "gcc-3.4 -fPIC" botches string constants when code moves! */
|
|
.globl STR_0x
|
|
STR_0x:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "0x"
|
|
.balign 4
|
|
|
|
.globl STR_hex
|
|
STR_hex:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "0123456789abcdef"
|
|
.balign 4
|
|
|
|
.globl STR_xread
|
|
STR_xread:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "xread %p(%x %p) %p %x\n"
|
|
.balign 4
|
|
|
|
.globl STR_unpackExtent
|
|
STR_unpackExtent:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "unpackExtent in=%p(%x %p) out=%p(%x %p) %p %p\n"
|
|
.balign 4
|
|
|
|
.globl STR_make_hatch_arm
|
|
STR_make_hatch_arm:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "make_hatch_arm %p %x\n"
|
|
.balign 4
|
|
|
|
.globl STR_auxv_up
|
|
STR_auxv_up:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "auxv_up %p %x %x\n"
|
|
.balign 4
|
|
|
|
.globl STR_xfind_pages
|
|
STR_xfind_pages:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "xfind_pages %x %p %d %p\n"
|
|
.balign 4
|
|
|
|
.globl STR_do_xmap
|
|
STR_do_xmap:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "do_xmap fdi=%x ehdr=%p xi=%p(%x %p) av=%p p_reloc=%p f_unf=%p\n"
|
|
.balign 4
|
|
|
|
.globl STR_upx_main
|
|
STR_upx_main:
|
|
mov r0,pc; mov pc,lr
|
|
.asciz "upx_main av=%p szc=%x f_dec=%p f_unf=%p xo=%p(%x %p) xi=%p(%x %p) dynbase=%x\n",
|
|
.balign 4
|
|
#endif /*}*/
|
|
|
|
@ vi:ts=8:et:nowrap
|
|
|