处理内存中的近调用¶
在汇编程序中,近调用看起来像这样:
这个近调用由字节 0xE8 表示,所以你可能会认为它存储在内存中是这样的:
或者,拆成单字节并按字节序交换后,像这样:
但内存中近调用的结构没那么简单。近调用不存储被调用者的绝对地址,而是存储相对于调用之后立即地址的被调用者偏移量。由于近调用是 5 字节,调用之后的立即地址在内存中晚 5 字节。因此,存储的地址可以这样计算:
如果 CALL 0x0BADF00D 在内存中位于 0xDEADBEEF,那么 0xE8 之后的值是:
那么在内存中,这条 CALL 指令看起来像这样:
要钩住一个近调用,你首先需要更改 0xE8 之后的偏移量(即小端序的 0x19 0x31 0x00 0x2D),让它指向你的新被调用者。