使用 ptrace 解析 Call 和 Ret。
Parsing Call and Ret with ptrace.
我尝试使用 ptrace 解析来自可执行文件的所有调用和请求。
符合 x64opcode,我发现 Calls 的操作码:0xe8 和 Rets: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 和 calls 的数量不同?
我会错过一些操作码吗?
有没有return的功能?
例如,您错过了像
这样的间接调用
callq *(<expr>)
使用其他操作码。 Libc 标准初始化例程使用这些。根据表达式,可能有几个操作码,两个例子:
ff d0 callq *%rax
41 ff 14 dc callq *(%r12,%rbx,8)
要全部搞定可能并不容易。也许使用像 libbfd 和 libopcodes
这样的库来解码指令会更容易、更清晰
我尝试使用 ptrace 解析来自可执行文件的所有调用和请求。 符合 x64opcode,我发现 Calls 的操作码:0xe8 和 Rets: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 和 calls 的数量不同? 我会错过一些操作码吗? 有没有return的功能?
例如,您错过了像
这样的间接调用callq *(<expr>)
使用其他操作码。 Libc 标准初始化例程使用这些。根据表达式,可能有几个操作码,两个例子:
ff d0 callq *%rax
41 ff 14 dc callq *(%r12,%rbx,8)
要全部搞定可能并不容易。也许使用像 libbfd 和 libopcodes
这样的库来解码指令会更容易、更清晰