通过分析函数调用过程的堆栈变化,可以看出在被调函数的EBP寄存器地址存放的是调用函数的EBP寄存器地址,EBP地址+4存放的是函数调用完成后的下一条指令存放地址,该指令的前一条指令则是调用函数的指令。说起来有点拗口,接下来代码分析一下:
分析使用的源码如下:
int _cdecl FunA(int a, int b)
{
int d;
d = a + b;
return d;
}
int _cdecl FunB(int a, int b)
{
return FunA(a, b);
}
int _cdecl FunC(int a, int b)
{
return FunB(a, b);
}
int _cdecl main(int argc, char* argv[])
{
int r;
r = FunC(2, 3);
return 0;
}
在函数FunA内的任意位置添加断点,然后执行代码,则会在该处停住,通过VS的cmd窗口分析步骤如下:
1、 查看寄存器值,得出EBP=0x002FF734
2、 根据该EBP,找到FuncA返回后的指令执行地址0x0005142B
3、 因为CALL函数执行的机器码=call机器码(1个字节)+函数地址(4个字节),得出call funcA这条指令的执行地址为0x00051426(0x0005142B-5)
4、 得出指令机器码为e8 6b fc ff ff
5、 机器码算出调用指令地址 0Xfffffc6B+5(五个字节)