1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
; fold_elf86.asm -- linkage to C code to process Elf binary
;
; This file is part of the UPX executable compressor.
;
; Copyright (C) 2000-2001 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 John F. Reiser
; markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
;
%define szElf32_Ehdr 0x34
%define szElf32_Phdr 8*4
%define e_entry (16 + 2*2 + 4)
%define p_memsz 5*4
%define szb_info 12
%define szl_info 12
%define szp_info 12
%define a_val 4
%define __NR_munmap 91
;; control just falls through, after this part and compiled C code
;; are uncompressed.
fold_begin: ; enter: %ebx= &Elf32_Ehdr of this program
; patchLoader will modify to be
; dword sz_uncompressed, sz_compressed
; byte compressed_data...
pop eax ; discard &sz_uncompressed
pop eax ; discard sz_uncompressed
; Move argc,argv,envp down so that we can insert more Elf_auxv entries.
; 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
mov esi, esp
sub esp, byte 6*8 ; AT_PHENT, AT_PHNUM, AT_PAGESZ, AT_ENTRY, AT_PHDR, AT_NULL
mov edi, esp
call do_auxv
push ebx ; save &Elf32_Ehdr of this stub
sub esp, dword MAX_ELF_HDR + OVERHEAD
lea eax, [szElf32_Ehdr + 2*szElf32_Phdr + szl_info + szp_info + ebx] ; 1st &b_info
mov esi, [e_entry + ebx] ; beyond compressed data
sub esi, eax ; length of compressed data
mov ebx, [ eax] ; length of uncompressed ELF headers
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} )
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
find_hatch:
push edi
EXTERN make_hatch
call make_hatch ; find hatch = make_hatch(phdr)
pop ecx ; junk the parameter
add edi, byte szElf32_Phdr ; prepare to try next Elf32_Phdr
test eax,eax
jz find_hatch
xchg eax,edx ; edx= &hatch
; _dl_start and company (ld-linux.so.2) assumes that it has virgin stack,
; and does not initialize all its stack local variables to zero.
; Ulrich Drepper (drepper@cyngus.com) has refused to fix the bugs.
; See GNU wwwgnats libc/1165 .
%define N_STKCLR (0x100 + MAX_ELF_HDR + OVERHEAD)/4
lea edi, [esp - 4*N_STKCLR]
pusha ; values will be zeroed
mov ecx, N_STKCLR
xor eax,eax
rep stosd
xor ecx, ecx ; 0
mov ch, PAGE_SIZE>>8 ; 0x1000
add ecx, [p_memsz + szElf32_Ehdr + ebx] ; length to unmap
mov bh, 0 ; from 0x401000 to 0x400000
push byte __NR_munmap
pop eax
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
|