在 Windows 系统中,本文将探讨一种更为隐蔽的方法,通过利用 .data 段的特性进行钩子通信,以绕过反作弊检测。寻找目标 API:首先,需要在内核模块中找到一个可以通过用户模式调用的 API。这些 API 通常是 Nt 或 Zw 开头的函数,它们被用户模式的 DLL(例如 win32u.dll)导出。常见的候选模块包括 ntoskrnl.exe、win32k.sys、win32kbase.sys 等。win32k.sys 的特殊性: win32k.sys 是一个特殊的内核驱动程序,它在会话空间中加载,这意味着它的内存映射方式与其他内核模块不同。它被映射到 GUI 进程(例如资源管理器或 Winlogon),因此只能由 GUI 进程的线程访问。定位 .DATA 段中的函数指针:反汇编分析目标模块 (如 win32k.sys) , 找到要 hook 的目标函数,以及在 .data 段中指向这个函数的指针。这些指针通常被定义为全局变量或静态变量,可以通过反汇编或调试工具找到。附加到 GUI 进程:由于 win32k.sys 的特殊性,它的内存映射仅在 GUI 进程中可用,为了修改 .data 段的函数指针, 需要使用 KeStackAttachProcess 函数,将驱动程序附加到 GUI 进程的上下文中(例如资源管理器或者 Winlogon)。通过附加到 GUI 进程的上下文, 驱动程序可以获得 GUI 进程的页面目录,从而可以修改 win32k.sys 的 .data 段中的函数指针。修改 .data 段的函数指针:在 GUI 进程的上下文中,通过目标进程的虚拟地址找到需要修改的指针地址, 修改 .data 段中的函数指针,让它指向你的自定义函数。自定义函数可以执行恶意代码或者将控制权转移到另一个地方。恢复原始指针:在自定义函数执行完毕后,可以选择将函数指针恢复为原始值,这样可以避免对程序的正常运行造成影响。先找到win32k.sys模块地址
上图为win32k.sys函数
上图为win32u.dll其中的函数
这正是我们符合要求的一个函数 (当然这种函数还有很多很多...)
利用挂靠到一个GUI进程 比如 explorer.exe 替换对应的qword_677A8也就是data_ptr,里面存的就是NtUserQueryDisplayConfig函数原本的地址为了挂接 .data 函数指针,我们必须使用 InterlockedExchangePointer。这是一个原子函数,即一个不能被调度器中断的函数。我们为
什么需要它呢?这是一个全局指针,很可能被多个线程访问。我们必须进行同步操作以避免错误。IDA中Win32k.sys的a1就是通信传递数据的关键,只要3环传入一个结构体 0环接后处理 即可完成一个通信.
Ring3中只需要调用"NtUserQueryDisplayConfig(a1的数据结构体)" 即可.PVOID get_sys_module(UNICODE_STRING& name) {
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-285348.htm