2026/8/25 17:43:17

DMALibrary内核键盘监听揭秘:直接读取gafAsyncKeyState的原理与实现

DMALibrary内核键盘监听揭秘:直接读取gafAsyncKeyState的原理与实现 DMALibrary内核键盘监听揭秘直接读取gafAsyncKeyState的原理与实现【免费下载链接】DMALibrarySimple but extensive library for DMA users, made for gamehacking项目地址: https://gitcode.com/gh_mirrors/dm/DMALibraryDMALibrary 是一个简单而全面的 DMA 用户库为 gamehacking 场景而生。本文揭秘它的内核键盘监听实现不走任何操作系统 API而是通过 FPGA 直接从目标机器物理内存中读取 Windows 内核符号gafAsyncKeyState实时掌握按键状态。下面从原理、地址定位到核心代码逐层拆解。为什么要在 DMA 上做键盘监听传统键盘 HookSetWindowsHookEx、RegisterHotKey等依赖宿主系统软件层在 DMA 攻击架构中并不可靠攻击程序在独立主机上运行与目标机器的操作系统完全隔离。DMALibrary 的思路是绕过 OS 软件层直达内存 Windows 内核会把全部 256 个虚拟键的状态维护在一个位图数组中符号名就是gafAsyncKeyState⚡ 通过 DMAFPGA 直接物理内存读取把这个 64 字节数组原样搬回本地主机即可由于不经过目标系统的驱动与 API按键状态只读可见且天然具备抗干扰、低延迟的特性。该功能被封装为c_keys类源码位于 InputManager.cpp 与 InputManager.h并通过 Memory.h 的GetKeyboard()接口对外暴露。gafAsyncKeyState内核里的按键总开关gafAsyncKeyState是 Windows 图形内核win32k中的一个全局数组结构非常紧凑项目说明覆盖范围256 个虚拟键码VK Code每键占用2 bit可表达 up / down / 过渡等状态总大小256 × 2 bit 64 字节一次 64 字节的内核内存读取就能拿到此刻哪些键被按下的完整快照——这就是整个键盘监听功能的物理基础。地址定位新旧系统两条路径gafAsyncKeyState的宿主模块随 Windows 版本变化DMALibrary 在 InitKeyboard() 中做了完整的分版本适配。它先从目标机注册表读取CurrentBuild与UBR再分两条路径路径一老系统Build 22000——EAT / PDB 符号解析定位winlogon.exe进程读取其加载的win32kbase.sys导出表EAT直接查找gafAsyncKeyState导出若导出表中找不到则回退到PDB 符号表VMMDLL_PdbSymbolAddress解析出符号地址。路径二新系统Build ≥ 22000——csrss 会话结构偏移新版 Windows 把键盘相关逻辑放进了csrss.exe加载的win32ksgd.sys需要一次多级指针解引用链读取csrss.exe中 win32k 模块基址附近的g_session_global_slots结构偏移随版本变化0x3110/0x82538/0x82530解引用出user_session_state指针按版本加偏移得到gafAsyncKeyState例如0x383026100 高 UBR、0x3828/0x3820、0x36A8、0x3690等代码中维护了一张清晰的版本 → 偏移对照表。这正是 DMA 内存操作的典型难点偏移必须跟随微软每个构建号更新也是阅读源码时最值得关注的部分。核心实现64 字节内核读 2-bit 位图解析地址拿到后真正读键盘只有三行核心逻辑UpdateKeys()调用VMMDLL_MemReadEx带上VMMDLL_PID_PROCESS_WITH_KERNELMEMORY标志以VMMDLL_FLAG_NOCACHE直读目标机内核内存中的 64 字节位图每次读取后与上一帧对比记录新按下的键previous_state_bitmap判断某键是否按下时用 2-bit 位运算精确取位state_bitmap[(virtual_key_code * 2 / 8)] 1 (virtual_key_code % 4 * 2)此外IsKeyDown() 内置了100ms 节流DMA 读取有物理延迟节流既降低 FPGA 带宽占用也避免高频轮询。三步上手Example 项目的用法示例程序 Example.cpp 演示了完整流程——初始化 DMA、初始化内核键盘、等待用户按下A键mem.Init(explorer.exe, true, true); // 初始化 DMAFPGA vmm/leechcore mem.GetKeyboard()-InitKeyboard(); // 定位 gafAsyncKeyState 内核地址 while (!mem.GetKeyboard()-IsKeyDown(0x41)) // 等待按下 AVK_A 0x41 Sleep(100);配合内存读写、Scatter 批量读取、CR3 修复等功能IsKeyDown可以作为 DMA 程序的内核级热键开关完全不依赖目标系统软件层。总结这套方案的关键点✅原理简洁内核本身已维护 256 键状态位图DMA 只需照抄64 字节✅无感监听不注入、不 Hook、不经过目标 OS 驱动天然隐蔽且稳定⚠️维护成本在偏移表Windows 每次更新可能改变 win32k 模块结构与偏移升级目标系统时需同步维护版本对照表⚠️依赖内核读权限VMMDLL_PID_PROCESS_WITH_KERNELMEMORY要求底层 vmm/leechcore 具备目标机内核内存访问能力。想进一步阅读建议从 InputManager.cpp键盘核心与 Memory.cppDMA 初始化、c_keys对象的创建入手再看 vmmdll.h 了解底层内存读取 API 的完整能力。【免费下载链接】DMALibrarySimple but extensive library for DMA users, made for gamehacking项目地址: https://gitcode.com/gh_mirrors/dm/DMALibrary创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考