~~本文所有内容均为胡诌,如有不正确的地方,随时私信。~~
知识理论
内核模块
内核模块是什么?
内核模块如何布局的?
暴力搜索
如何通过特征码暴力搜索未导出函数?
内核模块
内核模块是什么?
驱动程序每一个都是一个模块,称为“内核模块”。
- 都可以加载到内核中。
- 都遵守PE格式。
- 任意一个sys文件与内核文件没有区别。
- 运行的时候 - DriverEntry一旦开始运行的时候,就已经加载完毕了。
每一个内核都有一个DRIVEROBJECT的描述结构体 NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) PDRIVER_OBJECT 指向内核模块的结构体 PUNICODE_STRING 每次向注册表写入的一个值 。
内核模块布局
内核模块遍历
模块A的
pDataTableEntry->InLoadOrderLinks.Flink
就是模块B
DRIVER_OBJECT
地址
PLDR_DATA_TABLE_ENTRY pDataTableEntry = (PLDRDATA_TABLE_ENTRY)pDriverObject->DriverSection )
vkd> dt _DRIVER_OBJECT 822CEC08 ntdll!_DRIVER_OBJECT +0x000 Type : 0n4 +0x002 Size : 0n168 +0x004 DeviceObject : (null) //3环与0环通信,正常这里有一个设备地址 +0x008 Flags : 0x12 +0x00c DriverStart : 0xf8880000 Void//这个驱动被加载到的地址。类似ImageBase +0x010 DriverSize : 0x6000//占用大小 +0x014 DriverSection : 0x81a8e288 Void//这里是一个结构体链表,可以遍历。指向一个_LDR_DATA_TABLE_ENTRY结构 +0x018 DriverExtension : 0x822cecb0 _DRIVER_EXTENSION +0x01c DriverName : _UNICODE_STRING "\Driver\MyDriver2" +0x024 HardwareDatabase : 0x80690a90 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM" +0x028 FastIoDispatch : (null) +0x02c DriverInit : 0xf8884000 long MyDriver2!GsDriverEntry+0 +0x030 DriverStartIo : (null) +0x034 DriverUnload : 0xf8881030 void MyDriver2!DriverUnload123+0 +0x038 MajorFunction : [28] 0x804fb87e long nt!IopInvalidDeviceRequest+0 //这里存放28个回调函数 kd> g
kd> dt _DRIVER_EXTENSION 0x822cecb0 ntdll!_DRIVER_EXTENSION +0x000 DriverObject : 0x822cec08 _DRIVER_OBJECT +0x004 AddDevice : (null) +0x008 Count : 0 +0x00c ServiceKeyName : _UNICODE_STRING "MyDriver2" +0x014 ClientDriverExtension : (null) +0x018 FsFilterCallbacks : (null)
kd> dt _LDR_DATA_TABLE_ENTRY 0x81a8e288 ntdll!_LDR_DATA_TABLE_ENTRY // 执行下一个模块的起始位置 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x8055c1c0 - 0x820cfd98 ] +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0xffffffff - 0xffffffff ] +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x630069 - 0x0 ] +0x018 DllBase : 0xf8880000 Void//起始地址 +0x01c EntryPoint : 0xf8884000 Void +0x020 SizeOfImage : 0x6000 +0x024 FullDllName : _UNICODE_STRING "\??\C:\Documents and Settings\Administrator\桌面\MyDriver2.sys" +0x02c BaseDllName : _UNICODE_STRING "MyDriver2.sys" +0x034 Flags : 0x9104000 +0x038 LoadCount : 1 +0x03a TlsIndex : 0x49 +0x03c HashLinks : _LIST_ENTRY [ 0xffffffff - 0xfe65 ] +0x03c SectionPointer : 0xffffffff Void +0x040 CheckSum : 0xfe65 +0x044 TimeDateStamp : 0xfffffffe +0x044 LoadedImports : 0xfffffffe Void +0x048 EntryPointActivationContext : (null) +0x04c PatchInformation : 0x0079004d Void
遍历模块
利用:
LDRDATATABLEENTRY->InLoadOrderLinks
遍历所有内核模块。
include typedef struct LDRDATATABLEENTRY { LISTENTRY InLoadOrderLinks; LISTENTRY InMemoryOrderLinks; LISTENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODESTRING FullDllName; UNICODESTRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LISTENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; }; union { struct { ULONG TimeDateStamp; }; struct { PVOID LoadedImports; }; }; } LDRDATATABLEENTRY, * PLDRDATATABLEENTRY; VOID Unload(IN PDRIVEROBJECT pDriverObject) { DbgPrint("Goodbye world!\n"); return STATUSSUCCESS; } VOID EnumDriver(PDRIVEROBJECT pDriverObject) { LDRDATATABLEENTRY* pDataTableEntry, * pTempDataTableEntry; PLISTENTRY pList; pDataTableEntry = (LDRDATATABLEENTRY*)pDriverObject->DriverSection; if (!pDataTableEntry) { return; } pList = pDataTableEntry->InLoadOrderLinks.Flink; KdPrint(("系统中所有驱动模块的枚举")); while (pList != &pDataTableEntry->InLoadOrderLinks) { pTempDataTableEntry = (LDR_DATA_TABLE_ENTRY*)pList; KdPrint(("驱动名称 :%wZ , 模块地址:0x%x", &pTempDataTableEntry->FullDllName, &pTempDataTableEntry->EntryPoint)); pList = pList->Flink; } } NTSTATUS DriverEntry(IN PDRIVEROBJECT pDriverObject, IN PUNICODESTRING RegistryPath) { EnumDriver(pDriverObject); pDriverObject->DriverUnload = Unload; return STATUS_SUCCESS; }
暴力搜索未导出函数
内存遍历
1. 找到内核模块,然后按照特征码进行搜索。
2. windbg u + 函数名。
3. 根据硬编码进行匹配,根据功能比较特殊的,跳着提取。
4. 与重定位相关的不能作为特征码。
5. 常用的功能不能作为特征码。
6. 先匹配第一个值,如果一样加偏移在匹配第二个值,如果一样在加偏移匹配第三个值。
01 01 01 01 ?? ?? ?? ?? 02 02 02 02 ?? ?? ?? 03 03 03 03
代码
#include <ntifs.h> 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; typedef NTSTATUS(*PSPTERMINATETPROCESS)(PEPROCESS Process, NTSTATUS ExitStatus); ULONG GetPspTerminateProcess(ULONG ModuleBase, ULONG ModuleSize); VOID Unload(IN PDRIVER_OBJECT pDriverObject) { DbgPrint("Goodbye world!\n"); return STATUS_SUCCESS; } ULONG EnumDriver(PDRIVER_OBJECT pDriverObject) { LDR_DATA_TABLE_ENTRY* pDataTableEntry, * pTempDataTableEntry; ULONG flag = -1; PLIST_ENTRY pList; pDataTableEntry = (LDR_DATA_TABLE_ENTRY*)pDriverObject->DriverSection; if (!pDataTableEntry) { return 0; } pList = pDataTableEntry->InLoadOrderLinks.Flink; KdPrint(("系统中所有驱动模块的枚举")); while ((pList != &pDataTableEntry->InLoadOrderLinks) && (flag == -1)) { pTempDataTableEntry = (LDR_DATA_TABLE_ENTRY*)pList; flag = GetPspTerminateProcess(pTempDataTableEntry->DllBase, pTempDataTableEntry->SizeOfImage); pList = pList->Flink; } return flag; } ULONG GetPspTerminateProcess(ULONG ModuleBase, ULONG ModuleSize) { ULONG code1 = 0x8b55ff8b, code2 = 0xa16456ec, code3 = 0x00000124, code4 = 0x3b08758b; //SP2 ULONG i; ULONG address; DbgPrint("0x%x 0x%x\n", ModuleBase, ModuleSize); if (ModuleBase == 0x0) { return -1; } for (i = ModuleBase; i <= ModuleBase + ModuleSize; i++) { if (MmIsAddressValid((PULONG)i)) { //蓝屏原因:搜索到之后就应该退出,少句代码return address if ((*(PULONG)i == code1) && (*(PULONG)(i + 4) == code2) && (*(PULONG)(i + 8) == code3) && (*(PULONG)(i + 12) == code4)) { address = (ULONG)i; KdPrint(("[GetPspTerminateProcess] address :0x%x\n", address)); //打印地址 return address; } } } return -1; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath) { PSPTERMINATETPROCESS MyPspTerminateProcess; PEPROCESS pEProc; NTSTATUS FLAG; ULONG Address = EnumDriver(pDriverObject); //DbgPrint("函数地址:0x%x\n",Address); FLAG = PsLookupProcessByProcessId((HANDLE)1048, &pEProc); if (MmIsAddressValid((PULONG)Address)) { MyPspTerminateProcess = (PSPTERMINATETPROCESS)Address; //定位PspTerminateProcess MyPspTerminateProcess(pEProc, 0); //杀进程 } DbgPrint("函数强制结束成功\n"); ObDereferenceObject(pEProc); pDriverObject->DriverUnload = Unload; return STATUS_SUCCESS; }