驱动开发:内核枚举驱动内线程(答疑篇)

简介: 这篇文章比较特殊,是一篇穿插答疑文章,由于刚好在前一篇教程`《驱动开发:内核枚举PspCidTable句柄表》`整理了枚举句柄表的知识点,正好这个知识点能解决一个问题,事情是这样的有一个粉丝求助了一个问题,想要枚举出驱动中活动的线程信息,此功能我并没有尝试过当时也只是说了一个大致思路,今天想具体聊一聊这个话题,也想聊一聊自己对粉丝们的想法。

这篇文章比较特殊,是一篇穿插答疑文章,由于刚好在前一篇教程《驱动开发:内核枚举PspCidTable句柄表》整理了枚举句柄表的知识点,正好这个知识点能解决一个问题,事情是这样的有一个粉丝求助了一个问题,想要枚举出驱动中活动的线程信息,此功能我并没有尝试过当时也只是说了一个大致思路,今天想具体聊一聊这个话题,也想聊一聊自己对粉丝们的想法。

image.png

首先因为我的人生经历比较特殊,我经历过无法求知的困境,深知一个人在没有任何人指点的情况下去研究技术是多么的折磨人,所以在某些情况下只要你关注了我,我也会尽自己最大可能去帮助大家,即便是当时没有解决这个问题我也会记下来,只要能被解决我一定会第一时间告诉粉丝,但也希望大家不要遇到困难关注我,解决困难取消关注,这样我觉得很不地道。

好了步入正题,这个枚举驱动内的线程我们无法用传统的API去枚举,原因很简单你拿不到进程的EPROCESS结构,或者说他这个驱动程序本身就是系统的一部分根本就没有进程ID的概念,由于我一直没有尝试这个需求,所以当时对粉丝说的是通过PEB来拿到,但这个方法其实关键就在于,以我目前的知识储备无法拿到驱动的EPROCESS结构。

image.png

然后干脆就直接枚举出整个系统所有的进程与线程信息,例如上一篇文章中提到的枚举句柄表,打开ARK工具找到所需查询的线程,会发现他有一个ETHREAD结构。

image.png

我们直接在枚举列表中查询以下看看,你会发现所有句柄表线程中是存在这个ETHREAD结构。

image.png

但是这个是全局的,无法得到它属于哪个驱动模块,这就很尴尬了。

你或许灵机一动,我直接得到ETHREAD信息,从里面找EPROCESS,再从里面找进程名,但跟到最后你会发现它显示的是SYSTEM进程,如果继续往下就是内核了,小丑竟是你自己。

这里只能用笨办法,首先线程ETHREAD地址是0xFFFF9C02B2DCC540抹掉最后三位0xFFFF9C02B2DCC000

image.png

然后看看驱动列表中的0xFFFF9C02B2DCC060同样抹掉最后三位是0xFFFF9C02B2DCC000,这两个地址相差不大甚至说就是一摸一样。

image.png

我不知道别人的ARK工具是怎么实现的,但是我目前能想到的办法只能是这一种笨办法,两者作比较相差在一个误差以内就说明是进程内的子线程。

这样我们首先枚举的是驱动完整信息,然后在和线程作比较,从而判断或者说归档,将某一些子线程归类到某个驱动程序上面,代码我就不写了,再写也是重复的东西,前面的文章中都有代码,自己拼凑一下就可以实现的功能。

新增一个方法,通过IoThreadToProcess将线程句柄转换为进程EPROCES,并附加后提取出所属驱动。

if (PsLookupThreadByThreadId(i_id, &p_ethread) == STATUS_SUCCESS)
{
    //DbgPrint("线程TID: %d | ID: %d | 内存地址: %p | 对象: %p \n", i_id, i, BaseAddr + i * 0x10, ul_decode);

    // 通过线程THread得到进程PID
    NTKERNELAPI PEPROCESS IoThreadToProcess(PETHREAD Thread);
    NTKERNELAPI char* PsGetProcessImageFileName(PEPROCESS Process);

    PEPROCESS ep;
    PETHREAD et;
    HANDLE pid;

    ep = IoThreadToProcess(p_ethread);
    pid = PsGetProcessId(ep);

    DbgPrint("%d \n", pid);
}
目录
相关文章
|
5月前
|
安全 Java 编译器
深入理解PHP 8.0新特性及其对开发的影响Java中的多线程编程:从理论到实践
【5月更文挑战第27天】在这篇文章中,我们将详细探讨PHP 8.0的新特性以及它们如何影响开发者的工作流程。我们将深入研究这些新特性,包括JIT编译器,联合类型,命名参数,以及更多的错误处理机制。我们还将讨论这些新特性如何提高代码的可读性和性能,以及它们如何改变我们编写和维护PHP应用程序的方式。 【5月更文挑战第27天】在现代计算机科学中,多线程编程是一个重要的概念,它允许多个线程在同一时间内运行,从而提高了程序的效率和性能。本文将深入探讨Java中的多线程编程,包括其理论基础,实现方法,以及一些常见的问题和解决方案。我们将通过实例来理解如何创建和管理线程,以及如何使用Java的并发工具来
|
21天前
|
API Android开发 iOS开发
安卓与iOS开发中的线程管理对比
【9月更文挑战第12天】在移动应用的世界中,安卓和iOS平台各自拥有庞大的用户群体。开发者们在这两个平台上构建应用时,线程管理是他们必须面对的关键挑战之一。本文将深入探讨两大平台在线程管理方面的异同,通过直观的代码示例,揭示它们各自的设计理念和实现方式,帮助读者更好地理解如何在安卓与iOS开发中高效地处理多线程任务。
|
2月前
|
安全 测试技术 调度
iOS开发-多线程编程
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),保持对象不被释放;`weak`(弱引用),不保持对象,有助于避免循环引用;`assign`(赋值),适用于基本数据类型及非指针对象类型;`copy`(复制),复制对象而非引用,确保不变性。内存管理基于引用计数,利用自动引用计数(ARC)自动管理对象生命周期。此外,需注意避免循环引用,特别是在block中。最佳实践包括理解各策略、避免不必要的强引用、及时释放不再使用的对象、注意block中的内存管理,并使用工具进行内存分析。正确管理内存能显著提升应用质量。
|
2月前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享安卓与iOS开发中的线程管理比较
【8月更文挑战第30天】本文将探讨网络安全与信息安全的重要性,并分享关于网络安全漏洞、加密技术和安全意识的知识。我们将了解常见的网络攻击类型和防御策略,以及如何通过加密技术和提高安全意识来保护个人和组织的信息安全。
|
3月前
|
缓存 编译器 Go
开发与运维线程问题之Go语言的goroutine基于线程模型实现如何解决
开发与运维线程问题之Go语言的goroutine基于线程模型实现如何解决
51 3
|
3月前
|
算法 编译器 C++
开发与运维线程问题之在C++的原子操作中memory_order如何解决
开发与运维线程问题之在C++的原子操作中memory_order如何解决
35 2
|
3月前
|
Java 运维
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
51 2
|
3月前
|
存储 安全 Java
Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
54 0
|
4月前
|
算法 Java 大数据
Java不同版本的多线程开发:进化之路
Java不同版本的多线程开发:进化之路
46 1
|
5月前
|
存储 缓存 调度
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
《FFmpeg开发实战》第10章示例playsync.c在处理音频流和视频流交错的文件时能实现同步播放,但对于分开存储的格式,会出现先播放全部声音再快速播放视频的问题。为解决此问题,需改造程序,增加音频处理线程和队列,以及相关锁,先将音视频帧读入缓存,再按时间戳播放。改造包括声明新变量、初始化线程和锁、修改数据包处理方式等。代码修改后在playsync2.c中,编译运行成功,控制台显示日志,SDL窗口播放视频并同步音频,证明改造有效。
83 0
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频