我正在编写一个程序来监视系统调用(以及其他事情)。但是我在获取ptrace以识别我要传递给它的进程ID时遇到了一些问题。在执行程序时,我会收到以下错误消息:
:No such process但是,我已经在调用之前通过将进程ID打印到控制台并使用ps -all进行验证来验证进程ID。
以下是一些可能相关的代码(如有必要,我可以发布更多代码):
领导儿童进程:
/* Call to be traced */
if (ptrace (PTRACE_TRACEME, 0, 0, 0) < 0){
perror ("Process couldn't be traced");
exit (-1);
}
/* Execute process image */
if (execv (ProcessArgs[0], &ProcessArgs[1]) < 0){
perror ("Couldn't execute process");
exit (-1);
}在父进程的线程中:
DbgdProcess * _Process = ( DbgdProcess * ) _ProcessPass;
int SystemCall = 0,
Status = 0;
/* I have tried sleep(1) here to wait for PTRACE_ME to no avail */
while (!_Process->CloseSignal){
if ( wait (&Status) < 0) // error handler
if ( WIFEXITED (Status)) // error handler
if (!WIFSTOPPED (Status)) continue;
SystemCall = ptrace (PTRACE_PEEKUSER, _Process->ID, 4 * ORIG_RAX, 0);
if (SystemCall < 0) // error handler
printf ("Process made system call %d\n", SystemCall);
if (ptrace (PTRACE_CONT, _Process->ID, 0, 0) < 0) // error handler
}有人能向我解释一下这种行为吗?
一些额外的注释:
更新:
我从手册上读到这篇文章:
除了PTRACE_ATTACH、PTRACE_SEIZE、PTRACE_TRACEME、PTRACE_INTERRUPT和PTRACE_KILL之外,大多数tracee命令都要求tracee处于ptrace中,否则它们就会在ESRCH中失败。
我相信,ESRCH给出的信息是“没有这样的过程”。所以当我打电话的时候,这个进程可能没有停止?
更新:
我正在测试这个示例中的代码。在执行以下操作后,我才使其工作:-将标头从一个更改(eax_orig * 4)更新到(rax_orig * 8)
但是这些改变也在我的程序中,而且它仍然不起作用。
更新:
我的代码起作用了。我不完全确定为什么,但它开始工作后,我调用了PTRACE_ATTACH在同一个线程,使轮询调用使用ptrace(2)。我猜这意味着必须在父进程的同一个线程中使用ptrace,但我不完全确定。我现在的问题是,有人知道这是不是真的吗?或者,如果不是,为什么ptrace会这样做呢?
更新:
我找到了这个链接,这似乎表明我的问题并非闻所未闻。
发布于 2013-05-27 12:58:19
睡眠(1)有时是不够的;试着睡觉(5)。
发布于 2013-05-27 22:16:19
在检查进程是否已经停止之前,为什么要执行PTRACE_SYSCALL?
理想情况下,在父线程中,应该使用wait等待子线程停止。
一旦子节点停止使用WIFSTOPPED,则只使用任何其他ptrace调用。
PTRACE_SYSCALL似乎正在返回ESRCH。你能确认一下吗?
https://stackoverflow.com/questions/16767832
复制相似问题