For an assignment, I wrote the following assembly code shell_exec.asm
that should execute a shell in Linux:
section .data ; declare stuff
arg0 db "/bin/sh",0 ; 1st arg
align 4
argv dd arg0, 0 ; 2nd arg
envp dd 0 ; 3rd arg
section .text
global _start
_start:
mov eax, 0x0b ; execve
mov ebx, arg0 ; 1st arg
mov ecx, argv ; 2nd arg
mov edx, envp ; 3rd arg
int 0x80 ; kernel
I used nasm -f elf32 shell_exec.asm
for compilation and ld -m elf_i386 -o shell_exec shell_exec.o
for linking. Everything works so far and if I run ./shell_exec
the shell spawns the way I want.
Now I wanted to extract the shell code (like \12\34\ab\cd\ef...
) from this program. I used objdump -D -z shell_exec
to show all parts of the code including the section .data
and all zeroes. The output is as follows:
shell_exec: file format elf32-i386
Disassembly of section .text:
08049000 <_start>:
8049000: b8 0b 00 00 00 mov $0xb,%eax
8049005: bb 00 a0 04 08 mov $0x804a000,%ebx
804900a: b9 08 a0 04 08 mov $0x804a008,%ecx
804900f: ba 10 a0 04 08 mov $0x804a010,%edx
8049014: cd 80 int $0x80
Disassembly of section .data:
0804a000 <arg0>:
804a000: 2f das
804a001: 62 69 6e bound %ebp,0x6e(%ecx)
804a004: 2f das
804a005: 73 68 jae 804a06f <__bss_start+0x5b>
804a007: 00 add %al,(%eax)
0804a008 <argv>:
804a008: 00 a0 04 08 00 00 add %ah,0x804(%eax)
804a00e: 00 00 add %al,(%eax)
0804a010 <envp>:
804a010: 00 00 add %al,(%eax)
804a012: 00 00 add %al,(%eax)
If I only have a section .text
within my assembly code, I can usually just copy all given values and use them as my shell code. But how is the order in case I have those two sections, namely .data
and .text
?
Edit 1
So, my second attempt is to do the assembly code like this:
section .text
global _start
_start:
mov ebp, esp
xor eax, eax
push eax ; -4
push "/sh " ; -8
push "/bin" ; -12
xor eax, eax
push eax
lea ebx, [ebp-12]
push ebx ; 1st arg
mov ecx, esp ; 2nd arg
lea edx, [ebp-4] ; 3rd arg
mov eax, 0x0b ; execve
int 0x80 ; kernel
This avoids using multiple sections, but sadly leads to a segmentation fault.