【发布时间】:2018-05-08 16:19:02
【问题描述】:
目前,对于一个项目,我需要使用 ptrace() 编写某种调试器。最后,它应该显示程序中进入/退出的每个函数/系统调用以进行跟踪。
现在,我很困惑。我做了一个小程序,它应该尝试跟踪给定的程序,并打印它是否根据操作码(通过寄存器检索)找到调用或系统调用。这里是:
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <sys/user.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t child;
const int long_size = sizeof(long);
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("./bin", "bin", NULL);
} else {
int status;
unsigned ins;
struct user_regs_struct regs;
unsigned char prim, sec;
while (1) {
wait(&status);
if (WIFEXITED(status))
break;
ptrace(PTRACE_GETREGS, child, NULL, ®s);
ins = ptrace(PTRACE_PEEKTEXT, child, regs.rip, NULL);
prim = (unsigned)0xFF & ins;
sec = ((unsigned)0xFF00 & ins) >> 8;
if (prim == 0xE8 && sec == 0xCD)
printf("call found!\n");
if (prim == 0x80 && sec == 0xCD)
printf("syscall found!\n");
ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
}
}
return 0;
}
这是“bin”二进制文件的代码:
#include <unistd.h>
void toto()
{
write(1, "hello\n", 6);
}
int main()
{
toto();
toto();
return (1);
}
当我查看我的迷你调试器的输出时,它似乎只找到一个系统调用和一个调用...我尝试弄乱寄存器和偏移量,但我在互联网上找到的每个教程似乎都是针对32位机器,在我的情况下不起作用:/
有人可以给我一个小提示来帮助我继续吗?
谢谢,祝你有美好的一天!
【问题讨论】:
-
直接使用
ptrace是black art(该术语应用于计算的最后剩下的真实示例之一)。如果有任何方法可以重用已经完成这项工作的现有程序,例如strace或gdb,那么您绝对应该这样做。 -
@zwol 我不能很遗憾:/
-
@tijko 是的,我可能(而且我确信我是)错了,但我看到有人这样做。如果它不起作用,可能是为什么^^...你有什么想法吗?
-
@LeVentilo 编辑了我的回复,如果您仍然需要它