Parsing Call and Ret with ptrace.

I am trying to parse all calls and Rets from an executable using ptrace. According to x64opcode, I found opcodes for calls: 0xe8 and for Rets: 0xc3, 0xc2, 0xca, 0xcb.

Since I parsed them, I found more Rets than Calls.

There is a program that I am tracing:

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

There is my tracer:

 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); } 

There is my conclusion:

 Calls: 656 Rets: 666 Diff: -10 

Why not so many numbers and calls? Am I missing some opcodes? Are there any functions that do not return?

+6
source share
1 answer

You, for example, miss indirect calls, for example

 callq *(<expr>) 

which use other opcodes. Standard Libc initialization procedures use them. Several opcodes are possible, depending on the expression, two examples:

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

Probably not everything is easy to get. It might be easier and cleaner to decode instructions using the libbfd and libopcodes libraries

+4
source

All Articles