1
0
mirror of https://github.com/upx/upx synced 2025-10-05 19:20:23 +08:00
upx/src/stub/l_lx_elf64amd.S
John Reiser 023c06e178 Support for 64-bit AMD x86_64
Makefile
Added Files:
	a_lx_elf64.c amd_bxx.S amd_d_nrv2e.S amd_regs.h
	fold_elf64amd.S l_lx_elf64amd.S l_lx_elf64amd.lds

committer: jreiser <jreiser> 1131566835 +0000
2005-11-09 20:07:15 +00:00

110 lines
3.7 KiB
ArmAsm

/* l_lx_elf64amd.S -- Linux program entry point & decompressor (Elf binary)
*
* This file is part of the UPX executable compressor.
*
* Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
* Copyright (C) 1996-2004 Laszlo Molnar
* Copyright (C) 2000-2005 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>
*/
/*__LEXEC000__*/
_start: .globl _start
/* The following 'call' must be at _start; fold_begin knows this,
and so does PackLinuxElf64amd::pack3() .
*/
call main # push address of decompressor
#include "amd_d_nrv2e.S"
sz_b_info= 12
sz_unc= 0
sz_cpr= 4
b_method= 8
PROT_READ= 1
PROT_WRITE= 2
PROT_EXEC= 4
MAP_PRIVATE= 2
MAP_FIXED= 0x10
MAP_ANONYMOUS= 0x20
SYS_mmap= 9 # 64-bit mode only!
PAGE_SHIFT= 12
PAGE_MASK= (~0<<PAGE_SHIFT)
PAGE_SIZE= -PAGE_MASK
#include "amd_regs.h"
/* Decompress the rest of this loader, and jump to it.
Map a page to hold the decompressed bytes. Logically this could
be done by setting .p_memsz for our first PT_LOAD. But as of 2005-11-09,
linux 2.6.14 only does ".bss expansion" on the PT_LOAD that describes the
highest address. [I regard this as a bug, and it makes the kernel's
fs/binfmt_elf.c complicated, buggy, and insecure.] For us, that is the 2nd
PT_LOAD, which is the only way that linux allows to set the brk() for the
uncompressed program. [This is a signicant kernel misfeature.]
*/
unfold:
pop %rdi # &{ b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...}
subl %arg2l,%arg2l # %arg2= 0
push %rdi # remember &b_info
lea PROT_READ | PROT_WRITE | PROT_EXEC(%arg2),%arg3l
addl sz_cpr(%rdi),%arg1l # n.b.: %rdi===%arg1; XXX: 4GB
lea MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS(%arg2),%sys4l
addl $-1+ sz_b_info,%arg1l # XXX: 4GB
movl $ PAGE_MASK,%ecx
subl %ecx,%arg1l # XXX: 4GB
lea SYS_mmap(%arg2),%eax
andl %ecx,%arg1l # next page boundary after fold; XXX: 4GB
subl %ecx,%arg2l # %arg2l= PAGE_SIZE
push %rcx
subl %arg5l,%arg5l; subl %arg6l,%arg6l
syscall # trashes %rcx
pop %rcx
cmpl %ecx,%eax; jb 0f; hlt; 0: # XXX: 4GB
pop %rsi # %arg2= &b_info
push %rax # ret_addr after decompression
.byte 0x92 # xchg %eax,%arg3l # %arg3= dst for unfolding XXX: 4GB
lodsl; movl %arg2l,%arg4l # &len_dst ==> &do_not_care XXX: 4GB
lodsl; .byte 0x97 # xchg %rax,%arg1l # sz_cpr XXX: 4GB
lodsl; movzbl %al,%arg5l # b_method
xchg %arg1l,%arg2l # XXX: 4GB
jmp *%rbp # goto decompress; return to unfolded loader
main:
# int3 # uncomment for debugging
pop %rbp # &dcompress
call unfold
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
eof:
/*__XTHEENDX__*/
/*
vi:ts=8:et:nowrap
*/