I was trying to make my C program execute shellcode. Please look at the following.
root@ninja:~/Desktop/Programs# gdb -q ./a.out
Reading symbols from /root/Desktop/Programs/a.out...done.
(gdb) list 1
1 void function(void) {
2 int *ret;
3 int var;
4 char code[]=
5 "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
6 "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
7 "\xe1\xcd\x80";
8 ret = &var + 3;
9 (*ret) = (int) code;
10 }
(gdb)
11
12 void main() {
13 function();
14 }
(gdb) break 9
Breakpoint 1 at 0x804842a: file exp2.c, line 9.
(gdb) break 10
Breakpoint 2 at 0x8048432: file exp2.c, line 10.
(gdb) run
Starting program: /root/Desktop/Programs/a.out
Breakpoint 1, function () at exp2.c:9
9 (*ret) = (int) code;
(gdb) x/9xw code
0xbffff4a4: 0xdb31c031 0xb099c931 0x6a80cda4 0x6851580b
0xbffff4b4: 0x68732f2f 0x69622f68 0x51e3896e 0x8953e289
0xbffff4c4: 0x0080cde1
(gdb) x/i *ret
0x804843c <main+8>: pop %ebp
(gdb) c
Continuing.
Breakpoint 2, function () at exp2.c:10
10 }
(gdb) x/i *ret
0xbffff4a4: xor %eax,%eax
(gdb) nexti(2)
0xbffff4a4 in ?? ()
(gdb) x/3i $eip
=> 0xbffff4a4: xor %eax,%eax
0xbffff4a6: xor %ebx,%ebx
0xbffff4a8: xor %ecx,%ecx
(gdb) nexti
Program received signal SIGSEGV, Segmentation fault.
0xbffff4a4 in ?? ()
(gdb) nexti
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
var
was used as a point of reference to make ret
point to the return address of function()
. Then, the return address was changed to the start of code
. function()
returned to code
. However, the program terminated without executing the code. Thanks to @blatinox, I learnt that this was because the stack was non-executable.
I re-compiled the program with -z execstack
. The program now could execute the code, but I got another problem:
Starting program: /root/Desktop/Programs/a.out
Breakpoint 1, function () at exp2.c:9
9 (*ret) = (int)code;
(gdb) x/i *ret
0x804843c <main+8>: pop %ebp
(gdb) c
Continuing.
Breakpoint 2, function () at exp2.c:10
10 }
(gdb) x/i *ret
0xbffff4a4: xor %eax,%eax
(gdb) x/i code
0xbffff4a4: xor %eax,%eax
(gdb) nexti(2)
0xbffff4a4 in ?? ()
(gdb) x/17i $eip
=> 0xbffff4a4: xor %eax,%eax
0xbffff4a6: xor %ebx,%ebx
0xbffff4a8: xor %ecx,%ecx
0xbffff4aa: cltd
0xbffff4ab: mov $0xa4,%al
0xbffff4ad: int $0x80
0xbffff4af: push $0xb
0xbffff4b1: pop %eax
0xbffff4b2: push %ecx
0xbffff4b3: push $0x68732f2f
0xbffff4b8: push $0x6e69622f
0xbffff4bd: mov %esp,%ebx
0xbffff4bf: push %ecx
0xbffff4c0: mov %esp,%edx
0xbffff4c2: push %ebx
0xbffff4c3: mov %esp,%ecx
0xbffff4c5: int $0x80
(gdb) nexti(14)
0xbffff4c2 in ?? ()
(gdb) x/3i $eip
=> 0xbffff4c2: push %ebx
0xbffff4c3: mov %esp,%ecx
0xbffff4c5: int $0x80
(gdb) nexti
0xbffff4c3 in ?? ()
(gdb) x/2i $eip
=> 0xbffff4c3: mov %ecx,%esp
0xbffff4c5: hlt
(gdb) nexti
0xbffff4c5 in ?? ()
(gdb) x/i $eip
=> 0xbffff4c5: hlt
(gdb) nexti
Program received signal SIGSEGV, Segmentation fault.
0xbffff4c5 in ?? ()
(gdb)
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
0xbffff4c3: mov %esp,%ecx
changed to 0xbffff4c3: mov %ecx,%esp
, and 0xbffff4c5: int $0x80
changed to 0xbffff4c5: hlt
.
Why did the last two lines of the code change while executing?