用ptrace解析调用和Ret。

我尝试使用ptrace解析可执行文件中的所有Calls和Rets。 符合x64opcode ,我找到了调用的操作码:0xe8Rets:0xc3,0xc2,0xca,0xcb

自从我解析它们后,我发现了更多的Rets而不是Calls。

有我跟踪的程序:

void func() { write(1, "i", 1); } int main(int ac) { func(); return(0); } 

有我的示踪剂:

 int tracer(t_info *info) { int status; long ptr; int ret = 0; int call = 0; waitpid(info->pid, &status, 0); while (WIFSTOPPED(status)) { ptrace(PTRACE_GETREGS, info->pid, NULL, info->regs); ptr = ptrace(PTRACE_PEEKDATA, info->pid, info->regs->rip); if (((ptr & 0x000000ff) == 0xe8)) // Opcode for call { call++; } else if (((ptr & 0x000000ff) == 0xc3) // Opcodes for rets || ((ptr & 0x000000ff) == 0xc2) || ((ptr & 0x000000ff) == 0xca) || ((ptr & 0x000000ff) == 0xcb)) { ret++; } ptrace(PTRACE_SINGLESTEP, info->pid, 0, 0); waitpid(info->pid, &status, 0); } printf("Calls: %i\nRets: %i\nDiff: %i\n", call, ret, call - ret); return (0); } 

有我的输出:

 Calls: 656 Rets: 666 Diff: -10 

为什么没有相同数量的rets电话 ? 我是否会错过一些操作码? 有没有返回的function?

例如,你错过了间接调用

 callq *() 

使用其他操作码。 Libc标准初始化例程使用这些。 根据表达式,可能有几个操作码,有两个例子:

 ff d0 callq *%rax 41 ff 14 dc callq *(%r12,%rbx,8) 

得到它们可能并不容易。 也许使用像libbfd和libopcodes这样的库解码指令会更容易和更清晰