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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
; burneye initialization function
GLOBAL be_entry
EXTERN burneye
; this is the central entry point of the program
; we have to take care about not destorying the kernel supplied auxv's
;
; WARNING: this code is quite unclean, you do not want to mess with it, really
be_entry:
pushf
; ebx = addr, ecx = len, edx = prot
; mov ebx, 0x05370000 ; addr
; mov edx, 0x0007 ; PROT_READ | PROT_WRITE | PROT_EXEC
; mov ecx, be_payload
; mov ecx, 0x0000b000
; sub ecx, 0x05371000
; mov eax, 0x7d ; __NR_mprotect
; int 0x80
pop ebx
mov esi, esp
call be_auxv ; ecx = number of vectors, edx = base
mov ebp, edx ; base of auxv
cmp ecx, 32 ; more than 32 vectors
jl rel_auxv ; not enough -> relocate
xor eax, eax
jmp do_auxv
; we need eax more vectors
rel_auxv:
mov eax, 32
sub eax, ecx
shl eax, 3 ; * 8
do_auxv:
mov esi, esp
sub esp, eax
mov edi, esp
sub ebp, eax
; relocate auxiliary vectors
call be_auxvreloc ; in: esi = &argc ; out: edx = env[0]
pop eax ; eax = argc
push eax
push ebx ; SAVE flag register
push eax ; argc
mov eax, esp
add eax, 12 ; &argv[0]
push eax
push edx ; env
push ebp ; lowest vector
push ecx ; number of real vectors, space is for 32
call burneye ; returns: eax = entry point of rtld/exe
add esp, (5 * 4)
pop ebx ; RESTORE flag register
push eax ; save entry point on stack, to 'ret' to
; make an 'oops... i did it again' virgin stack space
%define BRITNEY 1024
lea edi, [esp - 4 * BRITNEY]
pusha
sub esp, (BRITNEY * 4)
mov ecx, BRITNEY
xor eax, eax
rep stosd ; zap array
add esp, (BRITNEY * 4)
; thanks to john reiser <jreister@bitwagon.com> for fixing this nasty
; bug :-)
push ebx ; i hate x86 register poorness
popf ; restore original flags
push dword 0 ; clear stack element
pop ebx
%ifdef VDEBUG
int3 ; FINAL BREAKPOINT
%endif
popa ; all regs except eip/esp are zero'ed now
ret ; return to entry point of ld-linux.so.*
; be_auxvreloc, insert
;
; in: esi = source &argc, edi = dest
; out: edi = &old_auxv[AT_NULL]
;
be_auxvreloc:
rarg: lodsd
stosd
or eax, eax
jnz be_auxvreloc
mov edx, edi ; new &env[0]
renv: lodsd
stosd
or eax, eax
jnz renv
raux: lodsd
stosd
or eax, eax
lodsd
stosd
jnz raux
sub edi, 8
ret
; be_auxv, find and count aux vectors
;
; stack looks like (at esi);
; <argc> <argc pointers> <NULL> <env[0], env[1], ...> <NULL> <aux> <env>
be_auxv:
; skip arguments
lodsd
shl eax, 2
add eax, 4
add esi, eax
; skip environment
skenv: lodsd
or eax, eax
jnz skenv
xor ecx, ecx ; counter = 0
mov edx, esi ; &auxv[0]
skaux: lodsd
inc ecx
or eax, eax
lodsd
jnz skaux
; we have ecx vectors now, INCLUDING the AT_NULL vector
ret
; be_findenv, find environment pointer array
;
; esi = pointer to lowest vector
;
; return: esi = env[0]
;
|