目录
0.内核模块
1.DRIVER_OBJECT
<1>.代码示例
2.遍历内核模块
<1>.手动查看
<2>.代码遍历
0.内核模块
1).在应用层中,每一个.exe/.dll都称之为模块,也就是PE文件.一个进程中除了自身主模块可以包含多个模块(dll).
2).驱动程序每一个都是一个模块,称为"内核模块",都可以加载到内核中,都遵守PE结构.但本质上讲,任意一个.sys文件与内核文件没有区别.
1.DRIVER_OBJECT
通过Windbg输入指令 dt _DRIVER_OBJECT
每个内核模块都有一个对应的结构体,来描述这个模块在内核中的:位置,大小,名称等等.
nt!_DRIVER_OBJECT
+0x000 Type : Int2B//类型
+0x002 Size : Int2B//大小
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT//设备对象结构
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void//模块基址
+0x010 DriverSize : Uint4B//模块大小
+0x014 DriverSection : Ptr32 Void//指向_LDR_DATA_TABLE_ENTRY结构体
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION//驱动扩展
+0x01c DriverName : _UNICODE_STRING//模块名称
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long//驱动真正入口点函数
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void//卸载函数
+0x038 MajorFunction : [28] Ptr32 long//派遣函数
<1>.代码示例
#include <ntifs.h>
NTSTATUS DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrint("Driver Exit \r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
DbgPrint("Driver Load \r\n");
pDriver->DriverUnload = DriverUnload;
DbgPrint("PDRIVER_OBJECT -> [0x%08x] \r\n", pDriver);
return STATUS_SUCCESS;
}
1).输出驱动对象地址?
2).通过Windbg查看结构属性
DRIVER_EXTENSION -> ServiceKeyName 为服务名
CMD中可输入
net start ServiceKeyName启动一个服务
net stop ServiceKeyName停止一个服务
2.遍历内核模块
DRIVER_OBJECT?->?DriverSection指向结构体_KLDR_DATA_TABLE_ENTRY(未导出结构)
WRK中的定义如下:
typedef struct _KLDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;//双向链表指向其他内核模块 通过链表可遍历当前系统所有内核模块
ULONG __Undefined1;
ULONG __Undefined2;
ULONG __Undefined3;
ULONG NonPagedDebugInfo;
ULONG DllBase;//模块基址
ULONG EntryPoint;//模块入口点
ULONG SizeOfImage;//模块大小
UNICODE_STRING FullDllName;//模块路径
UNICODE_STRING BaseDllName;//模块名称
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG __Undefined6;
ULONG CheckSum;
ULONG TimeDateStamp;
} KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY;
<1>.手动查看
DRIVER_OBJECT->DriverSection指向当前内核模块
通过第一个成员双向链表可以遍历整个未隐藏内核模块
<2>.代码遍历
#include <ntifs.h>
typedef struct _KLDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
ULONG __Undefined1;
ULONG __Undefined2;
ULONG __Undefined3;
ULONG NonPagedDebugInfo;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG __Undefined6;
ULONG CheckSum;
ULONG TimeDateStamp;
} KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY;
NTSTATUS DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrint("Driver Unload\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
PKLDR_DATA_TABLE_ENTRY pCur = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
PKLDR_DATA_TABLE_ENTRY pTem = pCur;
do
{
DbgPrint("IMAGEBASE [0x%08x] NAME [%ws] \r\n", pCur->DllBase, pCur->FullDllName.Buffer);
pCur = (PKLDR_DATA_TABLE_ENTRY)(pCur->InLoadOrderLinks.Blink);
} while (pCur != pTem);
//IRP
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
?
|