运行后即可得到输出效果如下:
文章插图
第二步: 找到
KeSetTimer
从里面搜索特征得到call KeSetTimerEx
函数地址 , 还记得《驱动开发:内核枚举IoTimer定时器》
中我们采用的特征码定位方式吗 , 没错本次还要使用这个方法 , 我们此处需要搜索到e80c000000
这段特征 。/*lyshark.com 0: kd> uf KeSetTimernt!KeSetTimer:fffff807`70520a30 4883ec38subrsp,38hfffff807`70520a34 4c89442420movqword ptr [rsp+20h],r8fffff807`70520a39 4533c9xorr9d,r9dfffff807`70520a3c 4533c0xorr8d,r8dfffff807`70520a3f e80c000000callnt!KiSetTimerEx (fffff807`70520a50)fffff807`70520a44 4883c438addrsp,38hfffff807`70520a48 c3ret*/#include <ntddk.h>#include <ntstrsafe.h>// 得到KiProcessorBlock地址ULONG64 GetKeSetTimerEx(){// 获取 KeSetTimer 地址ULONG64 ul_KeSetTimer = 0;UNICODE_STRINGuc_KeSetTimer = { 0 };RtlInitUnicodeString(&uc_KeSetTimer, L"KeSetTimer");ul_KeSetTimer = (ULONG64)MmGetSystemRoutineAddress(&uc_KeSetTimer);if (ul_KeSetTimer == 0){return 0;}// 前 30 字节找 call 指令BOOLEAN b_e8 = FALSE;ULONG64 ul_e8Addr = 0;for (INT i = 0; i < 30; i++){// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)ul_KeSetTimer)){continue;}// e8 0c 00 00 00 call nt!KiSetTimerEx (fffff807`70520a50)if (*(PUCHAR)(ul_KeSetTimer + i) == 0xe8){b_e8 = TRUE;ul_e8Addr = ul_KeSetTimer + i;break;}}// 找到 call 则解析目的地址if (b_e8 == TRUE){if (!MmIsAddressValid((PVOID64)ul_e8Addr)){return 0;}INT ul_callCode = *(INT*)(ul_e8Addr + 1);ULONG64 ul_KiSetTimerEx = ul_e8Addr + ul_callCode + 5;return ul_KiSetTimerEx;}return 0;}VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("卸载完成... \n");}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("hello lyshark.com \n");ULONG64 address = GetKeSetTimerEx();if (address != 0){DbgPrint("KeSetTimerEx = %p \n", address);}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}
输出寻找CALL地址效果图如下:文章插图
第三步: 也是最重要的一步 , 在
KiSetTimerEx
里面 , 搜索特征 , 拿到里面的KiWaitNever(),KiWaitAlways()
这两个函数地址 。- 488b05850c5100 KiWaitNever
- 488b356b0e5100 KiWaitAlways
/*0: kd> uf KiSetTimerExnt!KiSetTimerEx:fffff807`70520a50 48895c2408movqword ptr [rsp+8],rbxfffff807`70520a55 48896c2410movqword ptr [rsp+10h],rbpfffff807`70520a5a 4889742418movqword ptr [rsp+18h],rsifffff807`70520a5f 57pushrdifffff807`70520a60 4154pushr12fffff807`70520a62 4155pushr13fffff807`70520a64 4156pushr14fffff807`70520a66 4157pushr15fffff807`70520a68 4883ec50subrsp,50hfffff807`70520a6c 488b05850c5100movrax,qword ptr [nt!KiWaitNever (fffff807`70a316f8)]fffff807`70520a73 488bf9movrdi,rcxfffff807`70520a76 488b356b0e5100movrsi,qword ptr [nt!KiWaitAlways (fffff807`70a318e8)]fffff807`70520a7d 410fb6e9movzxebp,r9b*/#include <ntddk.h>#include <ntstrsafe.h>// 得到KiProcessorBlock地址ULONG64 GetKeSetTimerEx(){// 获取 KeSetTimer 地址ULONG64 ul_KeSetTimer = 0;UNICODE_STRINGuc_KeSetTimer = { 0 };RtlInitUnicodeString(&uc_KeSetTimer, L"KeSetTimer");ul_KeSetTimer = (ULONG64)MmGetSystemRoutineAddress(&uc_KeSetTimer);if (ul_KeSetTimer == 0){return 0;}// 前 30 字节找 call 指令BOOLEAN b_e8 = FALSE;ULONG64 ul_e8Addr = 0;for (INT i = 0; i < 30; i++){// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)ul_KeSetTimer)){continue;}// e8 0c 00 00 00 call nt!KiSetTimerEx (fffff807`70520a50)if (*(PUCHAR)(ul_KeSetTimer + i) == 0xe8){b_e8 = TRUE;ul_e8Addr = ul_KeSetTimer + i;break;}}// 找到 call 则解析目的地址if (b_e8 == TRUE){if (!MmIsAddressValid((PVOID64)ul_e8Addr)){return 0;}INT ul_callCode = *(INT*)(ul_e8Addr + 1);ULONG64 ul_KiSetTimerEx = ul_e8Addr + ul_callCode + 5;return ul_KiSetTimerEx;}return 0;}// 得到KiWaitNever地址ULONG64 GetKiWaitNever(ULONG64 address){// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)address)){return 0;}// 前 100 字节找 找 KiWaitNeverfor (INT i = 0; i < 100; i++){// 48 8b 05 85 0c 51 00 | mov rax, qword ptr[nt!KiWaitNever(fffff807`70a316f8)]if (*(PUCHAR)(address + i) == 0x48 && *(PUCHAR)(address + i + 1) == 0x8b && *(PUCHAR)(address + i + 2) == 0x05){ULONG64 ul_movCode = *(UINT32*)(address + i + 3);ULONG64 ul_movAddr = address + i + ul_movCode + 7;// DbgPrint("找到KiWaitNever地址: %p \n", ul_movAddr);return ul_movAddr;}}return 0;}// 得到KiWaitAlways地址ULONG64 GetKiWaitAlways(ULONG64 address){// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)address)){return 0;}// 前 100 字节找 找 KiWaitNeverfor (INT i = 0; i < 100; i++){// 48 8b 35 6b 0e 51 00 | mov rsi,qword ptr [nt!KiWaitAlways (fffff807`70a318e8)]if (*(PUCHAR)(address + i) == 0x48 && *(PUCHAR)(address + i + 1) == 0x8b && *(PUCHAR)(address + i + 2) == 0x35){ULONG64 ul_movCode = *(UINT32*)(address + i + 3);ULONG64 ul_movAddr = address + i + ul_movCode + 7;return ul_movAddr;}}return 0;}VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("卸载完成... \n");}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("hello lyshark.com \n");ULONG64 address = GetKeSetTimerEx();if (address != 0){ULONG64 KiWaitNeverAddress = GetKiWaitNever(address);DbgPrint("KiWaitNeverAddress = %p \n", KiWaitNeverAddress);ULONG64 KiWaitAlwaysAddress = GetKiWaitAlways(address);DbgPrint("KiWaitAlwaysAddress = %p \n", KiWaitAlwaysAddress);}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如何更新电脑的显卡驱动(笔记本显卡驱动要不要更新)
- 你Win7系统如何将显卡驱动更新到最新版本
- envoy开发调试环境搭建
- 云原生时代的DevOps平台设计之道
- IOS12未受信任的企业级开发者怎么解决
- Taurus.MVC 微服务框架 入门开发教程:项目部署:7、微服务节点的监控与告警。
- 如何解决未受信任的企业级开发者的问题(如何安装未受信任的企业级开发者)
- ipad未受信任的企业级开发者怎么解决(ipad开发者模式)
- 未受信任的企业级开发者怎么设置(未受信任的企业级开发者有危险吗)
- ipad未受信任的企业级开发者怎么打开(软件在ipad上不受信任)