win7 x64 inline hook的尝试

编程入门 行业动态 更新时间:2024-10-14 20:23:22

win7 x64 inline <a href=https://www.elefans.com/category/jswz/34/1758968.html style=hook的尝试"/>

win7 x64 inline hook的尝试

最近因为虚机性能问题,需要验证下是不是因为内核态加锁时间过长导致,所以需要在内核态hook两个内核函数:
KeAcquireSpinLockAtDpcLevel和KeReleaseSpinLock,虚机的操作系统是win7 64位。
所以在内核态hook,我采用inline hook的方式,有借鉴的blog:

这篇博客对原理讲的比较清楚,博客的作者说那段代码会蓝屏,他没有具体说是什么现象的蓝屏,所以我也不清楚到底他指的蓝屏是什么,但是我在实际使用过程中发现有两个蓝屏问题:

patch guard导致的蓝屏

我利用博客代码对KeAcquireSpinLockAtDpcLevel和KeReleaseSpinLock两个函数进行了hook,欣喜的是能顺利hook到两个函数里面,但是不一会儿就蓝屏了,蓝屏界面如下:


这个蓝屏导致的原因是win7 64位系统的patch guard机制,系统会不定时检测内核是否被篡改,如果有篡改就会促发蓝屏。

(1)对破解软件的尝试,我尝试了网上说的一些方法,比如我下载了no_pg_ds_v3这个工具,然后按照文档进行部署,部署成功后重启,会提示如下界面:


这时候选中“PatchGuard Disabled V3”,然后按F8去掉驱动程序签名强制,这时候就进入系统了,然而并没有什么卵用,系统还是会触发一样的蓝屏。

(2)对于调试模式的尝试,据说微软在调试模式会自动去掉patch guard机制,要不然windbg怎么做到打断点之类的功能的,于是我设置了一个调试模式的引导项,可以参照,重启后进入该引导项(上图的DebugEntry引导),还是没解决问题,最后找到了一篇外国的博客,需要在调试模式下再加一条命令:Bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 /start AUTOENABLE /noumex。这样patch guard就关掉了,经过测试可用。

因为对于我来说我只是开发一个调试工具,所以调试模式对我来说是可接受的,至于如何在普通场景下绕过去的方式我目前还没找到。

反编译引擎LDE造成的蓝屏

第二个蓝屏界面如下:


一般发生在加载驱动的时候,且刚开机的时候加载驱动特别容易重现。

我通过windbg对dump文件进行分析,发现每次蓝屏模块都不一样,也不是我写的那个程序模块,这样就比较难定位了。
我通过排除法,定位到蓝屏原因出在GetPatchSize函数,他是通过国外一个网友的一个shellcode来计算指令长度。

所以我直接没有调用这个函数,比如说我要hook KeAcquireSpinLockAtDpcLevel函数,我用GetPatchSize函数获取到他的指令长度为23,因为它指令长度不会变化,所以我就写死23。 其他函数也一样,先写一个demo,使用GetPatchSize计算指令长度,然后写死就行了。

核心代码:

ULONG lock_patch_size = 23;       
ULONG unlock_patch_size = 20;PVOID HookKernelApi(IN PVOID ApiAddress, IN PVOID Proxy_ApiAddress, OUT PVOID *Original_ApiAddress, IN ULONG PatchSize)
{/* 参数检查 */if (ApiAddress == nullptr || Proxy_ApiAddress == nullptr || Original_ApiAddress == nullptr) {return nullptr;}KIRQL irql;UINT64 tmpv;PVOID head_n_byte = nullptr, ori_func = nullptr;UCHAR jmp_code[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";UCHAR jmp_code_orifunc[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";//step 1: Read current datahead_n_byte = kmalloc(PatchSize);if (head_n_byte == nullptr) {return nullptr;}irql = WPOFFx64();memcpy(head_n_byte, ApiAddress, PatchSize);WPONx64(irql);//step 2: Create ori functionori_func = kmalloc(PatchSize + 14);    //原始机器码+跳转机器码if (ori_func == nullptr) {return head_n_byte;}RtlFillMemory(ori_func, PatchSize + 14, 0x90);tmpv = (ULONG64)ApiAddress + PatchSize;    //跳转到没被打补丁的那个字节memcpy(jmp_code_orifunc + 6, &tmpv, 8);memcpy((PUCHAR)ori_func, head_n_byte, PatchSize);memcpy((PUCHAR)ori_func + PatchSize, jmp_code_orifunc, 14);*Original_ApiAddress = ori_func;//step 3: fill jmp codetmpv = (UINT64)Proxy_ApiAddress;memcpy(jmp_code + 6, &tmpv, 8);//step 4: Fill NOP and hookirql = WPOFFx64();RtlFillMemory(ApiAddress, PatchSize, 0x90);memcpy(ApiAddress, jmp_code, 14);WPONx64(irql);return head_n_byte;
}VOID HookSpinlockFunctions()
{/* 加锁函数 */lock_head_n_byte = (PUCHAR)HookKernelApi(GetFunctionAddr(L"KeAcquireSpinLockAtDpcLevel"),(PVOID)Proxy_KeAcquireSpinLockAtDpcLevel,&ori_lock,lock_patch_size);/* 解锁函数 */unlock_head_n_byte = (PUCHAR)HookKernelApi(GetFunctionAddr(L"KeReleaseSpinLock"),(PVOID)Proxy_KeReleaseSpinLock,&ori_unlock,unlock_patch_size);
}

更多推荐

win7 x64 inline hook的尝试

本文发布于:2024-02-07 01:15:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1752442.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:hook   inline

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!