表情包.png (108.05 KB, 下载次数: 5)
下载附件
2020-3-8 17:23 上传
我们看一下效果图,撤回的消息被我们看到了,相当于防(防止)撤回
view.png (89.04 KB, 下载次数: 11)
下载附件
2020-3-8 17:24 上传
好了,看完效果,接下来我们看一下怎么找到它的位置,并用代码hook它。
本文用到的软件工具:
用CE打开微信进程
ce_open.png (71.89 KB, 下载次数: 11)
下载附件
2020-3-8 17:25 上传
用另一个微信号给在电脑登录的微信号随机发一条消息,勾选UTF-16选项,然后在CE中搜索消息内容
ce_search.png (75.35 KB, 下载次数: 2)
下载附件
2020-3-8 17:24 上传
撤回消息,看到一条xml消息,双击它添加到地址列表
ce_xml.png (81.36 KB, 下载次数: 4)
下载附件
2020-3-8 17:24 上传
打开OD,附加微信进程,用dd命令定位到上面的那个地址
od_location.png (42.73 KB, 下载次数: 1)
下载附件
2020-3-8 17:25 上传
再给电脑登录那个微信号发一条消息,然后在上面那个地址下内存写入断点,再把消息撤回,此时断点被触发,微信被断下,断下后,删除内存断点。在堆栈里寻找我们想要的内容,看到一个包含撤回提示,wxid和撤回内容的call
wxid,tips,msg.png (60.5 KB, 下载次数: 3)
下载附件
2020-3-8 17:26 上传
在反汇编窗口中跟随这个call,点击这个call,按F2在该call下断点,按F9继续运行。再给在电脑登录那个微信号发一条消息并撤回,该call断下
call的汇编.png (30.73 KB, 下载次数: 3)
下载附件
2020-3-8 17:26 上传
说明,这个call就是我们要找的消息撤回的位置,而且它有我们想要的数据
找到时的堆栈.png (60.74 KB, 下载次数: 2)
下载附件
2020-3-8 17:29 上传
找到了call,来整理一下该call的数据,数据都是存在堆栈里,所以有:
接下来编写一个dll,来hook这个call。在VS创建一个dll项目,核心代码如下:
#include "resource.h"
#include "hook.h"
#include "module.h"
#include
INT_PTR CALLBACK Dlgproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DlgThread(HMODULE hInstance);
#define REVOCK_CALL_RVA 0x28c33f
#define REVOCK_CALL_TARGET_RVA 0x28ccd0
DWORD revockCallVA = 0;
DWORD revockCallTargetVA = 0;
DWORD revockCallJmpBackVA = 0;
DWORD wechatWinAddr = 0;
BYTE backCode[5];
HWND m_dialog_hwnd;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, LPTHREAD_START_ROUTINE(DlgThread), hModule, 0, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void OnRevock(DWORD esp) {
wchar_t *tips = *(wchar_t **)(esp + 0x4);
wchar_t *msg = *(wchar_t **)(esp + 0x78);
if (NULL != tips) {
WCHAR buffer[0x8192];
wchar_t* pos = wcsstr(tips, L"撤回了一条消息");
if (pos!= NULL && NULL != msg) {
swprintf_s(buffer, L"%s,内容:%s",tips, msg);
SetDlgItemText(m_dialog_hwnd, IDC_EDIT1, buffer);
}
}
}
DWORD tEsp = 0;
_declspec(naked) void _OnRevock() {
__asm {
mov tEsp, esp
pushad
}
OnRevock(tEsp);
__asm {
popad
call revockCallTargetVA
jmp revockCallJmpBackVA
}
}
void DlgThread(HMODULE hInstance) {
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);
}
INT_PTR CALLBACK Dlgproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_INITDIALOG: {
m_dialog_hwnd = hWnd;
wechatWinAddr = GetWxModuleAddress();
revockCallVA = wechatWinAddr + REVOCK_CALL_RVA;
revockCallTargetVA = wechatWinAddr + REVOCK_CALL_TARGET_RVA;
revockCallJmpBackVA = revockCallVA + 5;
StartHook5(wechatWinAddr+REVOCK_CALL_RVA,backCode,_OnRevock);
}
break;
case WM_CLOSE:
Unhook5(wechatWinAddr + REVOCK_CALL_RVA, backCode);
EndDialog(hWnd, TRUE);
break;
}
return 0;
}
代码写完后,生成dll,把它注入到微信进程,防撤回消息就能实现了。DLL和源码:https://www.lanzouj.com/ia8dmib
总结:微信版本一直会变化,相应的hook地址也会改变,但是有了这个思路,它更新版本,我们也能快速的找到call。这个消息撤回的call也比较好找,像我这样初学逆向的朋友可以尝试自己找一下。