返回列表 发新帖

ptrace函数简介①

[复制链接]

39

主题

349

回帖

1676

积分

高中生

Rank: 4

金币
643
好评
11
信誉
125

考神MT论坛新人MT论坛最佳新人

发表于 2022-11-21 15:20:16 | 显示全部楼层 | 阅读模式  来自 江苏
本帖最后由 ggggmllll 于 2022-11-21 16:11 编辑

lz萌新一枚,本帖内容如有错误,欢迎指教。。。



本帖目录:
1,ptrace函数简介
2,PTRACE_ATTACH,PTRACE_CONT,PTRACE_DETACH使用介绍

1,ptrace函数简介:
以下是linux manpage中对ptrace函数的介绍:
The ptrace() system call provides a means by which one process
       (the "tracer") may observe and control the execution of another
       process (the "tracee"), and examine and change the tracee's
       memory and registers.  It is primarily used to implement
       breakpoint debugging and system call tracing.

       A tracee first needs to be attached to the tracer.  Attachment
       and subsequent commands are per thread: in a multithreaded
       process, every thread can be individually attached to a
       (potentially different) tracer, or left not attached and thus not
       debugged.  Therefore, "tracee" always means "(one) thread", never
       "a (possibly multithreaded) process".  Ptrace commands are always
       sent to a specific tracee using a call of the form

           ptrace(PTRACE_foo, pid, ...)

       where pid is the thread ID of the corresponding Linux thread.

       (Note that in this page, a "multithreaded process" means a thread
       group consisting of threads created using the clone(2)
       CLONE_THREAD flag.)

       A process can initiate a trace by calling fork(2) and having the
       resulting child do a PTRACE_TRACEME, followed (typically) by an
       execve(2).  Alternatively, one process may commence tracing
       another process using PTRACE_ATTACH or PTRACE_SEIZE.

       While being traced, the tracee will stop each time a signal is
       delivered, even if the signal is being ignored.  (An exception is
       SIGKILL, which has its usual effect.)  The tracer will be
       notified at its next call to waitpid(2) (or one of the related
       "wait" system calls); that call will return a status value
       containing information that indicates the cause of the stop in
       the tracee.  While the tracee is stopped, the tracer can use
       various ptrace requests to inspect and modify the tracee.  The
       tracer then causes the tracee to continue, optionally ignoring
       the delivered signal (or even delivering a different signal
       instead).

       If the PTRACE_O_TRACEEXEC option is not in effect, all successful
       calls to execve(2) by the traced process will cause it to be sent
       a SIGTRAP signal, giving the parent a chance to gain control
       before the new program begins execution.

       When the tracer is finished tracing, it can cause the tracee to
       continue executing in a normal, untraced mode via PTRACE_DETACH.

函数原型:
  1. long ptrace(enum __ptrace_request request, pid_t pid,void *addr, void *data);
  2. //request:一个枚举值,决定具体调用ptrace函数族的哪一个函数
  3. //pid:被调试进程的pid
  4. //addr,data:本篇教程暂不涉及
复制代码

ptrace 标准库函数实际上调用的是系统调用(syscall) __NR_ptrace ; 系统调用号 26 ;该函数是一个系统调用方法 , 可以监视进程执行 , 查看 / 更改 被监视进程的 内存 和 寄存器 情况 , 常用于断点调试 ;
注意,android在使用ptrace系统调用时,必须要有system或root权限


2,PTRACE_ATTACH,PTRACE_CONT,PTRACE_DETACH使用介绍:


PTRACE_ATTACH : 指明要附着的进程 ;
进程 A 要 调试进程 B , 在进程 A 中 先通过 ptrace 函数 附着进程 B , 传入 PTRACE_ATTACH 作为第一参数 ,调用 ptrace 函数时 , 会调用系统内核层 , 给进程 A 一个权限 , 将被调试进程 B 的控制权限交给 进程 A ;进程 A 调试 进程 B 时 , 进程 B 被挂起 , 进程 B 的 CPU 和 内存信息 , 都会被保存到内存中 , 进程 B 处于休眠状态 , CPU 不会运行 进程 B 的任何指令 ;


具体代码:
  1. pthread_mutex_t mutex;
  2. int ptrace_attach(pid_t pid)
  3. {
  4.         pthread_mutex_lock(&mutex);
  5.         if (ptrace(PTRACE_ATTACH, pid, NULL, 0) < 0)
  6.         {
  7.                 perror("failed on ptrace_attach()");
  8.                 return -1;
  9.         }
  10.         waitpid(pid, NULL, WUNTRACED);
  11.         pthread_mutex_unlock(&mutex);
  12.         return 0;
  13. }
复制代码

其中,非常重要的一点就是,在进行PTRACE_ATTACH操作之前,需要互斥操作(据说暂停进程也可以,但没试过),否则会出现ptrace attach busy的错误(lz就掉进过这个坑


PTRACE_CONT : ptrace attach进程完毕之后 , 退出调试 , 为了程序继续向后执行 , 使用 PTRACE_CONT 作为 ptrace 函数的 第一参数即可 ;
具体代码:
  1. int ptrace_cont(pid_t pid)
  2. {
  3.         if (ptrace(PTRACE_CONT, pid, NULL, 0) < 0)
  4.         {
  5.                 perror("failed on ptrace_cont");
  6.                 return -1;
  7.         }
  8.         puts("cont sucess");
  9.         return 0;
  10. }
复制代码

由于比较简单,故不叙述过多

PTRACE_DETACH要脱离的进程 ;

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

具体代码:

  1. int ptrace_detach(pid_t pid)
  2. {
  3.         if (ptrace(PTRACE_DETACH, pid, NULL, 0) < 0)
  4.         {
  5.                 perror("failed on ptrace_detach");
  6.                 return -1;
  7.         }
  8.         return 0;
  9. }
复制代码

虽然也比较简单,但lz本人从来本人从来没成功过

码字不易,喜欢的话可以点个赞支持一下



回复

使用道具 举报

48

主题

3111

回帖

7523

积分

硕士生

Rank: 6Rank: 6

金币
1622
好评
3
信誉
102

MT论坛最佳新人MT论坛新人

发表于 2022-11-21 15:23:40 来自手机  | 显示全部楼层  来自 广西
感谢分享
回复

使用道具 举报

24

主题

6184

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
2658
好评
12
信誉
384

考神

发表于 2022-11-21 15:39:33 | 显示全部楼层  来自 美国
好家伙,函数介绍直接是英语的,看太懂
回复

使用道具 举报

39

主题

349

回帖

1676

积分

高中生

Rank: 4

金币
643
好评
11
信誉
125

考神MT论坛新人MT论坛最佳新人

发表于 2022-11-21 15:48:03 | 显示全部楼层  来自 江苏
Yang丶 发表于 2022-11-21 15:39
好家伙,函数介绍直接是英语的,看太懂

你的ip属地不是美国吗
回复

使用道具 举报

39

主题

349

回帖

1676

积分

高中生

Rank: 4

金币
643
好评
11
信誉
125

考神MT论坛新人MT论坛最佳新人

发表于 2022-11-21 15:48:54 | 显示全部楼层  来自 江苏
Yang丶 发表于 2022-11-21 15:39
好家伙,函数介绍直接是英语的,看太懂

那个介绍其实也不是很重要
回复

使用道具 举报

0

主题

7448

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
2835
好评
0
信誉
98

MT论坛新人考神MT论坛帅哥MT论坛最佳新人

发表于 2022-11-21 16:09:15 来自手机  | 显示全部楼层  来自 广西
感谢分享
回复

使用道具 举报

2

主题

5826

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
3569
好评
1
信誉
96
发表于 2022-11-21 17:10:59 | 显示全部楼层  来自 湖北
感谢分享啊。
回复

使用道具 举报

95

主题

8175

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
291
好评
28
信誉
108

考神MT论坛新人MT论坛帅哥MT论坛最佳新人MT论坛活跃会员

发表于 2022-11-21 17:29:00 来自手机  | 显示全部楼层  来自 湖北
支持一下
回复

使用道具 举报

48

主题

3111

回帖

7523

积分

硕士生

Rank: 6Rank: 6

金币
1622
好评
3
信誉
102

MT论坛最佳新人MT论坛新人

发表于 2022-11-29 12:47:57 来自手机  | 显示全部楼层  来自 广西
感谢分享
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表