mirror of
https://github.com/Shinn-Home/KernelRuntimeImport
synced 2026-08-09 12:21:02 +00:00
3.9 KiB
3.9 KiB
KernelRuntimeImport
KernelRuntimeImport 是教学性质的 Windows x64 内核驱动示例,用于展示如何在运行时通过函数名 Hash 解析 ntoskrnl.exe 的导出函数地址并调用。
概览
实现运行时动态导入API并调用:
- 不直接在 PE 导入表中声明目标内核函数(IAT表不保存敏感函数,可以避免IAT Hook)。
- 在运行时定位内核镜像基址。
- 遍历导出表,对导出函数名做 Hash 比对。
- 解析到目标函数地址后,再通过函数指针完成调用。
当前示例以 MmGetPhysicalAddress 为例,演示完整的解析与调用流程。
Features
- 通过
__readmsr(0xC0000082)辅助定位ntoskrnl.exe基址,不依赖常规内核导出查询 API。 - 使用编译期字符串 Hash 宏
STRING_HASH(...)生成目标导出名 Hash。 - 通过遍历导出表并比较 Hash,在运行时解析目标函数地址。
- 使用
CALL_ROUTINE(...)宏将地址转换为目标函数签名并直接调用。 - 示例代码短小,便于二次扩展为多个导出函数的运行时解析器。
drv_main.cpp 中的最小调用示例如下:
constexpr ULONG MmGetPhysicalAddressHash = STRING_HASH("MmGetPhysicalAddress");
PVOID MmGetPhysicalAddressAddr = GetntoskrnlExportAddressByHash(MmGetPhysicalAddressHash);
if (MmGetPhysicalAddressAddr == nullptr)
{
DbgBreakPoint();
return STATUS_PROCEDURE_NOT_FOUND;
}
ULONG Num = 0x12345678;
PHYSICAL_ADDRESS PhyAddr = CALL_ROUTINE(
MmGetPhysicalAddressAddr,
ROUTINE_TYPE(PHYSICAL_ADDRESS, _In_ PVOID),
&Num);
UNREFERENCED_PARAMETER(PhyAddr);
上面的流程清楚说明了这个项目的核心功能:在驱动运行期间按 Hash 解析指定导出并直接调用,而不是通过静态导入项完成链接。
Supported Environment
目前仅在以下环境完成过测试:
| 系统版本 | 架构 | 状态 |
|---|---|---|
| Windows 10 19044 | x64 | 已测试 |
| Windows 11 22H2 | x64 | 已测试 |
| Windows 11 24H2 | x64 | 已测试 |
| Windows 11 25H2 | x64 | 已测试 |
说明:
- 从实现方式来看,理论上应兼容大部分 Windows 10 / Windows 11 x64 版本。
- 当前仓库只面向 x64 驱动场景,未验证 Win32、ARM 或 ARM64。
Build
当前构建环境如下:
- Visual Studio 2017
- WDK 10
- x64 Kernel-Mode Driver
构建步骤:
- 使用 Visual Studio 2017 打开
KernelRuntimeImport.sln。 - 确认已正确安装 WDK 10,并能使用
WindowsKernelModeDriver10.0工具链。 - 将构建平台切换为
x64。 - 选择
Debug或Release配置后执行编译。
说明:
- 当前项目仅支持 x64 驱动使用。
- 虽然工程文件中包含其他平台配置项,但当前实现和验证范围都以 x64 为准。
调试与警告
当导出函数解析失败时,当前示例会主动触发 DbgBreakPoint(),并返回 STATUS_PROCEDURE_NOT_FOUND:
if (MmGetPhysicalAddressAddr == nullptr)
{
DbgBreakPoint();
return STATUS_PROCEDURE_NOT_FOUND;
}
这意味着:
- 请在调试器连接的测试环境或虚拟机中运行本示例。
- 如果目标导出未解析成功,驱动会在
DriverEntry阶段中断,便于立刻定位问题。
项目结构
KernelRuntimeImport/KernelRuntimeImport.h:Hash、函数指针调用宏以及导出接口声明。KernelRuntimeImport/KernelRuntimeImport.cpp:内核基址定位与导出表遍历解析实现。KernelRuntimeImport/drv_main.cpp:最小驱动入口与调用示例。
使用说明
这个仓库更适合作为研究和演示样例阅读:
- 如果你想了解运行时导入的基本实现流程,可以从
DriverEntry入口开始读。 - 如果你想扩展为多个 API 的解析器,可以在现有
GetntoskrnlExportAddressByHash(...)基础上继续封装。 - 如果你想验证不同系统版本上的兼容性,建议在独立虚拟机中逐个测试。