实战Linux内核模块:终止ptrace跟踪程序与被跟踪进程
在Linux系统中ptrace进程跟踪是调试、分析程序的核心能力——比如我们常用的GDB调试器就是靠ptrace系统调用来实现断点调试、查看进程内存、单步执行等功能。但凡事有两面性恶意程序也可能通过ptrace跟踪系统中的关键进程窃取数据或篡改执行逻辑。今天我们就通过一个极简的Linux内核模块聊聊如何从内核层面识别并终止所有存在ptrace跟踪关系的进程对跟踪者与被跟踪者同时拆解背后的内核编程思路和核心知识点。一、先搞懂ptrace跟踪关系的内核本质要写终止ptrace跟踪的模块首先得知道内核里怎么记录“谁在跟踪谁”。Linux内核中每个进程都对应一个叫task_struct的结构体可以理解成进程的“身份证”里面藏着所有和进程相关的信息。其中有个关键的链表字段ptraced——只要进程A是跟踪者tracer那么所有被A跟踪的进程tracee都会被挂到A的ptraced链表上。简单说想找谁是跟踪者只要看它的ptraced链表有没有内容就行想找被跟踪的进程直接遍历这个链表就能全部揪出来。这也是我们这个模块的核心判断依据。二、模块核心功能简单直接的“终止逻辑”这个内核模块的目标没有花里胡哨的设计核心就四件事模块加载后周期性扫描系统中所有进程逐个检查进程的ptraced链表识别出“跟踪者”进程先给所有被跟踪进程发送无法拦截的SIGKILL信号必杀信号终止被跟踪者再终止跟踪者进程模块卸载时安全停止扫描并清理占用的内核资源。整个逻辑“简单粗暴”但胜在高效——毕竟内核层操作不需要经过用户态的权限校验能直接对进程下“终止指令”。三、代码拆解我们把核心代码拆成几个关键部分用普通人能懂的话解释不堆砌专业术语1. 基础准备宏定义与头文件#definepr_fmt(fmt)KBUILD_MODNAME: fmt#includelinux/list.h#includelinux/module.h#includelinux/sched.h#includelinux/sched/signal.h#includelinux/workqueue.hpr_fmt宏让内核打印日志时自动带上模块名比如日志会显示模块名: Loaded!方便我们定位日志来源头文件list.h用来操作内核链表比如ptraced链表sched.h用来访问进程的task_struct结构体workqueue.h用来实现“周期性扫描”的功能。2. 核心工具函数杀进程判断跟踪者1kill_task给进程发“致命信号”staticvoidkill_task(structtask_struct*task){send_sig(SIGKILL,task,1);}send_sig是内核里发送信号的函数这里发的是SIGKILL信号9——这是Linux里最“狠”的信号进程无法忽略、无法捕获收到就只能终止。参数里的1表示“向整个进程组发送”确保彻底杀死进程不留残留。2is_tracer判断是不是“跟踪者”staticboolis_tracer(structlist_head*children){structlist_head*list;list_for_each(list,children){structtask_struct*tasklist_entry(list,structtask_struct,ptrace_entry);if(task)returntrue;}returnfalse;}这个函数接收一个链表也就是进程的ptraced链表用list_for_each遍历链表如果链表里有元素说明有被跟踪的进程就返回“是跟踪者”true否则返回false。这里的list_entry是内核链表的核心宏——简单说就是“从链表节点找到对应的进程信息task_struct”是内核链表操作的必学知识点。3kill_tracee杀死所有被跟踪者staticvoidkill_tracee(structlist_head*children){structlist_head*list;list_for_each(list,children){structtask_struct*task_ptracedlist_entry(list,structtask_struct,ptrace_entry);pr_info(ptracee - comm: %s, pid: %d, gid: %d, ptrace: %d\n,task_ptraced-comm,task_ptraced-pid,task_ptraced-tgid,task_ptraced-ptrace);kill_task(task_ptraced);}}遍历跟踪者的ptraced链表逐个取出被跟踪进程先打印进程名、PID等信息方便排查再调用kill_task发SIGKILL终止它。3. 核心扫描逻辑check函数staticvoidcheck(void){structtask_struct*task;for_each_process(task){if(!is_tracer(task-ptraced))continue;kill_tracee(task-ptraced);kill_task(task);/* Kill the tracer once all tracees are killed */}}for_each_process是内核提供的宏能遍历系统中所有进程。对每个进程先用is_tracer判断是不是跟踪者如果是先杀所有被它跟踪的进程kill_tracee最后再杀这个跟踪者本身。4. 周期性扫描工作队列的妙用模块需要“一直扫描”但内核里不能用死循环会占满CPU所以用了“延迟工作队列”实现周期性执行staticvoidperiodic_routine(structwork_struct*ws){if(likely(loaded))check();queue_delayed_work(wq,dont_trace_task,JIFFIES_DELAY);}periodic_routine是每次要执行的函数先看模块是否还加载loaded为true如果是就执行check扫描进程然后把自己重新加入工作队列延迟1个内核节拍JIFFIES_DELAY1约10ms后再次执行——这样就实现了“循环扫描”既不卡CPU又能实时监控。5. 模块的加载与卸载生命周期管理1加载函数dont_trace_initstaticint__initdont_trace_init(void){wqcreate_workqueue(...);queue_delayed_work(wq,dont_trace_task,JIFFIES_DELAY);loadedtrue;pr_info(Loaded!\n);return0;}模块加载时创建工作队列 → 把扫描任务加入队列1个节拍后首次执行 → 标记模块已加载。2卸载函数dont_trace_exitstaticvoid__exitdont_trace_exit(void){loadedfalse;cancel_delayed_work(dont_trace_task);flush_workqueue(wq);destroy_workqueue(wq);pr_info(Unloaded.\n);}模块卸载时先标记“不再扫描” → 取消还没执行的扫描任务 → 等正在执行的任务完成 → 销毁工作队列释放资源——这是内核模块的通用规范避免内存泄漏或任务残留。四、设计思路与执行流程我们用流程图把模块的核心逻辑梳理清楚一看就懂否是否是模块加载创建工作队列提交首次延迟扫描任务10ms后执行重新提交延迟任务等待下一次扫描模块是否已加载终止本次任务遍历系统所有进程进程的ptraced链表非空遍历ptraced链表杀死所有被跟踪进程杀死该跟踪者进程模块卸载标记模块未加载取消未执行的扫描任务等待正在执行的任务完成销毁工作队列释放资源模块卸载完成If you need the complete source code, please add the WeChat number (c17865354792)这个模块的设计思路其实是内核编程的通用思路找对数据结构依托task_struct的ptraced链表精准定位跟踪关系——内核编程的核心就是“找对数据结构问题就解决了一半”异步周期性执行用工作队列实现非阻塞的循环扫描既保证实时性又不占用过多CPU资源安全的资源管理加载时创建资源卸载时彻底清理遵循“谁创建谁销毁”的原则。五、核心知识点总结从这个模块学到什么这个小模块虽然代码量少但覆盖了Linux内核编程的三大核心领域是入门内核开发的绝佳案例1. 进程管理领域task_structLinux内核描述进程的“核心结构体”包含PID、进程名、链表、状态等所有进程信息for_each_process遍历系统所有进程的基础宏是进程监控、进程管理类模块的必备工具内核态信号发送send_sig比用户态的kill系统调用权限更高能直接对所有进程发送信号。2. 内核链表领域list_headLinux内核的“通用链表”几乎所有内核数据结构比如进程链表、文件链表都基于它实现list_for_each/list_entry遍历链表、转换链表节点的核心宏——掌握这两个就能操作内核中90%的链表结构。3. 工作队列领域工作队列是内核实现“异步任务”的核心机制适合处理需要延迟、周期性执行的任务模块卸载时必须用flush_workqueue等待任务完成这是避免内核资源泄漏的关键。六、模块测试运行完整步骤制造ptrace跟踪场景测试靶场先开两个终端手动用gdb做ptrace跟踪模拟调试/跟踪场景终端1启动一个常驻进程被跟踪者# 启动sleep进程休眠300秒sleep300记一下这个sleep的PID比如后续用ps查。终端2用gdb附加sleep进程跟踪者# 查sleep的PIDpsaux|grepsleep# gdb附加该PID替换为实际sleep的PIDgdb -p 你的sleep进程PIDgdb成功attach后就建立了ptrace跟踪关系gdb是跟踪者(tracer)sleep是被跟踪者(tracee)。加载模块验证查杀效果1. 加载内核模块回到第三个root终端加载模块insmod dont_trace.ko加载成功无报错查看内核日志确认加载dmesg-w日志会输出模块名: Loaded!2. 观察查杀结果加载后模块会立即周期性扫描瞬间发生两件事终端2的gdb进程直接被杀死退回命令行终端1的sleep进程也被杀死进程退出dmesg会打印被杀死的跟踪者/被跟踪者的进程名、PID等日志。3. 验证无残留# 查gdb和sleep是否还存在psaux|grep-Egdb|sleep正常情况两个进程都已消失说明模块生效。卸载模块测试完成必做测试结束后安全卸载模块避免持续查杀rmmod dont_trace查看dmesg日志会输出模块名: Unloaded.模块停止扫描、资源释放完成。七、最后说两句这个模块虽然功能简单但它是“从0到1”理解内核进程管理的好例子。你可以基于它扩展更多功能比如只终止特定PID的跟踪者、记录跟踪行为日志、或者把“SIGKILL”换成“SIGSTOP”暂停进程而非终止。内核编程的核心从来不是写复杂的代码而是“理解内核的设计逻辑和数据结构”——只要找对了task_struct里的关键字段再配合内核提供的通用工具链表、工作队列就能写出简洁又有效的内核模块。总结该模块的核心是利用task_struct的ptraced链表识别跟踪者通过send_sig发送SIGKILL终止跟踪者和被跟踪者采用工作队列实现周期性扫描遵循内核模块生命周期规范确保安全卸载模块覆盖了进程管理、内核链表、工作队列三大内核编程核心领域是入门内核开发的优质实战案例。Welcome to follow WeChat official account【程序猿编码】

相关新闻

大模型Agent工具调用原理:动态提示词组装技术详解(必收藏)

大模型Agent工具调用原理:动态提示词组装技术详解(必收藏)

现代AI Agent提示词已从静态文本发展为动态组装。文章揭示"三明治"架构:身份层定义角色,能力层动态注入Tools、Skills和MCP资源,上下文层包含实时对话信息。Agent通过运行时"编译"提示词,根据用户意图动态加载…

2026/7/4 17:42:06 阅读更多 →
大模型浮点类型全解析:一文掌握float32、float16、bfloat16选型与实战

大模型浮点类型全解析:一文掌握float32、float16、bfloat16选型与实战

文章详细介绍了大模型训练与推理中的三种主要浮点类型(float32、float16、bfloat16)的技术特点与对比分析。重点解析了bfloat16凭借其扩展的数值范围(8位指数位)成为大模型训练首选的原因,并通过PyTorch代码示例展示了不同浮点类型的设置与混合精度训练实现。最后提…

2026/7/3 14:27:44 阅读更多 →
HarmonyOS 网络请求与数据持久化

HarmonyOS 网络请求与数据持久化

网罗开发(小红书、快手、视频号同名)大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方…

2026/7/3 14:27:45 阅读更多 →

最新新闻

多智能体系统安全控制与责任分配技术解析

多智能体系统安全控制与责任分配技术解析

1. 多智能体系统安全责任分配的核心挑战 在机器人集群、无人机编队等典型多智能体系统中,安全责任分配面临三个维度的核心挑战: 1.1 安全性与自主性的矛盾 传统集中式控制虽然能保证全局安全,但要求所有智能体公开完整状态信息&#xff0c…

2026/7/4 17:41:06 阅读更多 →
深度解析开源抖音下载器:3大技术优势与实战部署指南

深度解析开源抖音下载器:3大技术优势与实战部署指南

深度解析开源抖音下载器:3大技术优势与实战部署指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…

2026/7/4 17:41:06 阅读更多 →
操作系统级缓存:超越Redis的系统性能优化底层原理与实践

操作系统级缓存:超越Redis的系统性能优化底层原理与实践

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 大家好,我是专注于技术实战分享的博主。在追求极致性能的路上,我们常常将目光投向 Redis 这类明星缓存中间件…

2026/7/4 17:39:05 阅读更多 →
揭秘evbunpack:高效破解Enigma Virtual Box打包文件的专业工具

揭秘evbunpack:高效破解Enigma Virtual Box打包文件的专业工具

揭秘evbunpack:高效破解Enigma Virtual Box打包文件的专业工具 【免费下载链接】evbunpack Enigma Virtual Box Unpacker / 解包、脱壳工具 项目地址: https://gitcode.com/gh_mirrors/ev/evbunpack 当你在逆向工程或软件分析工作中遇到Enigma Virtual Box打…

2026/7/4 17:37:04 阅读更多 →
跨平台开发实战:从操作系统差异看远程控制软件适配挑战

跨平台开发实战:从操作系统差异看远程控制软件适配挑战

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 你是不是也经常遇到这样的困惑:手头一台Windows笔记本办公,家里一台Mac Mini当服务器,还有一台L…

2026/7/4 17:35:03 阅读更多 →
基于YOLOv8的字符识别系统开发与实践

基于YOLOv8的字符识别系统开发与实践

1. 项目概述这个基于YOLOv8的字母数字识别检测系统是我最近完成的一个计算机视觉项目。它能够实时检测并识别图像和视频中的36类字符(数字0-9和字母A-Z),在复杂场景下表现出色。相比传统OCR技术,这个系统最大的优势在于能够处理任…

2026/7/4 17:33:03 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻