~~本文所有内容均为胡诌,如有不正确的地方,随时私信。~~
知识理论
内核模块是什么?
内核模块如何布局的?
暴力搜索
如何通过特征码暴力搜索未导出函数?
内核模块
内核模块是什么?
驱动程序每一个都是一个模块,称为“内核模块”。
-
都可以加载到内核中。
-
都遵守PE格式。
-
任意一个sys文件与内核文件没有区别。
-
运行的时候 - DriverEntry一旦开始运行的时候,就已经加载完毕了。
每一个内核都有一个DRIVEROBJECT的描述结构体 NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) PDRIVER_OBJECT 指向内核模块的结构体 PUNICODE_STRING 每次向注册表写入的一个值 。
内核模块布局
内核模块遍历
模块A的
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 "DriverMyDriver2"
+0x024 HardwareDatabase : 0x80690a90 _UNICODE_STRING "REGISTRYMACHINEHARDWAREDESCRIPTIONSYSTEM"
+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 SettingsAdministrator桌面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)
{
world!n");
return STATUS_SUCCESS;
}
ULONG EnumDriver(PDRIVER_OBJECT pDriverObject)
{
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;
0x%xn", 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;
address :0x%xn", 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%xn",Address);
FLAG = PsLookupProcessByProcessId((HANDLE)1048, &pEProc);
if (MmIsAddressValid((PULONG)Address))
{
MyPspTerminateProcess = (PSPTERMINATETPROCESS)Address; //定位PspTerminateProcess
0); //杀进程
}
DbgPrint("函数强制结束成功n");
ObDereferenceObject(pEProc);
Unload; =
return STATUS_SUCCESS;
}
end
本文始发于微信公众号(雷石安全实验室):利用未导出函数结束进程
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论