KdMapper被加载驱动的实现
1.背景
内核映射器有较多年历史了,其中KdMapper是比较著名的,原版中它使用intel的驱动漏洞可以无痕的加载未经签名的驱动。本文章对被加载的驱动的实现进行简单的介绍。
2.常规实现
正常情况下,驱动是被KdMapper加载到内存,然后解析导入函数后直接调用其入口函数,故其加载的驱动有以下要求:
2.1 禁用安全检查
2.2 入口点为自定义函数
2.3 不能使用入口函数的参数
入口函数的两个参数 PDRIVER_OBJECT 和 PUNICODE_STRING 不能使用,因为KdMapper在进行无痕加载时并未初始化这两个参数,所以一般情况下驱动代码如下:
NTSTATUS CustomDriverEntry(
_In_ PDRIVER_OBJECT kdmapperParam1,
_In_ PUNICODE_STRING kdmapperParam2
)
{
UNREFERENCED_PARAMETER(kdmapperParam1);
UNREFERENCED_PARAMETER(kdmapperParam2);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Hello world!,This is called by KdMapper\r\n");
return 1;
}
2.4 常规测试效果
如图:
调试加载的驱动后仅打印一句消息,然后可以是进行一些操作,只是没有 PDRIVER_OBJECT 和 PUNICODE_STRING。
3. 可创建设备实现
3.1 代码实现
由于没有 PDRIVER_OBJECT 参数,即没有驱动对象,这些创建设备之类的都不可行,但也有方法来创建驱动对象,即使用未文档化 IoCreateDriver来创建。
实现代码如下:
#include <ntddk.h>
EXTERN_C
NTKERNELAPI
NTSTATUS IoCreateDriver(PUNICODE_STRING DriverName, PDRIVER_INITIALIZE InitializationFunction);
NTSTATUS DriverLoad(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisteryPath)
{
UNREFERENCED_PARAMETER(RegisteryPath);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "This is DriverLoad By IoCreateDriver\r\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "DriverObject is 0x%p\r\n", DriverObject);
return STATUS_SUCCESS;
}
NTSTATUS CustomDriverEntry(
_In_ PDRIVER_OBJECT kdmapperParam1,
_In_ PUNICODE_STRING kdmapperParam2
)
{
UNREFERENCED_PARAMETER(kdmapperParam1);
UNREFERENCED_PARAMETER(kdmapperParam2);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Hello world!,This is called by KdMapper\r\n");
UNICODE_STRING DriverName;
RtlInitUnicodeString(&DriverName, L"\\Driver\\HelloWorld");
IoCreateDriver(&DriverName, &DriverLoad);
return 1;
}
3.2 实现效果
可以看到生成的DriverObject地址,有了DriverObject就可以创建设备并进行通讯了,如图: