吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4655|回复: 136
上一主题 下一主题
收起左侧

[调试逆向] 微信逆向:防撤回消息分析

    [复制链接]
跳转到指定楼层
楼主
kn0sky 发表于 2024-7-24 10:13 回帖奖励
本帖最后由 kn0sky 于 2024-7-24 10:29 编辑

依然是从日志出发,可以结合前几篇文章一块看

  1. 微信逆向:hook 强制输出调试信息 - 『软件调试区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
  2. 微信逆向:定位功能调用(以文本消息发送为例) - 『软件调试区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
  3. 微信逆向:防多开检测原理和绕过 - 『软件调试区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

日志分析

从日志出发,清空日志,然后撤回消息,然后暂停打印新的日志,得到如下内容:(为了方便看,这里筛选出撤回相关的部分)

网络相关的略
21        2.319700        7932        WeChat.exe        (2024-7-10:10:14:12:657 25604)-i/SyncMgr:net scene sync Finish. sync id: 75, accumulation: 0, sync ccount: 1 
22        2.319873        7932        WeChat.exe        (2024-7-10:10:14:12:657 16196)-i/SyncMgr:start process cmdlist size : 1
23        2.319997        7932        WeChat.exe        (2024-7-10:10:14:12:657 16196)-i/SyncMgr:msg cmd count : 1
24        2.320204        7932        WeChat.exe        (2024-7-10:10:14:12:657 16196)-i/SyncMgr:doAddMsg srvid: 1454480870, msgtyp: 10002,cTime:1720577652,msgseq: 847233597 from : 用户1 to 用户2
25        2.320353        7932        WeChat.exe        (2024-7-10:10:14:12:657 16196)-i/SyncMgr:msg acctype 0 from user <NULL>
26        2.320499        7932        WeChat.exe        (2024-7-10:10:14:12:657 16196)-i/SyncMgr:Receive new xml : revokemsg

27        2.320652        7932        WeChat.exe        (2024-7-10:10:14:12:658 16196)-i/ChatRevokeMgr:rv 用户1 21907440767796979
28        2.321280        7932        WeChat.exe        (2024-7-10:10:14:12:658 16196)-i/SyncMgr:Update rv msg : 21907440767796979
29        2.321418        7932        WeChat.exe        (2024-7-10:10:14:12:658 16196)-i/ChatRevokeMgr:add or update rv msg : 21907440767796979 exist 1
30        2.321589        7932        WeChat.exe        (2024-7-10:10:14:12:659 16196)-i/MultiDBMsgMgr:DBName : MSG0.db Talker : 用户1, Id : 1
31        2.322783        7932        WeChat.exe        (2024-7-10:10:14:12:660 16196)-i/ChatMsgDeleteHelper:del msg attach id :21907440767796979 type 1 subtyp 0
34        2.323226        7932        WeChat.exe        (2024-7-10:10:14:12:660 16196)-i/ChatRevokeMgr:bIsSender 0, isTextType 1, reedit 0

35        2.323586        7932        WeChat.exe        (2024-7-10:10:14:12:660 25604)-i/ILinkTalkRoomMgr:getGroupVoipState, groupId 用户1 no banner, AllBannerCnt 0
36        2.323613        7932        WeChat.exe        (2024-7-10:10:14:12:660 16196)-i/MsgDBThreadWrapper:MyLaunch add task 18
37        2.323721        7932        WeChat.exe        (2024-7-10:10:14:12:661 25604)-i/SessionListItemUI:RefreshSessionGroipVoipStatus, name SYLPH status 0
38        2.323951        7932        WeChat.exe        (2024-7-10:10:14:12:661 10692)-i/MsgDBThreadWrapper:Task id 18 priority : 2 , wait time : 323 Micro Sec
39        2.323977        7932        WeChat.exe        (2024-7-10:10:14:12:661 16196)-i/ChatRevokeMgr:has msg 1 svrid 21907440767796979 subtype 0

差不多就筛成这样吧

这里有几条疑似的信息:

26        2.320499        7932        WeChat.exe        (2024-7-10:10:14:12:657 16196)-i/SyncMgr:Receive new xml : revokemsg
27        2.320652        7932        WeChat.exe        (2024-7-10:10:14:12:658 16196)-i/ChatRevokeMgr:rv 用户1 21907440767796979
28        2.321280        7932        WeChat.exe        (2024-7-10:10:14:12:658 16196)-i/SyncMgr:Update rv msg : 21907440767796979
29        2.321418        7932        WeChat.exe        (2024-7-10:10:14:12:658 16196)-i/ChatRevokeMgr:add or update rv msg : 21907440767796979 exist 1

伪代码分析

就从这几条信息入手,rv应该是revoke(撤回)的缩写,搜索字符串定位:Receive new xml:

      LOBYTE(v125) = 3;
      *((_QWORD *)&v125 + 1) = v21;
      v124 = *(_OWORD *)xmmword_184DED0B0;
      v123 = *(_OWORD *)xmmword_184DED0B0;
      v122 = *(_OWORD *)xmmword_184DED0B0;
      v121 = *(_OWORD *)xmmword_184DED0B0;
      v126[0] = *(_OWORD *)xmmword_184DED0B0;
      v22 = 2;
      log_message(
        2,
        (__int64)"D:\\Tools\\agent\\workspace\\MicroMsgWindowsV3911\\MicroMsgWin\\02_manager\\SyncMgr.cpp",
        3081,
        (__int64)"SyncMgr::GetNewXMLType",
        "SyncMgr",
        "Receive new xml : %s",
        &v125,
        v126,
        &v121,
        &v122,
        &v123,
        &v124);
      switch ( v3 )
      {
        case 7i64:
          v23 = 7i64;
          v24 = L"dynacfg";
          if ( *v21 >= 0x64u )
          {
            v25 = *v21 <= 0x64u;
            do
            {
              if ( !v25 )
                break;
              if ( v23 == 1 )
                goto LABEL_75;
              --v23;
              v26 = *(const wchar_t *)((char *)++v24 + (char *)v21 - (char *)L"dynacfg");
              v25 = v26 <= *v24;
            }
            while ( v26 >= *v24 );
          }
          goto LABEL_164;
        case 13i64:

这里是SyncMgr,同步消息的功能部分,GetNewXMLType应该意思是,同步消息通过xml结构进行,然后有很多类型,那么这个函数是判断出revoke msg的类型了

接下来往上一层追,判断出来类型了之后,应该就该执行操作了

  v30 = SyncMgr::GetNewXMLType(v56);
  if ( !(unsigned __int8)sub_182318F20(v30, v8, a2, a3) )
  {
    if ( v76 >= 0x10 )
    {
      v31 = Block[0];
      if ( v76 + 1 < 0x1000 || (v31 = (void *)*((_QWORD *)Block[0] - 1), (unsigned __int64)(Block[0] - v31 - 8) <= 0x1F) )
      {
        j_j_free_1_0(v31);
        return 0;
      }
LABEL_64:
      invalid_parameter_noinfo_noreturn();
    }
    return 0;
  }

这里紧接着是一个if条件,是bool类型的函数,用了刚才判断类型的返回值v30作为函数第一个参数,应该是根据类型进行不同的操作

进去看看,这个函数不长,就全部贴出来了:

char __fastcall SyncMgr::ProcessNewXMLMsg(int a1, __int64 a2, __int64 a3, _QWORD *a4)
{
  int v7; // ebx
  DWORD CurrentThreadId; // eax
  __int64 v9; // rdi
  char *v10; // rcx
  char *v11; // rdx
  __int64 v12; // rax
  _DWORD *v13; // rbx
  BOOL fPending[4]; // [rsp+60h] [rbp-78h] BYREF
  __int128 v16; // [rsp+70h] [rbp-68h] BYREF
  __int128 v17; // [rsp+80h] [rbp-58h] BYREF
  __int128 v18; // [rsp+90h] [rbp-48h] BYREF
  __int128 v19; // [rsp+A0h] [rbp-38h] BYREF
  __int128 v20; // [rsp+B0h] [rbp-28h] BYREF
  int v21; // [rsp+E0h] [rbp+8h] BYREF

  v21 = a1;
  v7 = dword_18590BCE4;
  CurrentThreadId = GetCurrentThreadId();
  v9 = v21;
  if ( CurrentThreadId == v7 )
    goto LABEL_12;
  if ( !InitOnceBeginInitialize(&stru_18593DE80, 0, fPending, 0i64) )
    goto LABEL_21;
  if ( fPending[0] )
  {
    v10 = (char *)off_185756C40;
    v11 = (char *)off_185756C40 + 56;
    if ( off_185756C40 != (char *)off_185756C40 + 56 )
    {
      do
      {
        dword_18593DDE0[*(int *)v10] = 1;
        v10 += 4;
      }
      while ( v10 != v11 );
    }
    if ( !InitOnceComplete(&stru_18593DE80, 0, 0i64) )
LABEL_21:
      abort();
  }
  if ( dword_18593DDE0[v9] != 1 )
  {
LABEL_12:
    switch ( (_DWORD)v9 )
    {
      case 4:
        return sub_182300AE0(a2, a3, a4);       // 撤回
      case 0x21:
        sub_182301380(a2, a3, a4);
        break;
      case 0x24:
        sub_182301A90(a2, a3, a4);
        return 0;
      default:
        if ( (unsigned __int8)sub_182319190((unsigned int)v9, a2, a3) )
          return 1;
        break;
    }
    return 0;
  }
  LOBYTE(v16) = 0;
  *((_QWORD *)&v16 + 1) = v9;
  v12 = *(_QWORD *)(a3 + 48);
  LOBYTE(v17) = 0;
  *((_QWORD *)&v17 + 1) = v12;
  *(_OWORD *)fPending = *(_OWORD *)xmmword_184DED0B0;
  v18 = *(_OWORD *)xmmword_184DED0B0;
  v19 = *(_OWORD *)xmmword_184DED0B0;
  v20 = *(_OWORD *)xmmword_184DED0B0;
  log_message(
    2,
    (__int64)"D:\\Tools\\agent\\workspace\\MicroMsgWindowsV3911\\MicroMsgWin\\02_manager\\SyncMgr.cpp",
    3550,
    (__int64)"SyncMgr::ProcessNewXMLMsg",
    "SyncMgr",
    "id %d xml type %d delay",
    &v17,
    &v16,
    &v20,
    &v19,
    &v18,
    (__int128 *)fPending);
  v13 = (_DWORD *)a4[8];
  if ( v13 == (_DWORD *)a4[9] )
  {
    sub_18231F080((_DWORD)a4 + 56, (_DWORD)v13, (unsigned int)&v21, a2, a3);
  }
  else
  {
    *(_QWORD *)fPending = a4[8];
    *v13 = v9;
    sub_183234350(v13 + 2, a2);
    sub_181B70FD0((__int64)(v13 + 26), a3);
    a4[8] += 1208i64;
  }
  return 0;
}

最先出现自定义函数调用的地方是switch-case语句那里,刚刚分析出来这里参数1是类型,看看参数1的传递:

char __fastcall SyncMgr::ProcessNewXMLMsg(int a1, __int64 a2, __int64 a3, _QWORD *a4)

  v21 = a1;

  v9 = v21;

    switch ( (_DWORD)v9 )

刚好就是这个switch-case语句的条件,所以处理就在这里

接下来就有2种方法定位撤回消息是哪个分支:

  1. 动态调试下断点,看撤回断下的时候这个函数开头rcx是多少
  2. 静态分析,依次点进去看看,哪个函数调用出现了刚刚见过的日志

动调的话,可以看到此时该类型值为4,进入第一个函数分支

静态分析的话,在该函数内部可以看到如下日志打印参数:

              log_message(
                2,
                (__int64)"D:\\Tools\\agent\\workspace\\MicroMsgWindowsV3911\\MicroMsgWin\\02_manager\\ChatRevokeMgr.cpp",
                377,
                (__int64)"ChatRevokeMgr::AddOrUpdateRevokeMsg",
                "ChatRevokeMgr",
                "add or update rv msg : %d exist %d",
                (__int128 *)v39,
                (__int128 *)v38,
                (__int128 *)v40,
                (__int128 *)v41,
                (__int128 *)v42,
                (__int128 *)v43);

格式符合刚刚接下来会出现的日志的样子

基本上这就是撤回操作的函数了

防撤回(核心代码)

知道撤回的逻辑了,接下来防撤回就很简单了

理一下这块的逻辑:

  1. 判断收到的同步消息xml类型
  2. 根据xml类型进行不同的处理

分析返回值发现,这个case分支的撤回函数的返回值是0

那么这里只需要在根据xml类型进行不同处理的函数这里进行hook,如果参数1为4,就直接返回0,即可

核心代码:

#include "pch.h"
#include "selHook_ProcessNewXMLMsg.h"

_ProcessNewXMLMsg fProcessNewXMLMsg;

char __fastcall MyProcessNewXMLMsg(
        int a1,
        __int64 a2,
        __int64 a3,
        __int64* a4
) {
        if (a1 == 4) {
                return 0;
        }
        return fProcessNewXMLMsg(a1, a2, a3, a4);
}

效果演示:

参考资料:

免费评分

参与人数 52吾爱币 +54 热心值 +46 收起 理由
heart1broken + 1 + 1 谢谢@Thanks!
dexiuxiu95 + 1 用心讨论,共获提升!
dszsu + 1 + 1 用心讨论,共获提升!
boybubble + 1 + 1 谢谢@Thanks!
willJ + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
TLPG + 1 + 1 用心讨论,共获提升!牛的牛的
13279828856 + 1 + 1 谢谢@Thanks!
kgdwfn + 1 我很赞同!
503514256 + 1 + 1 谢谢@Thanks!
lxserver + 1 + 1 我很赞同!
markhoo911 + 1 用心讨论,共获提升!
liuzhg + 1 + 1 我很赞同!
gezhonglunta + 1 + 1 谢谢@Thanks!
yhfQ + 1 我很赞同!
Shuigutou7 + 1 + 1 谢谢@Thanks!
shuoguoleilei + 1 + 1 我很赞同!
Muyu233 + 1 我很赞同!
hackgod + 1 + 1 热心回复!
Haoyua + 1 用心讨论,共获提升!
magine1995 + 1 谢谢@Thanks!
wumingyu2001 + 1 谢谢@Thanks!
2322 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
retiree + 1 + 1 谢谢@Thanks!
zerozaki1024 + 1 + 1 用心讨论,共获提升!
crizquan + 1 + 1 我很赞同!
lalicorne + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xiaofu666 + 1 + 1 热心回复!
angelabebe + 1 + 1 热心回复!
x410823 + 1 + 1 谢谢@Thanks!
Zalle + 1 + 1 用心讨论,共获提升!
Zhongyul + 1 谢谢@Thanks!
allspark + 1 + 1 用心讨论,共获提升!
kaowuzei7 + 1 我很赞同!
AuroraVerses + 1 谢谢@Thanks!
taoyaning + 1 我很赞同!
211aaa + 1 + 1 用心讨论,共获提升!
CcC147 + 1 + 1 我很赞同!
datalai + 1 我很赞同!
hazy1k + 1 + 1 我很赞同!
HLNM + 1 用心讨论,共获提升!
ly2582525775 + 1 + 1 用心讨论,共获提升!
6699PJ + 1 + 1 用心讨论,共获提升!
zoomzoomblood + 1 用心讨论,共获提升!
SKZD + 1 + 1 我很赞同!
kjzl5290 + 1 + 1 用心讨论,共获提升!
Wang886 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
qingyin123 + 1 + 1 热心回复!
Night1918 + 1 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 谢谢@Thanks!
JUNWO999 + 1 + 1 谢谢@Thanks!
myfunction + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
Redbell 发表于 2024-7-24 10:37

比如以前对撤回的信息高亮显示之类的,然后如果有直接使用的方式,例如“编译升级”,对自己的微信改造
推荐
voop 发表于 2024-7-26 02:21
理论上因为(个人所有权)你可以去修改微信让它防撤回,当然理论上微信也可以因为这个(最终用户协议,就是一开始你点了同意那个)封禁账号。
3#
xiaohali 发表于 2024-7-24 10:19
4#
Xiaosesi 发表于 2024-7-24 10:21
其他端的Receive new xml代码也是如此嘛
5#
 楼主| kn0sky 发表于 2024-7-24 10:31 |楼主

这一篇主要是静态分析,动态用的x64dbg
6#
Redbell 发表于 2024-7-24 10:32
虽然是有参考资料的,但也很厉害了...
所以可以自己篡改一下么?有什么可行操作么
7#
 楼主| kn0sky 发表于 2024-7-24 10:33 |楼主
Redbell 发表于 2024-7-24 10:32
虽然是有参考资料的,但也很厉害了...
所以可以自己篡改一下么?有什么可行操作么

你想改什么呢
8#
 楼主| kn0sky 发表于 2024-7-24 10:41 |楼主
Redbell 发表于 2024-7-24 10:37
比如以前对撤回的信息高亮显示之类的,然后如果有直接使用的方式,例如“编译升级”,对自己的微信改造

这不是改跳转防撤回,而是直接hook了撤回的call了,想怎么改,可操作空间很大的
9#
Redbell 发表于 2024-7-24 10:50
kn0sky 发表于 2024-7-24 10:41
这不是改跳转防撤回,而是直接hook了撤回的call了,想怎么改,可操作空间很大的

我其实还是想实操,比如不光是分析,而是拿这个apk直接实操成自己改造之后的,虽然可能会通不过安全校验
10#
Koriki 发表于 2024-7-24 11:06
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-9-8 07:05

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表