在win7 x64下做个复杂的内核绘制(有码续集)

上一贴《在win7 x64下做个简单的内核绘制》(点击即可阅读)中我们最后说到,有些dx9的程序,并不会走到NtUserHwndQueryRedirectionInfo。
这里我们来分析下具体原因是什么。
首先我们找到一款名为:CrossFire的游戏,作为示例。
一通调试分析,找到如下代码:
图片可能有点模糊,命中断点位置的代码是:
cmp [esi+760],ebx:其中 esi+760 = 0xC2D4118。
然而地址 0xC2D4118的值为0,所以代码会 je D3D9.DLL+7C47。
抛开这里往下看,如果没有je D3D9.DLL+7C47。
代码会走进这里:
一路跟进去:
再跟:
最终来到了熟悉的泉水湾(呸), 是NtUserHwndQueryRedirectionInfo:
然而直接走到D3D9.DLL+7C47 ,
肯定不会经过:
NtUserHwndQueryRedirectionInfo
最简单的解决方式肯定是直接把 je D3D9.DLL+7C47 nop,测试结果如下:
很明显,改了之后加载驱动可以直接绘制上这个“基佬色”的方块。
然而还原之后:
绘制效果消失了。
而且在 USER32.HungWindowFromGhostWindow+20处下断点是不会命中的(这不是废话吗)。
梳理流程:
判断函数主要判断 [esi+760] 是否为0。
如果为0,直接走D3D9.DLL+7C47,
否则走 NtUserHwndQueryRedirectionInfo。
这里我有必要提一下,不要想着锁定 [esi+760] 的值,这样做会导致D3D无限初始化Surface。
虽然进了 NtUserHwndQueryRedirectionInfo,但是会一直在这里死循环,不再进行任何绘制。
而且修改代码段的内存来强行让他走NtUserHwndQueryRedirectionInfo,恐怕也不是各位看官想要的结果。
摆在面前的有两条路:
1、在创建窗口->创建D3D设备 这个流程中仔细分析创建需要的参数,找出其原因。
2、在这个绘制流程中,进入判断函数前 改掉 [esi+760] 的值,进入 NtUserHwndQueryRedirectionInfo 之后再改回来。
由于时间有限,我姑且只讲一下第二种方式。
笔者重新理了一下流程:
如图所示,我们只需要在 D3DKMTPresent 这个函数进入内核之后
改变其 [esp+760] 的值为1。
在进入判断代码时,就会顺理成章的进入NtUserHwndQueryRedirectionInfo,
然后我们在 NtUserHwndQueryRedirectionInfo里把 [esp+760] 的值改成 0 。
这样走到后面的检测代码中,就不会无限获取D3D9主Surface导致死循环。
还有个很重要的问题 esp+760 如何获取,这个比较简单了,经过笔者指针扫描+瞎猜。
这个值可以通过如下方式获得。
最后一级偏移为760,所得地址便是 esp+760,所得值便是 [esp+760]。
同上一贴《在win7 x64下做个简单的内核绘制》(点击即可阅读)一样,这里没有本贴的代码或者poc。
上一贴的代码和示例demo在附件中。
原文作者:万剑归宗
原文链接:https://bbs.pediy.com/thread-247826.htm
转载请注明:转自看雪学院
更多阅读:
3、体验加壳过程