本文为张银奎老师《代码调试》一书中关于的栈实验,记录下照猫画虎的学习过程。
代码:
int __stdcall Proc(int n) { int a=n; printf("A test to inspect stack, n=%d,a=%d.",n,a); return n*a; } int main() { return func(1); }
汇编如下:
HiStack!Proc: 00401000 56 push esi 00401001 8b742408 mov esi,dword ptr [esp+8] 00401005 56 push esi 00401006 56 push esi 00401007 6830804000 push offset HiStack!`string' (00408030) 0040100c e81f000000 call HiStack!printf (00401030) 00401011 83c40c add esp,0Ch 00401014 8bc6 mov eax,esi 00401016 0fafc6 imul eax,esi 00401019 5e pop esi 0040101a c20400 ret 4 0040101d 90 nop 0040101e 90 nop 0040101f 90 nop HiStack!main: 00401020 6a7a push 7Ah 00401022 e8d9ffffff call HiStack!Proc (00401000) 00401027 c3 ret 00401028 90 nop 00401029 90 nop 0040102a 90 nop 0040102b 90 nop 0040102c 90 nop 0040102d 90 nop 0040102e 90 nop
bp a!main 设置断点 g执行到这个断点
0:000> r eip,esp
eip=00401020 esp=0013ff84
0:000> dd esp l1
0013ff84 00401115
p单步执行一次
0:000> r eip,esp
eip=00401022 esp=0013ff80
esp中压入一个int所需空间,向下减去4
t进入函数
0:000> r eip,esp
eip=00401000 esp=0013ff7c
esp又减去4个字节,压入了函数的返回后的地址 可以用dd esp l1显示返回地址的内容
0:000> dd esp l1
0013ff7c 00401027
光标定位到ret 4一行,ctrl+F10执行到这一行,观察eip和esp
0:000> r eip,esp
eip=0040101a esp=0013ff7c
esp内容和刚进入函数时一样,栈保持平衡。
p单步执行,到达c3 ret
0:000> r eip,esp
eip=00401027 esp=0013ff84
esp增加了8,和刚进入main时一样,参数被被调用函数func清理。
0:000> dd esp l1
0013ff84 00401115