summaryrefslogtreecommitdiff
path: root/sh.s
blob: e993a306f0c4737bf8728425475050405eee9c4d (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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
section .text
	global _start

_start:
	; TODO: handle interrupt signal

	push rbp
	mov rbp, rsp
	sub rsp, 0x110
	mov r15, rsp
	sub rsp, 0x110
	mov r9, rsp
	sub rsp, 0x110
	mov rbx, rsp

	mov rax, 0x1
	mov rdi, 0x1
	mov rsi, msg
	mov rdx, 0x1b
	syscall

	jmp parse_path

rloop:
	mov rax, 0x1
	mov rdi, 0x1
	mov rsi, prompt
	mov rdx, 0xd
	syscall

	mov r8, -0x1
	mov r12, rloopr
	jmp bzero

rloopr:
	mov rax, 0x0
	mov rdi, 0x0
	mov rsi, r15
	mov rdx, 0xff
	syscall

	; check for quit
	cmp byte [r15], 0x0
	mov r12, quit
	je weol

	; call parse
	jmp parse

exec:
	; fork so we don't hurt ourselves
	mov rax, 0x39
	syscall
	mov dword [cpid], eax
	cmp dword [cpid], 0x0
	jne wait4_it

	; now that we know what to execute, do so
	mov rax, 0x3b
	mov rdi, r13
	mov rsi, r14
	mov rdx, 0x0
	syscall

	; and now kill the child process
	jmp quit

wait4_it:
	mov rdi, rax
	mov rax, 0x3d
	xor rsi, rsi ; null status pointer
	xor rdx, rdx
	xor rcx, rcx ; null rusage pointer
	syscall

	mov dword [cpid], -0x1
	jmp rloop

; input: none
; output: r9 (path elements), r10 (length)
; clobbered: r8, r12
; other: r15 (buffer)
parse_path:
	mov rax, 0x2
	mov rdi, env
	mov rsi, 0x0
	syscall
	cmp rax, 0x0
	jl quit

	mov r8, -0x1
	mov r12, parse_path2
	jmp bzero

parse_path2:
	mov rdi, rax
	mov rax, 0x0
	mov rsi, r9
	mov rdx, 0xff
	syscall
	cmp rax, 0x0
	jl quit
	mov r8, r9
	dec r8

pathfinder:
	inc r8
	xor rax, rax
	mov byte al, [r8]
	cmp al, 0x50
	jne pathfinder
	mov byte al, [r8+1]
	cmp al, 0x41
	jne pathfinder
	mov byte al, [r8+2]
	cmp al, 0x54
	jne pathfinder
	mov byte al, [r8+3]
	cmp al, 0x48
	jne pathfinder
	mov byte al, [r8+4]
	cmp al, 0x3d
	jne pathfinder
	mov byte al, [r8+5]
	cmp al, 0x22
	jne pathfinder
	cmp al, 0x0
	je quit
	add r8, 0x6
	mov r10, 0x1
	push 0x0
	push r8
	dec r8

pathender:
	inc r8
	mov al, [r8]
	cmp al, 0x3a
	je pathender1
	cmp al, 0x22
	jne pathender
	mov byte [r8], 0x0
	mov r9, rsp
	jmp rloop

pathender1:
	inc r10
	mov byte [r8], 0x0
	lea rcx, [r8+0x1]
	push rcx
	jmp pathender

;input: r8 (iterator), r15 (buffer), r12 (return address)
;output: none
bzero:
	inc r8
	mov byte [r8+r15], 0x0
	cmp r8, 0xff
	jle bzero
	jmp r12

;input: r15 (buffer)
;output: r13 (path), r14 (arguments)
;clobbered: r8, rax, rbx, rcx
parse: ; needs special commands: cd exit export echo eval pwd
	;also needs pipes (|, >, <)
	push 0x0
	xor r13, r13
	jmp strlen

; go through and sub/push
parse1:
	cmp byte [r8+r15], 0x20
	je subzp
	cmp byte [r8+r15], 0x0a
	je subz
	cmp byte [r8+r15], 0x2f
	je sabsf

parse1r:
	dec r8
	cmp r8, 0x0
	jl parse2
	jmp parse1

sabsf:
	mov r13, 0x1
	jmp parse1r

subz:
	mov byte [r8+r15], 0x0
	jmp parse1

subzp:
	mov byte [r8+r15], 0x0
	lea rax, [r8+r15+0x1]
	push rax
	jmp parse1

parse2:
	push rbx
	mov r14, rsp
	cmp r13, 0x0
	jg parse7
	mov r8, -0x1

parse3:
	inc r8
	cmp r8, r10
	je parse4
	mov r13, r15
	mov rcx, [r9+r8*8]
	push r8
	jmp concat

parse4: ; not found
	mov rax, 0x1
	mov rdi, 0x1
	mov rsi, nfe
	mov rdx, 0x1a
	syscall
	jmp rloop

parse5: ; test rbx
	pop r8

	mov rax, 0x2
	mov rdi, rbx
	xor rsi, rsi
	xor rdx, rdx
	syscall

	cmp rax, 0x0
	jl parse3
	
	mov rdi, rax
	mov rax, 0x3
	syscall

parse6: ; found it
	mov r13, rbx
	jmp exec

parse7: ; absolute path
	mov rax, 0x2
	mov rdi, r15
	xor rsi, rsi
	xor rdx, rdx
	syscall

	cmp rax, 0x0
	jl parse4

	mov rdi, rax
	mov rax, 0x3
	syscall

	mov r13, r15
	jmp exec
	

;input: r12 (return address), r15 (buffer)
;output: r8 (length)
strlen:
	xor r8, r8

strlen1:
	cmp byte [r8+r15], 0x0
	je parse1
	cmp byte [r8+r15], 0xa
	je parse1
	inc r8
	jmp strlen1

; input: rcx (a), r13 (b)
; output: rbx (string)
; clobbered: r8, r11
concat:
	mov r8, -0x1
	jmp jlen1

jlen1:
	inc r8
	cmp byte [r8+rcx], 0x0
	je jlen02
	cmp byte [r8+rcx], 0xa
	je jlen02
	jmp jlen1

jlen02:
	dec r8
	mov r11, -0x1

jlen2:
	inc r8
	inc r11
	cmp byte [r11+r13], 0x0
	je treg
	cmp byte [r11+r13], 0xa
	je treg
	jmp jlen2

treg:
	cmp r8, 0xff
	jg boe
	xchg r15, rbx
	mov r8, -0x1
	mov r12, rsinc
	jmp bzero

rsinc:
	xchg r15, rbx
	mov r8, -0x1
	mov r11, -0x1

join1:
	inc r8
	cmp byte [r8+rcx], 0x0
	je join02
	cmp byte [r8+rcx], 0xa
	je join02
	mov al, [r8+rcx]
	mov [r8+rbx], al
	jmp join1

join02:
	mov byte [r8+rbx], 0x2f
join2:
	inc r8
	inc r11
	cmp byte [r11+r13], 0x0
	je parse5
	cmp byte [r11+r13], 0xa
	je parse5
	mov al, [r11+r13]
	mov [r8+rbx], al
	jmp join2

boe:
	mov rax, 0x1
	mov rdi, 0x1
	mov rsi, boem
	mov rdx, 0x1f
	jmp quit

; interrupt signal handler
sigint:
	cmp dword [cpid], 0x0
	jl sigint_nc

sigint_c: ; kill the child
	mov rax, 0x3e
	mov rdi, [cpid]
	mov rsi, 0x2
	syscall

sigint_nc:
	mov r12, rloop
	jmp weol

; input: r12 (return address)
; output: none
weol:
	mov rax, 0x1
	mov rdi, 0x1
	mov rsi, eol
	mov rdx, 0x1
	syscall
	jmp r12

quit:
	mov rax, 0x3c
	mov rdi, 0x0
	syscall

section .data
	sigs: dd 0x2
	cpid: dd 0x0
	eol: db 0xa
	msg: db "Welcome to deadbeef shell", 0x21, 0x0a
	prompt: db "[0xdeadbeef]", 0x20
	nfe: db "Error: program not found", 0x2e, 0x0a
	env: db "/etc/environment", 0x0
	boem: db "Error: input overflows buffer", 0x2e, 0x0a