版权声明:本文为博主原创文章,未经博主允许不得转载。个人博客:www.saoguang.top https://blog.csdn.net/u011580175/article/details/82822494
一、关于ptrace
ptrace是一种系统调用。p也就是process进程,trace追踪。也就是进程追踪。用于对进程的执行进行干涉以及寄存器状态(值)的读取以及设置,内存的写入与读取。比如,我们常用的Linux下的gdb调试。这个程序的主要功能实现就是通过ptrace系统调用。
#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid,
void *addr, void *data);
常用的ptrace参数,以及调用实例
- PTRACE_TRACEME:(跟踪我),这是对相对其父进程而言的。功能是指示其父进程,对其进行跟踪。使用此参数时,
pid
,addr
,data
参数都被忽略。
if (ptrace(PTRACE_TRACEME, i_pid, NULL, NULL) < 0) {
perror("PTRACE_TRACEME");
exit(-1);
}
- PTRACE_PEEKTEXT , PTRACE_PEEKDATA:从
addr
参数指示的地址开始,读取一个WORD
的长度的数据,通过,返回值传递回来。使用此参数时,data
参数被忽略。
data = ptrace(PTRACE_PEEKTEXT, i_pid, addr, NULL);
if (errno != 0) {
perror("PTRACE_PEEKTEXT");
exit(-1);
}
- PTRACE_POKETEXT , PTRACE_POKEDATA:从
addr
参数指示的地址,开始写入一个WORD
长度的数据。这两个请求是等效的。
if (ptrace(PTRACE_POKETEXT, i_pid, addr, data) < 0) {
perror("PTRACE_POKETEXT");
exit(-1);
}
- PTRACE_GETREGS:从被跟踪的进程中,读取用户寄存器的值。到一个
struct user_regs_struct
结构体中。这个结构体的定义在<sys/user.h>
头文件中。忽略addr
和data
参数。
// Read the user_reg
if (ptrace(PTRACE_GETREGS, i_pid, NULL, &h.pt_reg) < 0) {
perror("PTRACE_GETREGS");
exit(-1);
}
- PTRACE_SETREGS:将一个
struct user_regs_struct
类型的结构体变量的值,设置到被跟踪进程的用户寄存器中。这个请求与它对应的PTRACE_GETREGS请求是对应的。都忽略addr
和data
参数。
// Save the reg change
if (ptrace(PTRACE_SETREGS, i_pid, NULL, &h.pt_reg) < 0) {
perror("PTRACE_SETREGS");
exit(-1);
}
- PTRACE_ATTACH:将尝试附加到
pid
指定的进程上。附加成功后,目标进程将处于挂起状态。被跟踪进程,将会发送SIGSTOP
信号,给跟踪者。跟踪着需要调用waitpid(2)以接收,被跟踪进程,传来的SIGSTOP
信号。
// Attch to specify process
if (ptrace(PTRACE_ATTACH, i_pid, NULL, NULL) < 0) {
perror("PTRACE_ATTACH");
exit(-1);
}
- PTRACE_CONT:恢复
pid
指定的进程执行。当data
参数不为零时,data
将会被解释为一个signal
(信号),传递给被跟踪进程。(addr
参数被忽略)
if (ptrace(PTRACE_CONT, i_pid, NULL, NULL) < 0) {
perror("PTRACE_CONT");
exit(-1);
}
- PTRACE_KILL:将会把
SIGKILL
信号发送给被跟踪进程,以终止其执行。data
,addr
参数被忽略。
if (ptrace(PTRACE_KILL, i_pid, NULL, NULL) < 0) {
perror("PTRACE_KILL");
exit(-1);
}
三、更多详细内容
查看官方文档:http://man7.org/linux/man-pages/man2/ptrace.2.html