吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 60025|回复: 556
收起左侧

[原创] PCXX逆向 --- 带自定义提示的PCXX防撤回

    [复制链接]
JieKeH 发表于 2019-5-17 10:31
本帖最后由 Kido 于 2019-6-6 18:09 编辑

带自定义提示的防撤回

1.前言

最近太忙了,一直没有时间更新这个文章.今天做点好玩的东西

在第一篇分析获取登录二维码的数据中,我们分析了登录过程中二维码的显示逻辑,现在我们分析下怎么实现带自定义提示的消息防撤回,实现的效果图就是如下所示

撤回显示

可以看到这人一直在辱骂我,哈哈哈

PC微信核心模块:wechatwin.dll (2.6.7.57版本)

相关工具:

  • windbg 或者 OD,x64dbg (动态调试工具)
  • IDA (静态分析)
  • vs2015(开发hook功能模块)

2.分析

大家知道ios/android/mac中都实现了防撤回,这些平台上的分析也是有相似之处,就是搜索"Revoke"的关键字进行分析,我们可以借鉴他们的思路,尝试从关键字"Revoke"入手,我们先脑中想一下整个撤回逻辑的实现

  • 对方在一个终端上发起一个撤回消息,服务端收到这个通知,下发消息给我方的所有终端
  • 我方所有的终端收到了服务端发来的撤回消息通知
  • 我方所有的终端实现撤回消息逻辑

可以看出,如果我们要实现防撤回逻辑,需要在第二步的网络数据层或者第三步的撤回逻辑实现层做点手脚,我们先搜索下关键字"Revoke"吧

Revoke

可以看到Revoke相当之多了, 初步可以认为上面标注的消息中可能存在我们需要查找的逻辑,通过调试确认,能发现 On RevokeMsg svrId : %d这个就是服务端发来的撤回消息通知,看下下图中相关的逻辑

ServerRevoke

可以看出来服务端对于撤回消息的定义是10002,上图中还标注了sub_10252f80这个函数,下面解释下为什么要标注这个函数

看看上图中对sub_10483FE0的汇编调用

 sub     esp, 14h              
 mov     ecx, esp;                
 push    0
 push    dword ptr [eax+4]
 call    sub_10483FE0

再看下sub_10483FE0函数的汇编

push    ebp
mov     ebp, esp
sub     esp, 8
push    esi
mov     esi, ecx
mov     ecx, [ebp+arg_0]
push    edi
mov     dword ptr [esi], 0
mov     dword ptr [esi+4], 0
mov     dword ptr [esi+8], 0
mov     dword ptr [esi+0Ch], 0
mov     dword ptr [esi+10h], 0

综合起来看,可以看出来

 sub     esp, 14h              
 mov     ecx, esp;
mov     esi, ecx
mov     ecx, [ebp+arg_0]
push    edi
mov     dword ptr [esi], 0
mov     dword ptr [esi+4], 0
mov     dword ptr [esi+8], 0
mov     dword ptr [esi+0Ch], 0
mov     dword ptr [esi+10h], 0

其实就是有两个含义

  • ecx此时是一个类的指针,这个类的内存布局大小是0x14

  • 类每个成员是4字节大小,共有5个成员

而且从sub_10483FE0函数中可以发现这是一个MultiByteToWideChar的操作,可以推断下这个类其实有点类似Wstring,那么对于下面的汇编函数来说,此时ecx是wstring, dword ptr [eax+4]是string(UTF-8)

 sub     esp, 14h              
 mov     ecx, esp;                
 push    0
 push    dword ptr [eax+4]
 call    sub_10483FE0

那将断点断在在call    sub_10483FE0上, 先记录下此时的ecx的值,等执行完call    sub_10483FE0,再dd刚才保存的ecx的值,下面用xxxxx打码了一些个人信息

0:000:x86> dd 00efcb20-14
00efcb0c  13f0e7f0 000000d6 00000100 00000000
00efcb1c  00000000 a6d44d71 00efee84 00efe484
00efcb2c  00000000 00000000 00000000 00000000
00efcb3c  00000000 00000000 00000000 00000000
00efcb4c  00000000 00000000 00000000 00000000
00efcb5c  00000000 00000000 00000000 00000000
00efcb6c  00000000 00000000 00000000 00000000
00efcb7c  00000000 00000000 00000000 00000000
0:000:x86> du 13f0e7f0 
13f0e7f0  "<sysmsg type="revokemsg"><revoke"
13f0e830  "msg><session>wxid_xxxxxxxxxxxxx"
13f0e870  "</session><msgid>1675514177</msg"
13f0e8b0  "id><newmsgid>2468247753633590716"
13f0e8f0  "</newmsgid><replacemsg><![CDATA["
13f0e930  ""xxxxxxx" 撤回了一条消息]]></replacemsg"
13f0e970  "></revokemsg></sysmsg>"

可以看到拿到了服务端的消息数据,注意其中的 xxxx 撤回了一条消息 这个和微信界面显示是一致的,那么可以知道微信其实提取了replacemsg里面的消息显示给界面

ida中搜索"replacemsg"这个字符串,可以发现sub_10257570中是唯一处理replacemsg的函数,并且可以找到一条sub_10252F80 -> sub_10257570 的调用链条,现在可以知道,sub_10252F80这个函数其实就是第三步的撤回逻辑实现层,下图是sub_10252F80的逻辑,一步步的跟下去,可以知道sub_10253250这个函数是逻辑实现层

逻辑实现层

下图是sub_10253250函数中的逻辑,经过调试后能发现,如果v69为0的时候,界面仍然会显示出来 xxx撤回了一条消息 , 但是实际上这条消息并没有被撤回,所以我们的思路很简单,Patch这块的代码,让它一直走else里面的逻辑即可

3.深入挖掘

到第二步其实已经就可以了,但是其实还是有一个问题的,你会发现,上面在阻止别人撤回的同时也阻止了自己的撤回,更糟糕的是,当自己发起撤回的时候,界面会弹出来两次 你撤回了一条消息 ,一开始其实还好了,自己用这个插件的时候倒是能接受,后来把这个插件给好友使用后,被一直吐槽,说体验很差,还有就是希望加上自定义的撤回提醒,吐槽的久了以后,那就进一步研究下,当自己发起撤回的时候,就不拦截这个撤回了

注意看下sub_10253250函数中下图的代码段, 其中v46是个结构体,sub_1004E320初始化这个结构,sub_1025A390是对这个结构体的赋值,v50是结构体中的成员,可以看到当v50为10000的时候,sub_10253250是什么事情也不做就退出了,这个结构体值得我们的关注,它里面的成员对sub_10253250的逻辑有很大的影响,调试观察下这个结构体的数据吧

将断点断在sub_1025A390执行后,直接能打印出来此时v46中的值,然后先让别人撤回一条消息,再自己撤回一条消息,可以看到两次v46内容的差异性

撤回对比

为啥使用这两个数据的作为差异比较呢,当自己撤回的时候,微信还提供重新编辑的功能,但是当别人撤回的时候,微信就直接撤回了,也就是说,微信其实是保存了是自己撤回还是别人撤回这个变量作为区分的

再看下sub_10253250函数中下图的代码段

查看sub_102541D0 -> sub_102542A0 的调用,在sub_102542A0中可以看出当a1为1的时候,会提供撤回编辑的能力,这个a1是 (_DWORD )(v7 + 52) != 0 赋值的 v7就是v46,也就是上图中的差异的位置

至此就找到了判断是别人撤回还是自己撤回的标志,解决了第一个问题,那下面还要解决第二个问题,那就是撤回消息的定制

既然sub_102542A0函数中提供了撤回编辑的能力,并且可以在sub_102542A0中看到下面的函数片段

对应的汇编操作

  • .text:102544A1 85 C0                                         test    eax, eax
    .text:102544A3 74 06                                         jz      short loc_102544AB
    .text:102544A5 66 83 38 00                                   cmp     word ptr [eax], 0
    .text:102544A9 75 05                                         jnz     short loc_102544B0

可以看出来这个是字符串拼接,a5就是需要被拼接的字符串.调试看下这个数据

Breakpoint 1 hit
WeChatWin!IMVQQEngine::`default constructor closure'+0x1a7121:
69a844a1 85c0            test    eax,eax
0:000:x86> du eax
0c073b08  ""xxx" 撤回了一条消息"

也就是说对a5进行修改就可以了,a5是sub_102542A0的参数,那么在sub_102541D0中看下a5的赋值

好了,只需要修改lpmem就行了.

4.工程实现

现在我们知道只需要hook住sub_102541D0,然后判断下撤回的来源

  1. 如果是别人撤回的,Patch掉sub_10253250的v69的逻辑,并且修改撤回的字符串消息为我们自定义消息
  2. 如果是自己的撤回,恢复sub_10253250的v69的逻辑

下图中SigPatternRevoke2_6_7_40是sub_102541D0函数头开始的特征码

下图是代{过}{滤}理函数的实现,注意修饰符__declspec(naked) 就是告诉编译器按照我们写的汇编代码生成代码,不要偷偷的再加入一些多余的汇编代码

解释下 上图 中间那段汇编push寄存器的来源, 首先是Push edx, 从下图中可以看到sub_102541D0中判断自己还是别人撤回的标志位是[exi+52],而esi来源于edx,故代{过}{滤}理函数需要的参数是edx寄存器

从上图中可以看到要修改的字符串是[ebp+8]的位置,而ebp又是

push  ebp
mov   ebp, esp

也就是说当断点断在 push ebp这个位置的时候,此时的[esp+4]就是字符串了, 而看下代码中的代{过}{滤}理函数

__asm
        {
                PUSHAD;
                sub esp, 20;
        }

其中 pushad会使得 esp-0x20(压了8个寄存器), 然后又 sub esp, 20(0x14), 所以代{过}{滤}理函数 esp + 0x14 + 0x20 + 4 的位置就是字符串了

剩下的RevokeMsg2_6_7_40函数就是比较简单了

  1. 需要注意下这个字符串使用的内存不是crt的堆,而是进程堆就可以了. 至于为啥这样,这里就当留个作业了,提示下sub_10484190函数内有答案
  2. PatchMemoryUCHAR中修改的就是sub_10253250的v69的逻辑

具体的工程实现就在上篇文章上增加而来,还是放到百度云盘了

网盘链接  提取码: 3964



重要提示:

  • 如果对代码工程感兴趣的,可以下载网盘的文件
  • 如果只是对二进制的bin文件有兴趣的,直接下载论坛的附件,解压后将version.dll放到微信的安装目录下就可以



如果二进制的bin文件替换后没有效果的,可以做下面的排查
  • 文件替换后,要重启微信才生效。
  • 目前支持的微信版本是 2.6.7.40 2.6.7.48 2.6.7.57,其余的微信版本是不支持的


做了上述的排查后还是没有生效的,可以查看下dbgview的log信息.回帖的时候可以截图或者上传log信息

如果发现微信异常或者功能异常的,也可截图回帖,感谢


2019/06/04 :增加2.6.8.51版本的支持


2.6.8.51.7z

576.24 KB, 阅读权限: 10, 下载次数: 909, 下载积分: 吾爱币 -1 CB

Version.zip

746.9 KB, 阅读权限: 10, 下载次数: 4161, 下载积分: 吾爱币 -1 CB

bin文件

点评

怎么新的版本,显示键盘记录木马?一直被拦截  发表于 2019-6-17 09:25

免费评分

参与人数 220吾爱币 +206 热心值 +203 收起 理由
萌萌哒胖次 + 1 + 1 用心讨论,共获提升!
正版大叔 + 1 + 1 谢谢@Thanks!
Rodge100 + 1 + 1 热心回复!
一杯小米酒 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
scry + 1 + 1 用心讨论,共获提升!
fanfan12121 + 1 谢谢@Thanks! 虽然没看懂
俗气 + 1 + 1 谢谢@Thanks!
e698j2 + 1 + 1 谢谢@Thanks!
fuckbin + 1 + 1 我很赞同!
Fa1sePRoMiSe + 1 + 1 用心讨论,共获提升!
永恒的未来 + 1 我很赞同!
wuxiaojie + 1 + 1 热心回复!
13235699629 + 1 + 1 用心讨论,共获提升!
Destiny007 + 1 谢谢@Thanks!
swebcc + 1 + 1 用心讨论,共获提升!
pinkly + 1 用心讨论,共获提升!
Brainor + 1 + 1 我很赞同!
懵逼猫咪 + 1 + 1 谢谢@Thanks!
ab10012358 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fu90 + 1 + 1 我很赞同!
XinChenK + 1 + 1 谢谢@Thanks!
Hiro_J + 1 + 1 谢谢@Thanks!
laohucai + 1 + 1 谢谢@Thanks!学到了很多知识。
VitaL + 1 谢谢@Thanks!
dd0373 + 1 谢谢@Thanks!
番茄炒西红柿1 + 1 + 1 我很赞同!
Cway + 1 谢谢@Thanks!
ProgramerFangL + 1 + 1 谢谢@Thanks!
cenvin + 1 + 1 热心回复!
zthinking + 1 + 1 用心讨论,共获提升!
左右1906 + 1 + 1 再出一个QQ的就很好了,这个好像不管用,还是撤回了
yangdl + 1 热心回复!
love514415 + 1 + 1 我很赞同!
yx13343795594 + 1 + 1 我很赞同! 有态度的防撤回
yhygwj + 1 + 1 谢谢@Thanks!
非恨丶 + 1 + 1 我很赞同!
fg676123 + 1 + 1 我很赞同!
vincener + 1 我很赞同!
purplewall + 1 我很赞同!
Adorable_Star + 1 谢谢@Thanks!
pengzhihua + 1 + 1 我很赞同!
hgd_icbc + 1 热心回复!
傻笑的老鼠 + 1 + 1 用心讨论,共获提升!
limit7 + 1 + 1 厉害了,佩服佩服
切惦红纯 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xulichen + 1 + 1 我很赞同!
媚眼的丹客 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yuanmo + 1 + 1 谢谢@Thanks!
zpp7 + 1 + 1 用心讨论,共获提升!
iret_52 + 1 + 1 这个有意思
秦先生 + 1 + 1 我很赞同!
aa849397558 + 1 + 1 手贱点了升级, 不管用了2.6.8.51
yixi + 1 + 1 谢谢@Thanks!
1188 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Poison丶biting + 1 + 1 谢谢@Thanks!
zmywsw + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xueya + 1 + 1 很不错的逆向文 不过我相信大多数是看不懂得 作者有时间出教学吗?
shidongjiao + 1 我很赞同!
Ailynhm + 1 我很赞同!
小木头堆 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
8901658 + 1 + 1 我很赞同!
胖维尼 + 1 + 1 用心讨论,共获提升!
Q4964 + 1 351#,萌新请教怎么知道防撤回由wechatwin.dll控制?
告别花季 + 1 谢谢@Thanks!
小疯子已经疯了 + 1 + 1 用心讨论,共获提升!
Uhn + 1 + 1 谢谢@Thanks!
梁萧 + 1 我很赞同!
azabual + 1 + 1 用心讨论,共获提升!
尘世迷途小书童 + 1 + 1 谢谢@Thanks!
池到了 + 1 + 1 谢谢@Thanks!
阿墨 + 1 谢谢@Thanks!
小粉B + 1 + 1 谢谢@Thanks!
tong_wen2504 + 1 谢谢@Thanks!
52pjShiron + 1 + 1 热心回复!
太空独角兽 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
风吹落叶飘 + 1 + 1 谢谢@Thanks!
xuanzuanmu + 1 + 1 热心回复!
55555555 + 1 + 1 厉害,可用
yj1049841 + 1 + 1 谢谢@Thanks!
LUCKandme + 1 用心讨论,共获提升!
心语科技 + 1 + 1 用心讨论,共获提升!
ukonw3477 + 1 + 1 热心回复!
靑葉 + 1 + 1 热心回复!
sllijingwei + 1 + 1 谢谢@Thanks!
sdysyhj + 1 + 1 谢谢@Thanks!
ImLee + 1 + 1 谢谢@Thanks!
a3607896 + 1 + 1 谢谢@Thanks!
Ai5 + 1 + 1 热心回复!
LaUstiN + 1 谢谢@Thanks!
linying0208 + 1 + 1 谢谢@Thanks!
Harvey丶 + 1 + 1 我很赞同!
seethesun + 1 + 1 我确实看不懂 感谢分享 码起收藏
beawes0me + 1 + 1 用心讨论,共获提升!
ipi0001 + 1 + 1 试过有效,感谢楼主!
杀猪用牛刀 + 1 + 1 谢谢@Thanks!
非法管理者 + 1 + 1 用心讨论,共获提升!
寒狼 + 1 + 1 好像还是需要配合防撤回多开版本,不然第二账号会失效
流云0202 + 1 + 1 我很赞同!
jakhu + 1 + 1 我很赞同!
冷笑丶小雨 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

Brainor 发表于 2019-9-3 19:32
本帖最后由 Brainor 于 2020-4-2 21:26 编辑

补一下更新
适用于2.6.8.68.
前面的版本可以使用的可能2.6.7.40, 2.6.7.48, 2.6.7.57, 2.6.8.51.
除了2.6.8.68, 这些版本的我都没试过, 都是在楼主代码中已经存在的~

另外, 有些版本可能我的电脑没有更新到, 那这个插件就不会对这些版本有用, 我相信大家都懂的哈~


update:
19.9.17: 适用于2.7.1.54
19.9.23: 适用于2.7.1.65
19.10.12: 适用于2.7.1.74
20.1.7: 适用于2.8.0.106
20.1.8: 适用于2.8.0.111
20.4.2: 适用于2.9.0.63

Version.zip

43.46 KB, 下载次数: 25, 下载积分: 吾爱币 -1 CB

2.9.0.63

免费评分

参与人数 4吾爱币 +4 热心值 +4 收起 理由
fushanpupil + 1 + 1 热心回复!
wenjg + 1 + 1 谢谢@Thanks!
XinChenK + 1 + 1 热心回复!
n1ghtc4t + 1 + 1 谢谢@Thanks!

查看全部评分

jiazhiyuan0325 发表于 2019-5-17 11:04
honda160 发表于 2019-5-17 11:29
JieKeH 发表于 2019-5-17 11:27
你的版本是对的嘛

2.6.7.57呀,百度盘上那3个全部覆盖到微信根目录了,微信也重启过了
XTo 发表于 2019-5-17 10:48
看看学习学习
kenny216 发表于 2019-5-17 10:56
楼主,下载下来的东西怎么用?能否做个程序。
zhaoladen 发表于 2019-5-17 10:59
学习学习
格鲁特 发表于 2019-5-17 11:00
没有傻瓜一键的那种吗?
小阿花 发表于 2019-5-17 11:06
看上去好有意思,很厉害的样子
unixcs 发表于 2019-5-17 11:16
好东西!!!
tankyle 发表于 2019-5-17 11:19
把version放进安装目录就可以了吗
但是测试了一下撤回的消息还是撤回了啊
zpzb 发表于 2019-5-17 11:23
比较详细的 说明,多谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-22 16:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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