$ gcc -g -o testshellcode testshellcode.c #为了调试,需要在编译时加-g选项 $ gdb ./testshellcode #启动gdb调试 ... (gdb) set logging on #如果要记录调试过程中的信息,可以把日志记录功能打开 Copying output to gdb.txt. (gdb) l main #列出源代码 20 21 return sum; 22 } 23 24 int main() 25 { 26 int sum; 27 28 sum = func(1, 2, 3); 29 (gdb) break 28 #在调用func函数之前让程序停一下,以便记录当时的ebp(基指针) Breakpoint 1 at 0x80483ac: file testshellcode.c, line 28. (gdb) break func #设置断点在函数入口,以便逐步记录栈信息 Breakpoint 2 at 0x804835c: file testshellcode.c, line 13. (gdb) disassemble main #反编译main函数,以便记录调用func后的下一条指令地址 Dump of assembler code for function main: 0x0804839b <main+0>: lea 0x4(%esp),%ecx 0x0804839f <main+4>: and $0xfffffff0,%esp 0x080483a2 <main+7>: pushl 0xfffffffc(%ecx) 0x080483a5 <main+10>: push %ebp 0x080483a6 <main+11>: mov %esp,%ebp 0x080483a8 <main+13>: push %ecx 0x080483a9 <main+14>: sub $0x14,%esp 0x080483ac <main+17>: push $0x3 0x080483ae <main+19>: push $0x2 0x080483b0 <main+21>: push $0x1 0x080483b2 <main+23>: call 0x8048354 <func> 0x080483b7 <main+28>: add $0xc,%esp 0x080483ba <main+31>: mov %eax,0xfffffff8(%ebp) 0x080483bd <main+34>: sub $0x8,%esp 0x080483c0 <main+37>: pushl 0xfffffff8(%ebp) 0x080483c3 <main+40>: push $0x80484c0 0x080483c8 <main+45>: call 0x80482a0 <printf@plt> 0x080483cd <main+50>: add $0x10,%esp 0x080483d0 <main+53>: mov $0x0,%eax 0x080483d5 <main+58>: mov 0xfffffffc(%ebp),%ecx 0x080483d8 <main+61>: leave 0x080483d9 <main+62>: lea 0xfffffffc(%ecx),%esp 0x080483dc <main+65>: ret End of assembler dump. (gdb) r #运行程序 Starting program: /mnt/hda8/Temp/c/program/testshellcode
Breakpoint 1, main () at testshellcode.c:28 28 sum = func(1, 2, 3); (gdb) print $ebp #打印调用func函数之前的基地址,即Previous frame pointer。 $1 = (void *) 0xbf84fdd8 (gdb) n #执行call指令并跳转到func函数的入口
Breakpoint 2, func (a=1, b=2, c=3) at testshellcode.c:13 13 int sum = 0; (gdb) n 16 sum = a + b + c; (gdb) x/11x $esp #打印当前栈的内容,可以看出,地址从低到高,注意标记有蓝色和红色的值 #它们分别是前一个栈基地址(ebp)和call调用之后的下一条指令的指针(eip) 0xbf84fd94: 0x00000000 0x00000000 0x080482e0 0x00000000 0xbf84fda4: 0xb7f2bce0 0x00000000 0xbf84fdd8 0x080483b7 0xbf84fdb4: 0x00000001 0x00000002 0x00000003 (gdb) n #执行sum = a + b + c,后,比较栈内容第一行,第4列,由0变为6 18 memset(buffer, '\0', BUF_SIZE); (gdb) x/11x $esp 0xbf84fd94: 0x00000000 0x00000000 0x080482e0 0x00000006 0xbf84fda4: 0xb7f2bce0 0x00000000 0xbf84fdd8 0x080483b7 0xbf84fdb4: 0x00000001 0x00000002 0x00000003 (gdb) n 19 memcpy(buffer, STR_SRC, sizeof(STR_SRC)-1); (gdb) x/11x $esp #缓冲区初始化以后变成了0 0xbf84fd94: 0x00000000 0x00000000 0x00000000 0x00000006 0xbf84fda4: 0xb7f2bce0 0x00000000 0xbf84fdd8 0x080483b7 0xbf84fdb4: 0x00000001 0x00000002 0x00000003 (gdb) n 21 return sum; (gdb) x/11x $esp #进行copy以后,这两列的值变了,大小刚好是7个字节,最后一个字节为'\0' 0xbf84fd94: 0x00000000 0x41414141 0x00414141 0x00000006 0xbf84fda4: 0xb7f2bce0 0x00000000 0xbf84fdd8 0x080483b7 0xbf84fdb4: 0x00000001 0x00000002 0x00000003 (gdb) c Continuing. sum = 6
Program exited normally. (gdb) quit
|