Linux内核ptrace机制原理

本文深入探讨Linux内核的ptrace机制,从基本原理、系统调用入手,详细解析了不同架构如arm64和x86的arch_ptrace实现。主要内容包括ptrace请求类型、内存访问、task状态改变以及架构特定的处理方式。
摘要由CSDN通过智能技术生成

1. 基本原理

ptrace用于实现跟踪task相关的功能,主要包括以下几种
PTRACE_TRACEME:用于trace当前task;
PTRACE_PEEKTEXT/PTRACE_PEEKDATA:用于读取指定tracee内存地址所在位置的代码段/数据段的一个WORD,Linux没有独立的代码段和数据段空间,因此,这两种请求是等价的,具体参考官方说明或者ptrace的man page;
PTRACE_PEEKUSR:用于读取tracee USER区域地址偏移处的一个WORD,这里的用户区域保存了进程的寄存器等信息,详细信息参考sys/user.h,这里的偏移必须是按WORD对齐,但是为了维护内核的完整性,对于USER区域的修改是不允许的;
PTRACE_POKETEXT/PTRACE_POKEDATA:复制WORD数据到指定tracee内存地址处,目前这两种请求也是等价的;
PTRACE_POKEUSER:分别复制通用或者浮点寄存器数据到tracer的地址空间,这里的数据格式参考sys/user.h,SPARC系统(针对ASIC架构)的data与addr(ptrace系统调用的两个参数)已经反转,即该系统下,寄存器数据只copy到地址所指的空间。
PTRACE_ATTACH/PTRACE_DETACH:用于附着或者去附着进程,一般在操作task私有空间之前,都需要先执行ATTACH请求,在完成对应操作之后,需要DETACH,如果不DETACH,则会task的私有空间可能会被一直占用,导致无法估量的危险。

其余请求说明参考ptrace理解
官方说明:https://man7.org/linux/man-pages/man2/ptrace.2.html

2.系统调用

(注意:以下源码是基于Linux 5.12.1分析的)

(1)内核系统函数入口

函数定义位置:kernel/ptrace.h
SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
unsigned long, data);
参数说明:request:表示的请求类型,详细参考第一节;
pid:表示的是被trace的进程ID;
addr:表示的是被trace的内存地址,这个地址可由readelf/objdump命令获取并计算,如果想执行函数替换,则需要通过这两个命令获取到函数入栈(push)的地址,然后在此地址基础上计算偏移,用于替换对象函数,如果是PTRACE_ATTACH请求,该值可为NULL;
data:用于保存被trace的内存内容,可以是从内存地址读取到的,也可以是给内存地址写入的内容,具体需要看request的值。

(2)过程分析

1)判断是否是trace当前task,如果是,则调用ptrace_traceme,该函数主要是调用security_ptrace_traceme,通过当前task的父进程trace,通过当前进程的用户命名空间

static int ptrace_traceme(void)
{
   
	int ret = -EPERM;

	write_lock_irq(&tasklist_lock);
	/* Are we already being traced? */
	if (!current->ptrace) {
   
		ret = security_ptrace_traceme(current->parent);//该函数调用了security钩子函数cap_trace_traceme
		/*
		 * Check PF_EXITING to ensure ->real_parent has not passed
		 * exit_ptrace(). Otherwise we don't report the error but
		 * pretend ->real_parent untraces us right after return.
		 */
		if (!ret && !(current->real_parent->flags & PF_EXITING)) {
   
			current->ptrace = PT_PTRACED;
			ptrace_link(current, current->real_parent);
		}
	}
	write_unlock_irq(&tasklist_lock);

	return ret;
}
int cap_ptrace_traceme(struct task_struct *parent
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值