方法是基于PsLoadModuleList方式

驱动中遍历模块

一丶简介

简介:

进入内核了.遍历内核中使用的模块该怎么办. 其实在驱动中.我们的DriverEntry入口位置.

提供了两个参数. 一个是DrIverObject另一个则是注册表路径.

其实遍历模块的技巧就在这个DriverObject中.

众所周知在Ring3下遍历模块可以通过TEB PEB遍历. 我们会接触一个结构体叫做LDR_DATA_TABLE_ENTRY的结构体.

内核中也会使用这个结构体. 看下DriverObject对象所代表的含义.


typedef struct _DRIVER_OBJECT {
CSHORT Type;
CSHORT Size; PDEVICE_OBJECT DeviceObject; //驱动对象
ULONG Flags; //驱动的标志 PVOID DriverStart; //驱动的起始位置
ULONG DriverSize; //驱动的大小
PVOID DriverSection; //指向驱动程序映像的内存区对象
PDRIVER_EXTENSION DriverExtension; //驱动的扩展空间 UNICODE_STRING DriverName; //驱动名字 PUNICODE_STRING HardwareDatabase; PFAST_IO_DISPATCH FastIoDispatch; PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; } DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;

在这里主要使用 DriverSection这个成员 这个成员则可以解释为LDR_DATA_TABLE_ENTRY结构体.

里面存放着我们的所有模块.


typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks; //链表存储,指向下一个LDR_DATA_TABLE_ENTRY结构
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase; //基址
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName; //存放着驱动模块名
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
struct {
ULONG TimeDateStamp;
};
struct {
PVOID LoadedImports;
};
};
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

所以代码就很简单了.直接遍历自身结构体的 DriverSection成员即可.解释为(LDR_DATA_TABLE_ENTRY)结构.

二丶代码以及演示.

#include "Driver.h" //这个替换为自己的. 包含Ntddk.h即可.
#include <wdm.h> //KLDR_DATA_TABLE_ENTRY typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
struct {
ULONG TimeDateStamp;
};
struct {
PVOID LoadedImports;
};
};
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
ULONG iCount = 0;
NTSTATUS ntStatus;
pDriverObj->DriverUnload = DriverUnLoad; KdBreakPoint(); /*
主要是遍历DriverObject中的 DriverSection 它可以解释为LDR_DATA_TABLE_ENTRY结构体
*/ PLDR_DATA_TABLE_ENTRY pLdr = NULL;
PLIST_ENTRY pListEntry = NULL;
PLIST_ENTRY pCurrentListEntry = NULL; PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
pListEntry = pLdr->InLoadOrderLinks.Flink;
pCurrentListEntry = pListEntry->Flink; while (pCurrentListEntry != pListEntry) //前后不相等
{
//获取LDR_DATA_TABLE_ENTRY结构
pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (pCurrentModule->BaseDllName.Buffer != 0)
{
DbgPrint("ModuleName = %wZ ModuleBase = %p \r\n",
pCurrentModule->BaseDllName,
pCurrentModule->DllBase);
}
pCurrentListEntry = pCurrentListEntry->Flink;
}
return STATUS_SUCCESS;
}

结果.

代码简单改一下.还可以获得指定的模块的基址以及结束地址.

代码如下

VOID GetModuleBaseByName(PDRIVER_OBJECT pDriverObj,UNICODE_STRING ModuleName)
{
PLDR_DATA_TABLE_ENTRY pLdr = NULL;
PLIST_ENTRY pListEntry = NULL;
PLIST_ENTRY pCurrentListEntry = NULL; PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
pListEntry = pLdr->InLoadOrderLinks.Flink;
pCurrentListEntry = pListEntry->Flink; while (pCurrentListEntry != pListEntry) //前后不相等
{
//获取LDR_DATA_TABLE_ENTRY结构
pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (pCurrentModule->BaseDllName.Buffer != 0)
{ if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0)
{
DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
pCurrentModule->BaseDllName,
pCurrentModule->DllBase,
(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
} }
pCurrentListEntry = pCurrentListEntry->Flink;
}
}

驱动中遍历模块,以及获取ntoskrnl.exe基址的更多相关文章

  1. kernel 获取ntoskrnl.exe基址

    标题: kernel shellcode之寻找ntoskrnl.exe基址 http://scz.617.cn:8/windows/201704171416.txt 以64-bits为例,这是Eter ...

  2. scala调用java的方法,返回了一个对象链表List<Student>,在scala中遍历该链表获取指定Student的名字name

    假设Student类如下: class Student { private int no; private String name; public int getNo() { return no; } ...

  3. VC中遍历进程并获取进程信息

    代码如下: /***************************************************/ /* 函数: 遍历进程信息 /* 参数:进程名称 例如: aaa.exe /* ...

  4. python 中requests 模块用py2exe生成exe后SSL certificate exception的问题

    [('system library', 'fopen', 'No such process'), ('BIO routines', 'BIO_new_file', 'no such file'), ( ...

  5. 驱动中获取PsActiveProcessHead变量地址的五种方法也可以获取KdpDebuggerDataListHead

    PsActiveProcessHead的定义: 在windows系统中,所有的活动进程都是连在一起的,构成一个双链表,表头是全局变量PsActiveProcessHead,当一个进程被创建时,其Act ...

  6. SOS从内存转储中提取模块(EXE、DLL和其他二进制文件)

    假设有一种情况,您从客户那里得到一个内存转储,需要模块(DLL.EXE.OCX等)来进一步调试..(.NET模块可用于通过反向工程查看源代码.)我们可以使用windbg目录中的clr10\sos.dl ...

  7. VC中遍历目标进程中的模块

    VC中遍历目标进程中的模块 MFC代码win32 也可以用 在下面代码进行修改转换就可以了CString strModule; 可以换成 char* 但是MODULEENTRY32结构中的szModu ...

  8. java中遍历实体类,获取属性名和属性值

    方式一(实体类): //java中遍历实体类,获取属性名和属性值 public static void testReflect(Object model) throws Exception{ for ...

  9. 在弹框中获取foreach中遍历的id值,并传递给地址栏(方法2)

    1.php有时候我们需要再弹框中获取foreach中遍历的数据(例如id),在弹框中点击按钮并传递给地址栏跳转.那么应该怎么做呢.第二种方法. 2. 可以在弹框中给出一个input hidden 点击 ...

随机推荐

  1. c#---Socean.RPC框架实测[并发量13w][响应时间0.04ms]

    目录1.高性能RPC框架:Socean.RPC 前言 经过一段时间的优化,Socean.RPC的性能又提高了一些,不过这差不多是socketAPM模型的极限了.本框架仅仅2000多行代码,无第三方框架 ...

  2. 指针 vs 引用 (2)

    这波要针对上篇分析里 标红的问题(成员变量用 T,T&啥情况)继续思考, 要学习以下材料: 1. 知乎上:用指针还是引用 2. StackOverflow上的相关问题 https://stac ...

  3. Mybatis源码解析(三) —— Mapper代理类的生成

    Mybatis源码解析(三) -- Mapper代理类的生成   在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...

  4. cmd脚本

    管道命令 | |命令的作用,就是让前一命令的输出当做后一命令的输入. > >会清除掉原有文件中的内容后把新的内容写入原文件: echo @echo off > a.bat. > ...

  5. Matlab享元模式

    享元模式(Flyweight)通过共享技术实现相同或相似对象的重用,可以减少创建对象的数量,以减少内存占用和提高性能.Java String的常量池,python logging,线程池,数据库连接池 ...

  6. 面试题:什么叫B*树

    B*-tree是B+-tree的变体,在B+树的基础上(所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针),B*树中非根和非叶子结点再增加指向兄弟的指针:

  7. Mysql基础。

    之前学SQL server的时候简单学过SQL的一点基础,Mysql就直接从外键约束开始继续学. 外键约束:foreign key 让表与表产生关系,从而保证数据的正确性. 1.在创建表时添加外键: ...

  8. 详解Eureka 缓存机制

    原文:https://www.cnblogs.com/yixinjishu/p/10871243.html 引言 Eureka是Netflix开源的.用于实现服务注册和发现的服务.Spring Clo ...

  9. Ueditor 自动设置上传图片的宽度或高度

    Uedior在上传图片的生活,需要自动设置上传图片的宽度或高度属性.该方法只能用于多图上传组件,单图上传无法使用. 该方法基于 ueditor 1.4.3 版本制作: 1.添加属性字段,在config ...

  10. HTTP状态码面试必知

    typora-root-url: ./HTTPCODE HTTP状态码必知必会 这里主要介绍运维过程中经常遇到的状态码.并通过业界流行的Nginx进行模拟实现,让大家能有一种所见即所得的感觉.希望大家 ...