驱动中遍历模块,以及获取ntoskrnl.exe基址
方法是基于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基址的更多相关文章
- kernel 获取ntoskrnl.exe基址
标题: kernel shellcode之寻找ntoskrnl.exe基址 http://scz.617.cn:8/windows/201704171416.txt 以64-bits为例,这是Eter ...
- scala调用java的方法,返回了一个对象链表List<Student>,在scala中遍历该链表获取指定Student的名字name
假设Student类如下: class Student { private int no; private String name; public int getNo() { return no; } ...
- VC中遍历进程并获取进程信息
代码如下: /***************************************************/ /* 函数: 遍历进程信息 /* 参数:进程名称 例如: aaa.exe /* ...
- python 中requests 模块用py2exe生成exe后SSL certificate exception的问题
[('system library', 'fopen', 'No such process'), ('BIO routines', 'BIO_new_file', 'no such file'), ( ...
- 驱动中获取PsActiveProcessHead变量地址的五种方法也可以获取KdpDebuggerDataListHead
PsActiveProcessHead的定义: 在windows系统中,所有的活动进程都是连在一起的,构成一个双链表,表头是全局变量PsActiveProcessHead,当一个进程被创建时,其Act ...
- SOS从内存转储中提取模块(EXE、DLL和其他二进制文件)
假设有一种情况,您从客户那里得到一个内存转储,需要模块(DLL.EXE.OCX等)来进一步调试..(.NET模块可用于通过反向工程查看源代码.)我们可以使用windbg目录中的clr10\sos.dl ...
- VC中遍历目标进程中的模块
VC中遍历目标进程中的模块 MFC代码win32 也可以用 在下面代码进行修改转换就可以了CString strModule; 可以换成 char* 但是MODULEENTRY32结构中的szModu ...
- java中遍历实体类,获取属性名和属性值
方式一(实体类): //java中遍历实体类,获取属性名和属性值 public static void testReflect(Object model) throws Exception{ for ...
- 在弹框中获取foreach中遍历的id值,并传递给地址栏(方法2)
1.php有时候我们需要再弹框中获取foreach中遍历的数据(例如id),在弹框中点击按钮并传递给地址栏跳转.那么应该怎么做呢.第二种方法. 2. 可以在弹框中给出一个input hidden 点击 ...
随机推荐
- jsp,servlet文件上传问题完善
1. 上传文件时文件名中文乱码 upload.setHeaderEncoding("utf-8"); 有个疑惑: 不管设置不设置都不乱码,但是刘帅龙老师讲的时候出现了乱码 . 2. ...
- OpenGl函数库
[OpenGL核心函数库] glAccum操作累加缓冲区glAddSwapHintRectWIN定义一组被SwapBuffers拷贝的三角形glAlphaFunc允许设置alpha检测功能glAreT ...
- Java 字符串(一)字符串初始化
一.String类概述 1.概述 java.lang.String 类代表字符串.Java程序中所有的字符串文字(例如 "abc" )都可以被看作是实现此类的实例.String 是 ...
- 2007英语CET6四6级资料六级大学单词
anticipation n. 预期,期望 appreciation n. 感谢,感激 array n. 陈列,一系列 assurance n. 保证 emergency n. 紧急情况 encour ...
- Excel 批量导入Mysql(创建表-追加数据)
之前弄数据库的时候, 测试excel导mysql, 中间用pandas 处理后再入库. 直接上代码, 此种有真意, 尽在不言中. #!/usr/bin/env python # coding: ut ...
- mac php thinkphp5 验证码报错 Call to undefined function think\captcha\imagettftext()
百度一下,是GD库里缺少了freetype支持,然后各种拓展的方法都试了半天,php-v里都生效了,phpinfo里还是不生效,原来是各种文章里都缺少了最关键的一步,修改Apache的配置(我使用的是 ...
- Git回滚代码
回滚命令: 1.回退到上个版本 $ git reset --hard HEAD^ 2.回退到前2次提交之前,以此类推,回退到n次提交之前 $ git reset --hard HEAD~2 3.退到/ ...
- K8S概念理解参考
- git提交时报错处理办法
git提交时报错:Updates were rejected because the tip of your current branch is behind: 有如下几种解决方法: 1.使用强制pu ...
- eclipse集成lombok插件
原文:https://my.oschina.net/u/3771868/blog/1837243 lombok官网:https://projectlombok.org/jar包下载路径:https:/ ...