Fix Elf_auxv table. upx was duplicating AT_PHDR (and others)
because Linux 2.4.5 supplies many more AT_ entries than before. First noticed by Sebastian <scut@nb.in-berlin.de>. fold_elf86.asm fold_sh86.asm l_lx_sep86.asm l_lx_elf.c l_lx_sh.c l_lx_sep.c committer: jreiser <jreiser> 994871296 +0000
This commit is contained in:
+53
-34
@@ -24,6 +24,7 @@
|
||||
; markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
;
|
||||
|
||||
%define PAGE_SIZE ( 1<<12)
|
||||
%define szElf32_Ehdr 0x34
|
||||
%define szElf32_Phdr 8*4
|
||||
%define e_entry (16 + 2*2 + 4)
|
||||
@@ -31,7 +32,9 @@
|
||||
%define szb_info 12
|
||||
%define szl_info 12
|
||||
%define szp_info 12
|
||||
%define a_type 0
|
||||
%define a_val 4
|
||||
%define sz_auxv 8
|
||||
|
||||
%define __NR_munmap 91
|
||||
|
||||
@@ -46,17 +49,59 @@ fold_begin: ; enter: %ebx= &Elf32_Ehdr of this program
|
||||
pop eax ; discard &sz_uncompressed
|
||||
pop eax ; discard sz_uncompressed
|
||||
|
||||
; Move argc,argv,envp down so that we can insert more Elf_auxv entries.
|
||||
; Move argc,argv,envp down to make room for complete Elf_auxv table.
|
||||
; Linux kernel 2.4.2 and earlier give only AT_HWCAP and AT_PLATFORM
|
||||
; because we have no PT_INTERP. Linux kernel 2.4.5 (and later?)
|
||||
; give not quite everything. It is simpler and smaller code for us
|
||||
; to generate a "complete" table where Elf_auxv[k -1].a_type = k.
|
||||
; ld-linux.so.2 depends on AT_PHDR and AT_ENTRY, for instance
|
||||
|
||||
%define PAGE_SIZE ( 1<<12)
|
||||
%define OVERHEAD 2048
|
||||
%define MAX_ELF_HDR 512
|
||||
%define AT_NULL 0
|
||||
%define AT_IGNORE 1
|
||||
%define AT_PHDR 3
|
||||
%define AT_NUMBER 20
|
||||
|
||||
mov esi, esp
|
||||
sub esp, byte 6*8 ; AT_PHENT, AT_PHNUM, AT_PAGESZ, AT_ENTRY, AT_PHDR, AT_NULL
|
||||
sub esp, sz_auxv * AT_NUMBER ; more than 128 bytes
|
||||
mov edi, esp
|
||||
call do_auxv
|
||||
do_auxv: ; entry: %esi=src = &argc; %edi=dst. exit: %edi= &AT_NULL
|
||||
; cld
|
||||
|
||||
L10: ; move argc+argv
|
||||
lodsd
|
||||
stosd
|
||||
test eax,eax
|
||||
jne L10
|
||||
|
||||
L20: ; move envp
|
||||
lodsd
|
||||
stosd
|
||||
test eax,eax
|
||||
jne L20
|
||||
|
||||
; complete Elf_auxv table full of AT_IGNORE
|
||||
push edi ; save base of resulting table
|
||||
inc eax ; convert 0 to AT_IGNORE
|
||||
mov ecx, 2 * (AT_NUMBER -1)
|
||||
rep stosd
|
||||
dec eax ; convert AT_IGNORE into AT_NULL
|
||||
stosd ; terminate Elf_auxv
|
||||
stosd
|
||||
pop edi ; base of resulting table
|
||||
|
||||
L30: ; distribute existing Elf32_auxv into new table
|
||||
lodsd
|
||||
test eax,eax ; AT_NULL ?
|
||||
xchg eax,edx
|
||||
lodsd
|
||||
je L40
|
||||
mov [a_type + sz_auxv*(edx -1) + edi], edx
|
||||
mov [a_val + sz_auxv*(edx -1) + edi], eax
|
||||
jmp L30
|
||||
L40:
|
||||
|
||||
%define OVERHEAD 2048
|
||||
%define MAX_ELF_HDR 512
|
||||
|
||||
push ebx ; save &Elf32_Ehdr of this stub
|
||||
sub esp, dword MAX_ELF_HDR + OVERHEAD
|
||||
@@ -67,14 +112,14 @@ fold_begin: ; enter: %ebx= &Elf32_Ehdr of this program
|
||||
mov edx, esp ;
|
||||
mov ecx, [4+ eax] ; length of compressed ELF headers
|
||||
add ecx, byte szb_info
|
||||
pusha ; (AT_next, sz_cpr, f_expand, &tmp_ehdr, {sz_unc, &tmp}, {sz_cpr, &b1st_info} )
|
||||
pusha ; (AT_table, sz_cpr, f_expand, &tmp_ehdr, {sz_unc, &tmp}, {sz_cpr, &b1st_info} )
|
||||
EXTERN upx_main
|
||||
call upx_main ; returns entry address
|
||||
add esp, dword 8*4 + MAX_ELF_HDR + OVERHEAD ; remove 8 params, temp space
|
||||
pop ebx ; &Elf32_Ehdr of this stub
|
||||
push eax ; save entry address
|
||||
|
||||
mov edi, [a_val + edi] ; AT_PHDR
|
||||
mov edi, [a_val + sz_auxv * (AT_PHDR -1) + edi]
|
||||
find_hatch:
|
||||
push edi
|
||||
EXTERN make_hatch
|
||||
@@ -104,31 +149,5 @@ EXTERN make_hatch
|
||||
mov eax, __NR_munmap ; do not dirty the stack with push byte + pop
|
||||
jmp edx ; unmap ourselves via escape hatch, then goto entry
|
||||
|
||||
do_auxv: ; entry: %esi=src = &argc; %edi=dst. exit: %edi= &AT_NULL
|
||||
; cld
|
||||
|
||||
L10: ; move argc+argv
|
||||
lodsd
|
||||
stosd
|
||||
test eax,eax
|
||||
jne L10
|
||||
|
||||
L20: ; move envp
|
||||
lodsd
|
||||
stosd
|
||||
test eax,eax
|
||||
jne L20
|
||||
|
||||
L30: ; move existing Elf32_auxv
|
||||
lodsd
|
||||
stosd
|
||||
test eax,eax ; AT_NULL ?
|
||||
lodsd
|
||||
stosd
|
||||
jne L30
|
||||
|
||||
sub edi, byte 8 ; point to AT_NULL
|
||||
ret
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
|
||||
|
||||
Reference in New Issue
Block a user