首页
社区
课程
招聘
[原创]Hook GetWindow
发表于: 8小时前 80

[原创]Hook GetWindow

8小时前
80

属于很古旧的方式,放在很多年以前确实还是比较好用的,目前的话属于没什么用,当然对抗纯R3的Api遍历依旧有效果。

演示系统版本:WIN11 25H2(因为应用层的结构非常稳定,不会像内核tagWND一样经常改变,所以你使用你自己的操作系统按照这里的偏移依旧可以轻松复现)

这里的qword_1800D02C8就是我们的gSharedInfo地址+8解引用的值。这里的dword_1800D02D0就是我们的gSharedInfo地址+0x10解引用的值,所以我们在内核中只需要解析user32.dll的pdb,拿到gSharedInfo的地址我们就可以获取到这两个数值。
接下来我们在CE中打开winlogon.exe,因为winlogon.exe是系统进程能确保所有的操作系统都有这个进程,另外打开一个有窗口的演示进程,我们使用spy获取到这个窗口的窗口句柄。

这里我们依旧计算出了v11的值,因为不同进程这两个全局变量对应的值是不一样的,具体来说这里计算出的值也就是如果在winlogon.exe中调用GetWindow,且参数1是0x3003E时,v11经计算出来的值。
在正常流程下,GetWindow函数拿到v11后,通过 调用

那么我们要让系统所有进程调用GetWindow函数时,在某些情况下进入内核,那么就需要修改

让这个if语句不再返回真即可,我们到CE中查看v11+0x10这个地址的值

因为我们要让所有进程都生效,正是因为他是共享内存,所以我们便可以使用物理写来修改这个地址,那么任何进程调用GetWindow函数,参数1只要是我们修改v11+0x10地址的值后的hwnd,那么他就一定会走

那么现在我们在CE中具体操作一下,我们右键查看(v11+0x10)的
内存区域,获取到这个地址对应的物理地址。

然后我们在Windbg中查看并修改第一字节

修改后我们就可以,用CE打开spy对NtUserMapDesktopObject的调用点下断,CE从winlogon进程切换到spy的原因是spy调用了GetWindow函数方便查看效果。

可以看到调用GetWindow时,如果hwnd是我们修改过v11+0x10的值的hwnd,那么获取应用层tagWND时,就要调用NtUserMapDesktopObject函数不再通过共享内存获取。

大于等于WIN11就hook NtUserMapDesktopObject,WIN10就hook NtUserCallOneParam。

全部return 0时会出现窗口卡死的问题。我们只需要在我们的hook函数内调用PsGetCurrentThreadProcessId函数,打印一下进程名肯定更好,然后开始拖动窗体,点击窗体的按钮,看看有哪些进程被打印了,测试发现基本就是进程自身还有dwm进程,当这两个进程调用NtUserMapDesktopObject如果我们返回空tagWND,窗体将无法正常使用。

当要获取应用层tagWND时都会进行前文提到的这个if判断,我们修改v11+0x10地址的值后会导致其他函数也进入了NtUserMapDesktopObject,比如

user32!DispatchMessageWorker->user32!ValidateHwnd内部就进入了我们的NtUserMapDesktopObject。再比如调用GetForegroundWindow、EnumWindows、IsWindowVisible等都进入了这个分支,但是像GetForegroundWindow我们不希望他返回空tagWND,这时候我们就需要像windbg的kv指令一样,KeGetCurrentThread()->TrapFrame->Rsp 就是用户栈指针,不理解的话直接让AI复现即可。

我们的目标是让GetWindow函数遍历不到我们的窗体,但是hook NtUserMapDesktopObject后直接返回空tagWND显然是不对的,因为我们遍历时调用GetNextWindow这个宏,当我们的Previous Window的handle作为参数1调用GetNextWindow时是可以返回我们处理了v11+0x10位置的这个hwnd的,当这个hwnd作为参数调用GetNextWindow时才会无效,并且出现截断(也就是这个hwnd之后用GetNextWindow,或者获取child window的窗体都因为这里返回空tagWND导致遍历结果列表中不再出现这些窗体),所以正确的方法是先获取到我们要保护的窗体的Previous Window的handle以及Next Window的Handle,并且判断该调用来源于GetWindow函数,然后判断uCmd参数,直接用Previous Window的handle以及Next Window的Handle先调用NtUserMapDesktopObject,获取到这两个窗口的应用层tagWND,然后根据参数替换为对应的tagWND进行返回即可。


传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

收藏
免费 4
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回