intentrace底层实现(上):ptrace是如何拦截Linux进程每一次系统调用的

发布时间:2026/11/2 2:52:03
intentrace底层实现(上):ptrace是如何拦截Linux进程每一次系统调用的 intentrace底层实现上ptrace是如何拦截Linux进程每一次系统调用的【免费下载链接】intentraceintentrace is strace with intent, it goes all the way for you instead of half the way. intentrace is currently in beta项目地址: https://gitcode.com/gh_mirrors/in/intentraceintentrace 是一个带意图的 strace 替代工具它基于 Linux 的 ptrace 机制拦截并记录进程中每一次系统调用再通过推理启发式告诉你每次调用到底想干什么。本文带你深入 intentrace 的底层实现上篇搞懂 ptrace 是如何拦截 Linux 进程的系统调用的。运行效果一眼看懂系统调用追踪 ️先看看它追踪google-chrome启动过程时的输出——每一行都是一次被 ptrace 拦截的系统调用右侧之后是 intentrace 对结果的意图化解读传统 strace 只会打印read(3, 0x7ffd..., 4096) 832这样的原始信息你还需要自己查手册理解每个参数的含义。而 intentrace 会直接解释为从文件描述符 3 读取 832 字节、映射内存失败权限被修改等自然语言结论。双进程架构fork PTRACE_TRACEME 埋下伏笔intentrace 追踪一个新程序时并没有直接运行它而是在 main.rs 中采用经典的fork 双进程结构参考parent()与child_trace_me()函数父进程调用fork()创建子进程自己进入主循环负责拦截子进程先调用ptrace::traceme()即PTRACE_TRACEME声明我被追踪然后exec目标程序。PTRACE_TRACEME的作用是让子进程此后每次进入/退出系统调用时都会自动停下来并把控制权交还父进程。这是 ptrace 拦截体系的第一块基石。 如果目标是已经在运行的进程intentrace 则用-p pid配合ptrace::attach动态附加原理完全相同。ptrace 的核心机制一次系统调用 两次停顿 父进程的主循环src/main.rs中parent()函数围绕一个简单动作展开反复执行ptrace::syscall(pid) → 等待子进程停下来 → 读取寄存器 → 放行PTRACE_SYSCALL让被追踪进程在每次系统调用入口和出口各停顿一次于是父进程拿到两帧快照停顿时机关键寄存器拿到什么入口enteringorig_rax系统调用号如openat、mmap入口rdi rsi rdx r10 r8 r9最多 6 个调用参数出口exitingrax返回值或错误码为什么必须读orig_rax而不是rax因为系统调用返回时rax会被返回值覆盖而orig_rax是内核原样保留的原始调用号是区分进入还是返回的唯一可靠依据。代码中用一个syscall_entering布尔量在两次停顿之间切换状态入口时构造SyscallObject并解析参数出口时读取rax判定成败再PTRACE_SYSCALL放行进程直到进程退出ESRCH结束整个循环。偷看别人内存peek poke 阶段 光有寄存器里的参数还不够——比如openat的参数只是一个指向路径字符串的指针。要解读出真实路径必须读取被追踪进程的内存。intentrace 把这一步封装在 peeker_poker.rs名字致敬 ptrace 文档里读写被追踪进程内存的术语 peek/poke核心是process_vm_readv系统调用read_bytes按定长读取远程内存read_bytes_variable_length读取变长数据如 C 字符串并小心处理跨 4KiB 页边界的半读问题read_bytes_as_struct把读到的字节块直接转成内存结构体。这样像截图中readlink /usr/bin/google-chrome /etc/alternatives/google-chrome这类解析出符号链接真实目标的能力就是靠远程读内存实现的。从原始参数到意图SyscallObject 与骨架映射 ⚙️拦截到一次调用后intentrace 还需要回答两个问题参数是什么类型返回值该怎么解读骨架映射syscall_skeleton_map.rs为每个系统调用登记一份形状描述例如read的返回是字节数或Errnommap的返回是地址或MAP_FAILED。目前覆盖了 380 个 Linux 系统调用中最常用的约 166 个遵循少数调用覆盖绝大多数软件的策略类似 UniKraft 内核的思路调用对象syscall_object.rsSyscallObject把调用号、被追踪 PID、进入/退出状态和结果聚合在一起fill_buffer()负责渲染成终端上那行带颜色的人话输出返回值解析src/return_resolvers.rs、src/utilities.rs把rax解释为成功 N 字节或失败 errno 含义比如EPERM会被翻译成具体的权限说明。这就是 intentrace 与 strace 的本质区别拦截靠 ptrace理解靠推理——它不止展示发生了什么还解释这意味着什么。快速上手构建并运行 intentrace git clone https://gitcode.com/gh_mirrors/in/intentrace cd intentrace cargo build --release几个常用命令intentrace -q ls # -q 屏蔽被追踪程序自身的输出 intentrace -f docker run alpine # -f 追踪 fork 出的子进程 intentrace -Z ls # -Z 只看失败的系统调用 intentrace -C ls # -C 额外打印统计汇总表注意当前 beta 版本仅支持 x86-64 架构多线程程序支持仍在完善中。小结intentrace 的拦截链路可以浓缩为一句话子进程PTRACE_TRACEME自曝 → 父进程PTRACE_SYSCALL双停顿 →getregs读orig_rax和参数寄存器 →process_vm_readv偷读内存还原指针内容 → 骨架映射 返回值解析输出意图。下一篇我们将深入参数解析与意图推理的启发式细节。【免费下载链接】intentraceintentrace is strace with intent, it goes all the way for you instead of half the way. intentrace is currently in beta项目地址: https://gitcode.com/gh_mirrors/in/intentrace创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询