作为练习,我一直在尝试使用Rust的nix::sys::ptrace::ptrace
(与C的ptrace几乎相同)来通过读取RAX /的内容来仿真strace
的系统调用日志记录功能。每次系统调用时,RBX / RCX / RDX寄存器。我想要的输出将类似于以下内容:
Found syscall: 4
Arg1: 1
Arg2: Hello World!
从我在网上找到的示例来看,似乎PTRACE_PEEKUSER
和PTRACE_PEEKDATA
的组合最适合完成此操作(也许也是PTRACE_GETREGS
吗?),但是我很难理解如何满足我需要传递给这些函数的第三个参数,以使其起作用。
ptrace
的手册页列出了此示例,演示了正确的用法:
ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER, pid, addr, 0);
手册页只说:“在被追踪者的内存中的地址addr
上读一个单词。”但是addr
应该是什么?如何确定满足此参数的正确地址?
我在网上找到的示例都有类似的内容:
ptrace(PTRACE_PEEKUSER, pid, sizeof(long)*ORIG_EAX, 0);
或
ptrace(PTRACE_PEEKUSER, pid, somenumber*RAX, 0)
如何在运行时查找/计算这些寄存器的偏移量? (在Rust中!)
答案 0 :(得分:3)
自从我戳Linux内核(现在是Mac用户)以来已经有很长时间了。如果我没记错的话...
使用类似sudo apt-get install linux-headers-$(uname -r)
的名称安装内核头文件。假设您处于x86_64-linux-gnu
(根据您的rax
兴趣进行猜测)。
打开/usr/include/x86_64-linux-gnu/sys/reg.h
标头:
...
#ifdef __x86_64__
/* Index into an array of 8 byte longs returned from ptrace for
location of the users' stored general purpose registers. */
# define R15 0
# define R14 1
# define R13 2
# define R12 3
# define RBP 4
# define RBX 5
# define R11 6
# define R10 7
# define R9 8
# define R8 9
# define RAX 10
...
评论说:
从ptrace返回的8个字节长的数组的索引,用于定位用户存储的通用寄存器。
所有这些宏(RAX
,RCX
,...)为特定寄存器定义索引。并且由于每个字节均为8字节长(仅x86_64
),因此偏移量为8 * $index
。如果使用rax
寄存器,则将偏移量计算为8 * RAX = 8 * 10 = 80
。 80
是在addr
函数调用中用于ptrace
自变量的内容。这就是它的工作方式。请注意,它与其他架构等不同。
PTRACE_PEEKUSER
-用于寄存器和其他调试信息。
PTRACE_PEEKDATA
-用于程序数据和代码。
PTRACE_PEEKTEXT
-man ptrace
(Linux)说-将字数据复制到示踪内存中的地址addr。对于PTRACE_PEEKTEXT
和PTRACE_PEEKDATA
,这两个请求当前是等效的。这是因为Linux没有用于文本和数据的单独地址空间。
nix
板条箱提供了getregs函数来读取所有这些文件。它返回libc
user_regs_struct。仅Linux支持:
libc
的板条箱也包含这些索引:
如果仅对一个寄存器感兴趣,则可以使用此索引来计算ptrace函数的偏移量/ addr。将其与8
(#[cfg(target_arch = "x86_64")]
)/ 4
(#[cfg(target_arch = "x86")]
)乘以PTRACE_PEEKUSER
来读取(请参见Request)。
阅读What are the calling conventions for UNIX & Linux system calls on i386 and x86-64。换句话说,您对rdi
,rsi
,rdx
,...寄存器感兴趣。 nix
条板箱提供了专门的read函数,其中internally calls ptrace
函数与PTRACE_PEEKDATA
一起使用。
ptrace
函数已被弃用。文档说明:
从0.10.0开始不推荐使用:ptrace()的使用应改为专用的帮助器功能
您应使用getregs
和read
之类的专用功能。您可以找到其中的列表in the documentation。