Windows 版微信防撤回
公司相关的微信群太多了,导致经常会有人错发消息,出于对撤回内容的好奇下,最近研究了下如何防撤回,微信撤回消息相关函数实现在 WeChatWin.dll 中,我的想法是要么 hook 相关函数,或者直接改 WeChatWin.dll 的指令逻辑,后者实现起来简单点,就先尝试下。
首先电脑端先登录微信,然后打开 x32dbg,在菜单里找到「文件」 > 「附加」,附加窗口中找到「wechat」,然后附加上去。
接着在菜单「视图」 > 「模块」,找到加载的 WeChatWin.dll,并双击。
在 WeChatWin.dll 的反汇编窗口中点右键,选择「搜索」 > 「当前模块」 > 「字符串」,搜索“revokemsg”,此时会列出一堆搜索结果,需要去逐个甄别哪个才是真正的函数调用,最后我发现字符串是「"revokemsg"」(注意有双引号)的才是函数调用,其它什么“L”开头的、“<revokemsg>”均不是。双击它,看到的关键汇编代码如下:
69F8B0F2 | 32DB | xor bl,bl | 循环开始 69F8B0F4 | 8B45 94 | mov eax,dword ptr ss:[ebp-6C] | 69F8B0F7 | C785 60FFFFFF 30E31F6B | mov dword ptr ss:[ebp-A0],wechatwin.6B1 | 69F8B101 | 3D C07C526B | cmp eax,wechatwin.6B527CC0 | 69F8B106 | 74 09 | je wechatwin.69F8B111 | 69F8B108 | 50 | push eax | 69F8B109 | E8 64E8BB00 | call wechatwin.6AB49972 | 69F8B10E | 83C4 04 | add esp,4 | 69F8B111 | 8D8D 60FFFFFF | lea ecx,dword ptr ss:[ebp-A0] | 69F8B117 | E8 44496F00 | call wechatwin.6A67FA60 | 69F8B11C | 8D4D C0 | lea ecx,dword ptr ss:[ebp-40] | 69F8B11F | E8 0C932800 | call wechatwin.6A214430 | 69F8B124 | 8D4D 08 | lea ecx,dword ptr ss:[ebp+8] | 69F8B127 | E8 04932800 | call wechatwin.6A214430 | 69F8B12C | 8AC3 | mov al,bl | 69F8B12E | 8B4D F4 | mov ecx,dword ptr ss:[ebp-C] | 69F8B131 | 64:890D 00000000 | mov dword ptr fs:[0],ecx | 69F8B138 | 59 | pop ecx | 69F8B139 | 5F | pop edi | 69F8B13A | 5E | pop esi | 69F8B13B | 5B | pop ebx | 69F8B13C | 8B4D F0 | mov ecx,dword ptr ss:[ebp-10] | 69F8B13F | 33CD | xor ecx,ebp | 69F8B141 | E8 7EE4BB00 | call wechatwin.6AB495C4 | 69F8B146 | 8BE5 | mov esp,ebp | 69F8B148 | 5D | pop ebp | 69F8B149 | C3 | ret | 69F8B14A | 8B06 | mov eax,dword ptr ds:[esi] | 69F8B14C | 8BCE | mov ecx,esi | 69F8B14E | FF50 18 | call dword ptr ds:[eax+18] | 69F8B151 | 85C0 | test eax,eax | 判断是否有撤回 69F8B153 | 74 9D | je wechatwin.69F8B0F2 | 这里是个循环,如果没有撤回消息,控制流就跳到循环开始处,否则就继续向下执行 69F8B155 | 68 DCBF266B | push wechatwin.6B26BFDC | 6B26BFDC:"revokemsg" 69F8B15A | 8BC8 | mov ecx,eax | 69F8B15C | E8 DF4B6F00 | call wechatwin.6A67FD40 | 调用消息撤回函数
把这段理解成一个循环判断是否有撤回消息,着手点在这一段代码上:
call dword ptr ds:[eax+18] test eax,eax je wechatwin.69F8B0F2 push wechatwin.6B26BFDC mov ecx,eax call wechatwin.6A67FD40
为了不让调用到最后句撤回消息函数,有两个选择:
1、把 je 指令改成 jmp,让指令永远跳不到最后一句 call 指令;
2、把最后句 call 指令用 nop 替换掉。
相比之下我觉得修改 je 指令稳妥点,选中 je 指令那行,点右键,选择「汇编」,把 je 改为 jmp,然后勾选「保持大小」和「剩余字节以 NOP 填充」。
最后点右键,选中「补丁」,补丁窗口中会列出修改的内容,确认无误后点「修补文件」,把导出补丁后的 WeChatWin.dll 放到微信目录下覆盖原本的即可。