[摘要](内存低址) 再看看后续的指令做了些什么? 0x8048443 <main+23>: add 0x4,%esp ; 抛弃栈中为被调用函数准备的参数. 0x8048446 <main...
(内存低址)
再看看后续的指令做了些什么?
0x8048443 <main+23>: add $0x4,%esp ; 抛弃栈中为被调用函数准备的参数.
0x8048446 <main+26>: jmp 0x804845b <main+47> ; 跳转到0x804845b继续执行
0x8048448 <main+28>: mov 0xc(%ebp),%eax ; 0x8048433 jne的条件判断跳转
; 入口(即argc!=2的情况)
; 把ebp+0xc所指向的内存单元的
; 内容赋给eax, 从上面的分析我
; 们知道里面放的是argv的地址
0x804844b <main+31>: mov (%eax),%edx ; 把eax指向的地址的内存单元里
; 的内容赋给edx, 我们知道argv
; 是个数组, argv的值就是argv[0]
0x804844d <main+33>: push %edx ; 把argv[0]入栈. 注意这里的
; argv[0]其实是个地址值.
0x804844e <main+34>: push $0x80484bb ; 把常数0x80484bb入栈
; 以上为调用printf函数准备参数.
0x8048453 <main+39>: call 0x8048330 <printf> ; 调用printf函数
0x8048458 <main+44>: add $0x8,%esp ; 抛弃为调用printf函数准备的参数
0x804845b <main+47>: leave ; 恢复调用main函数的函数的栈帧
0x804845c <main+48>: ret ; 返回到调用main函数的函数
估计0x80484bb指向的是printf函数的format字串, 看看是不是?
(gdb) x/1s 0x80484bb
0x80484bb <_IO_stdin_used+15>: "Usage: %s <A string>\n"
果然是. 那从0x8048448到0x8048458这段指令就是C语言
printf("Usage: %s <A string>\n", argv[0]);
的等价汇编语句了.
我们把断点设到0x804845b, 再继续执行.
(gdb) b *0x804845b
Breakpoint 6 at 0x804845b
(gdb) c
Continuing.
Breakpoint 6, 0x804845b in main ()
下一条指令是leave, 应该是恢复调用函数的函数的栈帧.
单步执行一下, 看看寄存器及栈的情况.
(gdb) si
0x804845c in main ()
(gdb) i reg
eax 0x10 16
ecx 0x400 1024
edx 0x4010a980 1074833792
ebx 0x4010c1ec 1074840044
esp 0xbffff6bc -1073744196
ebp 0xbffff6d8 -1073744168
esi 0x4000ae60 1073786464
edi 0xbffff704 -1073744124
eip 0x804845c 134513756
eflags 0x386 902
(以下省略)
...
(gdb) x/8x $esp
0xbffff6bc: 0x400349cb 0x00000002 0xbffff704 0xbffff710
0xbffff6cc: 0x40013868 0x00000002 0x08048350 0x00000000
下一条指令是ret, 我们知道栈顶放的是main函数的返回地址(0x400349cb).
此时进程在内存中的相关影像:
(内存高址)
关键词:编写自己的缓冲区溢出运用程序