dwgx@blog:~$dwgx
> cd ../posts

DXSense 往第五人格进程里塞个 ImGui 调试面板

// created

DXSense 往第五人格进程里注入一个 DLL,用 Dear ImGui 在游戏里画一层调试 overlay,实时看进程内存、改数值、按帧盯渲染。第五人格是 DX11,拿它练手正合适。只在离线 demo 里玩,不碰在线对局,也别拿去干。项目 2026 年 4 月就停了,仓库留着当存档,下面是当时的笔记。

整个东西拆两半,一个被注入的 DLL,一个 injector。injector 走最朴素的路子:VirtualAllocEx 写路径,CreateRemoteThread 拉 LoadLibraryW,把 DXSense.dll 塞进去。DLL 进去之后几个点当时比较上心:

  • DllMain 里什么都别干,开个 boot 线程立刻 return。在 loader lock 里跑 DX11 初始化那套分分钟死锁,这坑踩一次就记住。
  • vtable 不硬编偏移。拿 message-only 的 HWND 建 dummy swapchain(D3D11CreateDeviceAndSwapChain),从真实 vtable 现扫 Present / ResizeBuffers,再用 MinHook 挂上去。硬编那张索引表,SDK 一升级就崩。
  • 输入走 WndProc 子类化。SetWindowLongPtrW 只换 swapchain 那个窗口,不用全局 SetWindowsHookEx,后者污染整个会话里每个窗口,太脏。
  • Hook 生命周期 RAII 管。全塞进一个 HookManager,teardown 时一次性撤,免得散落的 MH_* 漏 hook。
  • CRT 静态链接 /MT,躲开跟宿主进程 MSVC 运行时版本打架。

两个自己比较满意的地方。一个是 Procedure Fabric,那些长期运行的行为不想用一堆临时线程管,抽象成 Loom 加带类型的 Pin 加 Tick 流,engage/disengage 全声明式,开关一个行为很干净。另一个塞了个嵌入式 Python 桥,运行时能 peek / poke / call,不用改个地址就重编 DLL,直接在面板里写脚本试,调试快一截。

渲染后端那层抽象过 IRenderBackend,实际只把 DX11 做完了。INSERT 开关整个 overlay,依赖就 Dear ImGui(docking 分支)和 MinHook 两个。

代码 All Rights Reserved,公开只是给想学架构的人看思路:DLL 注入、Hook 生命周期、ImGui 集成、Procedure Fabric 这些 pattern。别拿去打在线对局对抗反作弊,别二次分发,别编成成品发出去,出事我不背。不维护,不修,不接 PR。想要类似的,kiero / GuidedHacking / MinHook 上游文档写得比我清楚,自己从头撸更靠谱。