3

我正在尝试使用 Intel Pintool在 x86-64 机器(Mac Pro)上进行监控CALL和指令。RET我将IARG_INST_PTR(下面提到)传递给docount函数并使用指令指针我通过检查操作码(CALLRET0xe8 和来自Intel x86-64 手册的 0xc3 来推断指令。但是,似乎这个检查并不完全准确,因为我注意到RETCALL使用此逻辑检测的任何给定二进制文件的数量更多。

INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_CONTEXT,
    IARG_INST_PTR, IARG_END);

谁能给我一些关于我做错了什么的指示?

我从/tools/ManualExamples/inscount0.cpp. 要找到它,请在此处搜索文件名。

4

2 回答 2

0

不同版本的CALLs 具有不同的操作码,所以你不能只检查0xE8. 完整列表可在英特尔手册的调用程序部分中找到:

操作码 指令 说明
E8 cw         CALL rel16     调用近、相对、相对于下一条指令的位移
E8 cd         CALL rel32     调用近、相对、相对于下一条指令的位移
                               32 位位移符号在 64 位模式下扩展到 64 位。
FF /2         CALL r/m16     近调用,绝对间接,在 r/m16 中给出的地址。
FF /2         CALL r/m32     近调用,绝对间接,在 r/m32 中给出的地址。
FF /2         CALL r/m64     近调用,绝对间接,在 r/m64 中给出的地址。
9A cd         CALL ptr16:16  调用远、绝对、在操作数中给出的地址。
9A cp         CALL ptr16:32  调用远、绝对、在操作数中给出的地址。
FF /3         CALL m16:16    呼叫远,m16:16 中给出的绝对间接地址。
                               在 32 位模式下:如果选择器指向一个门,那么
                               RIP = 取自门的 32 位零扩展位移;别的
                               RIP = 距离远指针的零扩展 16 位偏移
                               指令中引用。
FF /3         CALL m16:32    在 64 位模式下:如果选择器指向门,则
                               RIP = 取自门的 64 位位移;别的
                               RIP = 距离远指针的零扩展 32 位偏移
                               指令中引用。
REX.W FF /3   CALL m16:64    在 64 位模式下:如果选择器指向一个门,则
                               RIP = 取自门的 64 位位移;别的
                               RIP = 距远指针的 64 位偏移量
                               指令中引用。

一样RET

操作码* 指令 描述
C3       RET             接近返回调用程序。
CB       RET              Far 返回调用程序。
C2 iw    RET imm16       接近返回调用过程并从堆栈中弹出 imm16 字节。
CA iw    RET imm16        Far 返回调用过程并从堆栈中弹出 imm16 字节。

请注意,上面包含相同操作码的行仅适用于不同的模式(16/32/64 位)

于 2015-04-18T03:36:56.423 回答
0

call 和 ret 指令之间并不总是匹配,因为函数可能会被异常、goto-like 语句、longjumps、信号等中断......所以如果你想重新协调调用和 ret,你可能想要采取考虑到这一切。

这已经讨论过好几次了,尤其是这里

于 2015-09-14T21:45:32.423 回答