summaryrefslogtreecommitdiff
path: root/other/burneye/src/stub/init.asm
blob: 3633dab5c0c396f12ed91c764dfdb33a93b83f2f (plain)
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]
;