如何在 C 中检索传递给 linux 系统调用的参数?

How to retrieve arguments passed to linux system call in C?

我正在使用 ptrace 跟踪系统调用,例如读、写、打开等。如果存在打开系统调用,则可以从 user_regs_struct 检索传递给该系统调用的参数。第一个参数存储在 rdi 寄存器中。 rdi 的内容是一个 unsigned long long int。如何从中检索字符串文件名,例如。 foo.txt 哪个被传递给 open 系统调用?

传递给 open 的参数(以及系统调用接收字符串的任何其他情况)是指向字符串在内存中的位置的指针。

不幸的是,这些指针是针对调试器的地址space,不能直接从调试器的地址space引用。

ptrace 文档会让您重复调用 ptrace(PTRACE_PEEKDATA...) 来获取字符串,一次 4 个(或 8 个,取决于平台)字节。您可以在旧的 fakeroot-ng code 中看到如何执行此操作的示例。请注意,该代码受 GPL 保护,因此请勿逐字复制,除非您正在编写兼容许可证的代码。

幸运的是,有一种获取数据的方法既简单更快。它的可移植性较差,但如果您正在编写 ptrace 代码,您通常不会在意。

跟踪器线程可以打开文件/proc/pid/mem(其中pid当然是被调试者的数字pid)。请注意,只有 pid 的 ptracer 可以打开该文件。

打开该文件后,您可以pread(2) 从它在您想要的地址的偏移量处获取数据,并直接从调试对象的地址space 获取数据。由于 read 接口不限于四个字节,您可以猜测字符串的长度,读取那么多字节,然后找到终止 NULL 并知道精确的字符串。

由于调用的系统调用较少,因此此方法不仅更简单,而且速度更快。