zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 )

2023-06-13 09:17:59 时间

文章目录

一、ptrace 函数族


ptrace 函数原型 : ptrace 函数实际上是由一系列的函数组成 , 具体调用哪个函数 , 要根据第一个参数确定 ;

       #include <sys/ptrace.h>

       long ptrace(enum __ptrace_request request, pid_t pid,
                   void *addr, void *data);

ptrace 函数参考文档 : https://man7.org/linux/man-pages/man2/ptrace.2.html

下面是 enum __ptrace_request request 参数的可能的取值 : 在上述文档中有详细的说明 ;

1、进程附着

PTRACE_ATTACH : 指明要附着的进程 ;

进程 A 要 调试进程 B , 在进程 A 中 先通过 ptrace 函数 附着进程 B , 传入 PTRACE_ATTACH 作为第一参数 ; ( 注意 : 进程 A 必须有 root 权限 )

调用 ptrace 函数时 , 会调用系统内核层 , 给进程 A 一个权限 , 将被调试进程 B 的控制权限交给 进程 A ;

进程 A 调试 进程 B 时 , 进程 B 被挂起 , 进程 B 的 CPU 和 内存信息 , 都会被保存到内存中 , 进程 B 处于休眠状态 , CPU 不会运行 进程 B 的任何指令 ;

2、进程脱离

PTRACE_DETACH : 要脱离的进程 ;

进程 A 如果调用 ptrace 函数 , 传入 PTRACE_DETACH , 就会释放权限 , 发出信号 , 进程 B 恢复运行 ;

3、进程数据读写权限

读取进程数据权限 : PTRACE_PEEKTEXT、PTRACE_PEEKDATA、PTRACE_PEEKUSER

写入进程数据权限 : PTRACE_POKETEXT、PTRACE_POKEDATA、PTRACE_POKEUSER

注意 : 读写内存时 , 尽量在进程挂起后读写 , 否则内存数据不可靠 ;

4、进程对应的主线程寄存器读写

读取寄存器 : PTRACE_GETREGS

写出寄存器 : PTRACE_SETREGS

同一个进程 , 可能有多个线程 , 不同线程可能会被分配到不同的 CPU , 进程读写的寄存器可能有多套 ;

上面的 PTRACE_GETREGS , PTRACE_SETREGS , 读写的寄存器 是 执行 主线程 的 CPU 的 寄存器 ;

5、单步调试

PTRACE_SYSCALL : 每当发生系统调用时, 被调试进程暂停 , 将控制权交还给调试进程 ;

PTRACE_SINGLESTEP : 每当执行一条指令时 , 被调试进程暂停 , 将控制权交还给调试进程 ; 单步调试 ;

6、继续向后执行

PTRACE_CONT : ptrace 调试进程 , 完毕之后 , 退出调试 , 程序继续向后执行 , 使用该 PTRACE_CONT 作为 ptrace 函数的 第一参数即可 ;

CONTINUE 继续执行 ;

二、ptrace 函数族状态转换


进程 A 调试 进程 B , 进程 A 先 调用 ptrace 函数 Attach 进程 B , 可以进行 数据读写 , 单步执行 , 等待系统调用 , 读写寄存器 等操作 , 执行完毕后 可以继续执行 ;

调试完毕后 , 进程 B 脱离 Detach 进程 A 的调试 ;