无法使PTRACE_SEIZED(ptrace请求)工作

时间:2017-07-06 22:24:38

标签: c linux

我正在使用ptrace并尝试获取我的进程的注册系统调用值(orig_rax),使用PTRACE_TRACEME请求(tracer / tracee)执行此操作时没有问题,然后我尝试使用{{1 (在运行时附加进程)并没有问题,但现在我尝试PTRACE_ATTACH,我有一些问题,以获得这些系统调用,我只是无法正确解析我的过程。
我知道PTRACE_SEIZEDPTRACE_ATTACH之间的区别在于,我需要停止自己的过程(我使用PTRACE_SEIZED)。 下面是我的代码:PTRACE_INTERRUPT for that之后的所有printf和if (i == 3) break;都是出于调试目的。所以我只是想通过将我的进程与while(1)请求(来自ptrace函数)相关联来解析我的程序并解压缩所有系统调用(orig_rax寄存器)(更具体地说是用我的{{{ 1}}函数,在我的PTRACE_SEIZED中调用/ bin / ls 当我运行我的代码时,所有ptrace_function返回0并且进程很好地接收到停止信号(execl),但是rip寄存器似乎没有改变(有时它会改变并且我得到一些正确的orig_rax值只有一次并且在我得到之后什么都没有总是一样的价值)
我还尝试使用main代替WIFSTOPPED(status) == true,并且在我的PTRACE_SINGLESTEP中只有一次使用,因为RIP始终是相同的值。
(我在google上做了一些研究,发现没有使用PTRACE_SEIZED进行进程解析的例子,我是ptrace,内核,信号的初学者,所以也许我的误解来自这里) 任何帮助,示例,有用的链接表示赞赏。我希望我足够清楚。感谢。

PTRACE_SYSCALL

1 个答案:

答案 0 :(得分:2)

来自ptrace手册页......

PTRACE_SEIZE的部分下,我们有:

  

与PTRACE_ATTACH不同,PTRACE_SEIZE会停止该过程。

PTRACE_TRACEME下,我们有:

  

对于PTRACE_ATTACH,PTRACE_SEIZE,PTRACE_INTERRUPT和PTRACE_KILL以外的请求,必须停止tracee。

因此,为了使跟踪器能够检查tracee的寄存器等,必须停止跟踪。但是,PTRACE_SEIZE [本身]并没有这样做。

因此,在尝试检查其寄存器或内存之前,您需要使用PTRACE_ATTACH或在PTRACE_SEIZE之外执行其他操作来停止该过程。

当您考虑它时,获取正在运行的流程的快照没有多大价值,因为您不会获得原子视图它。你是"赛车"反对它[就像两个线程在全球价值竞争]。也就是说,(例如)你抓住eax,然后抓住内存,但他们可能已经在ptrace次来电之间更改了值。

<强>更新

  

我知道我必须停止我的过程(追踪),这就是我使用的原因:pt_ret = ptrace(PTRACE_INTERRUPT, pid, NULL, NULL);

在循环中,执行PTRACE_INTERRUPT以停止该过程。然后,您获取数据,打印并循环。

但是,在你的循环中,你永远不会做任何事情来恢复tracee(例如PTRACE_CONT),所以一旦循环的第一次迭代完成,跟踪的进程仍然停止。只有在退出循环并执行PTRACE_DETACH

后,它才会恢复

更新#2:

是。 PTRACE_SYSCALL 恢复跟踪过程。但是,跟踪器的ptrace调用将立即返回 。然后,在循环顶部,您执行另一个PTRACE_INTERRUPT

这意味着跟踪的进程将被安排运行,但可能会在它有机会运行之前再次停止。 (即追踪者和追踪者是&#34;赛车&#34;)。这可能接近你所看到的。

另外,我增加了跟踪器中的迭代次数,因为3看起来有点小。

循环之前尝试执行PTRACE_INTERRUPT 。这使PTRACE_SEIZE后跟PTRACE_INTERRUPT道德等同于PTRACE_ATTACH

然后,循环:waitpid,print,PTRACE_SYSCALL应该可以在没有比赛的情况下工作。将PTRACE_INTERRUPT置于与PTRACE_SYSCALL [类型]相同的循环中会违背PTRACE_SYSCALL的目的。

使用PTRACE_INTERRUPT [在初始版本之后]仅在PTRACE_CONT执行时才有意义。

但是,在执行PTRACE_SYSCALL时,使用waitpid循环WNOHANG可能是有意义的。如果您未在合理的时间内停止,则表示目标不进行任何系统调用。此时,您可以发出PTRACE_INTERRUPT然后强制停止,以便您可以检查状态。

在循环上方PTRACE_INTERRUPT,尝试PTRACE_SINGLESTEP以减少粒度。

就单步执行而言,

ls有点不透明(例如,您可能必须安装debuginfo包才能获得符号表)。

尝试编写一个简单的目标/跟踪程序,您可以在其中精确控制行为。您可以生成完整的反汇编。然后,将地址与您从单步跟踪中获得的rip值进行匹配。