1 |
|
背景
最近出于需求需要, 学习了一下微信逆向 wxhelper 的代码实现, wxhelper 暴露了大量的微信接口, 使得能够轻易基于此实现一个微信机器人 🤖️。因为是第一次接触逆向相关技术, 出于好奇就记录一下
实现原理
1 | |---------------- |
如上的流程图
- 首先需要通过一些手段获取到微信中需要被暴露的关键 Call, 作者把自己常用的方法记录在 wxhelper/wiki 文档, 感兴趣可以查阅
- 编译 wxhelper dll 程序注入到微信进程
- 该 dll 会创建一个端口为 19088 的 http server 向外提供接口来开放调用关键 Call 的能力
下面讲一下该 wxhelper dll 如何实现 hook 微信的关键 Call, 如下 dll 入口函数主要是调用了 GlobalContext::GetInstance().initialize 函数
1 | // src/dllMain.cc |
initialize 函数主要是启动了一个 http server
1 | // src/global_context.cc |
http server 的请求处理函数 HttpDispatch 即表示了向外提供的 hook 微信关键 Call 的实现。以 /api/hookSyncMsg 路径的请求为例, 如果客户端想通过调用该接口来监听微信收到消息的事件
1 | // src/http_server_callback.cc |
收到该请求后核心是调用了 wxhelper::hooks::HookSyncMsg 函数。可以发现 HookSyncMsg 函数中出现了关键的DetourAttach 系统调用
1 | // src/hooks.cc |
DetourAttach 是 Windows 平台上的一个函数,它是微软研究院开发的 Detours 库中的一部分。Detours 库提供了一种用于修改和重定向函数调用的技术,常用于实现函数的钩子和函数的动态修改。
DetourAttach 函数的作用是将一个目标函数的地址与一个自定义的回调函数关联起来,从而在目标函数被调用时执行回调函数。具体来说,DetourAttach 函数会修改目标函数的代码,使其在执行前调用指定的回调函数。DetourAttach 函数的原型如下:
1 | LONG DetourAttach(PVOID *ppPointer, PVOID pDetour); |
现在总算明白了, 原来是通过 DetourAttach 系统调用把微信收到消息的处理函数 R_DoAddMsg 给代理了, 也就是把 R_DoAddMsg 调用重定向为了 HandleSyncMsg, 而 HandleSyncMsg 函数里就可以写你的业务逻辑, 最后 HandleSyncMsg 的尾部调用一下微信的原始处理函数 R_DoAddMsg 即可
用 JavaScript 解释 DetourAttach 的行为就是
1 | const rawHandler = wx.R_DoAddMsg |
最后的一个关键点就是如何获取微信原本的处理函数 R_DoAddMsg 的地址, 可以看到 R_DoAddMsg 地址其实就是该 dll 的地址 GetWeChatWinBase() + 之前通过逆向手段获取到的该函数的偏移量 offset::kDoAddMsg
1 | // src/hooks.cc |
获取该 dll 的地址核心是 GetModuleHandleA 系统调用
1 | // src/utils.cc |
GetModuleHandleA 是 Windows 平台上的一个函数,用于获取指定模块的句柄(handle)。获取到的模块句柄可以用于后续的操作,例如获取模块中的函数地址、修改模块中的数据等。函数原型如下:
1 | HMODULE GetModuleHandleA(LPCSTR lpModuleName); |
至于如何获取关键 Call 的偏移量见上面提到的 wxhelper/wiki 文档