我有以下代码:
Func5() { ShowStackTrace();}
Func4() { Func5();}
这是我的堆栈跟踪 -
**Frame for Func5**
EIP : 403899
Function name : Func5
EBP : 12ff0c
ESP : 12fed0
Return address : 4038c8
CS : 23
DS : 9998
ESI : 0
EDI : 0
**Frame for Func4**
Function name : Func4
EBP : 12ff14
ESP : 12ff14
CS : 23
DS : 9998
ESI : 0
EDI : 0
现在使用Func5的返回地址,我得到了它上面的前5个字节
ff ff ff 88 E8
这里存在E8意味着这是一个调用语句(near),接下来的4个字节用于计算地址。因此,当我们读取CALL Func5时,EIP将是4038c3。如何从这些数据计算Func5的起始地址? 请告诉您是否需要任何其他数据。如果这是一个远程调用(操作码 - FF),如何进行计算?
答案 0 :(得分:3)
您正在按相反顺序打印字节。正确的顺序是:
E8 88 ff ff ff
其中E8
是“jump relative imm32”的操作码
这意味着jump relative 0xFFFFFF88
或-0x78
,因为x86使用的是小端。
编辑:它相对于调用指令后的下一个字节。例如,
0x100: E8 10 00 00 00 ;// call relative, will call 0x115 (0x105 + 0x10)
;// and will leave 0x105 on the stack as return address
0x105: 90 ;// next instruction
答案 1 :(得分:1)
这取决于平台。在大多数UNICES上,dladdr为地址提供最近的符号。
在Windows上它更复杂:查看dbghelp.dll和msapi.dll API。 我不记得,但这已经不远了。