微信PC端技术研究(2)-保存聊天语音

article/2025/10/9 17:44:35

微信PC端技术研究-保存聊天语音

转载地址:
[原创]微信PC端技术研究(2)-保存聊天语音-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com

0x0. 前言

最近又学习了某位大佬用CE的方法,大佬的一句话有点醍醐灌顶,然后有了新的感觉,然后开始尝试实践这篇文章。

自己总结一下CE用法的核心思路:通过各种技巧搜索找到内存中关键数据,然后结合动态调试找到操作数据的函数。

0x1. 了解CE

官网:https://www.cheatengine.org/

看看来自百科的介绍:

Cheat Engine 是一款内存修改编辑工具 ,它允许你修改你的游戏或软件内存数据,以得到一些其他功能。它包括16进制编辑,反汇编程序,内存查找工具。与同类修改工具相比,它具有强大的反汇编功能,且自身附带了外挂制作工具,可以用它直接生成外挂。

在我看来,CE做的最好的就是各种策略的内存搜索能力。

支持准确数据(整数、字符串、十六进制、浮点数、字节数组等等)搜索,针对目标数据明确效果显著,比如金币数。

支持数据范围的搜索,比如大于某个值,小于某个值等等。比如想找到没有显示数值的血量数据。

支持多组数据同时搜索,针对数据结构复杂的情况

支持搜索结果的多次过滤(图中框选的Next Scan),最终找到目标数据。比如血量未知时,通过加血、减血多次搜索最终找到血量地址。

说到底CE内存搜索的能力就是通过各种策略帮助你找到游戏中需要修改的数据(比如血量、分数、金币等等),然后通过内存修改能力(直接改血量)打破游戏平衡,外挂制作工具生成外挂,助你超神!

0x2. 分析

进入正题,本文是要拿到微信聊天的语音消息,然后dump保存下来。

要按以前我的思路,会通过网络通信找到接受消息的函数,然后找到语音数据,看起来很简单,但是有点难。

因为函数真的很多,网络消息也会受到很多干扰。

现在用CE了,应该怎么办呢?

找到关键数据

关键数据肯定是语音消息了,但是怎么搜索呢,肯定搜语音内容不现实,所以转了弯,先看看文字消息,找到接受文字消息处理函数之后,猜测语音处理函数会相同或者在不同分支。

接着,如何搜索文字消息呢?已经收到的显示在聊天窗口的内容当然可以通过CE找到,但是没用啊,它和接受文字消息处理函数已经没关系了,流程已经处理完成了。

那么在测试中肯定知道发送的消息内容,通过CE来搜索可以吗?

额,我觉得不行,还没收到消息呢,内存中也没有这个文字消息,搜索不到(如果可以,请大佬指点一下)。

能想到的是,在接受到消息某一点通过调试器断下来,然后CE搜索,这样可以,但是这个断点找不到阿,放弃。

那怎么办呢?

看到左侧聊天列表中显示的最新一条消息,有了新的思路。

每次收到新消息后,都会在列表中显示最新消息内容(图中绿框指示位置、注意是unicode字符)。

那么,先用CE(First Scan)搜索当前搜到的消息内容,找到可能的内存地址。多次接受不同消息后,Next Scan按钮搜索每次新的消息内容,最终确定聊天列表中显示的最新消息内容的内存地址。

多次刷选之后,留下两个地址,通过CE修改内容,在界面中查看是否改变,最终确认第二个地址就是我们的目标,暂把该地址记录为MsgAddr。

分析消息接收函数

关键数据地址已经找到,下面的工作复杂也不复杂,就看微信是如何实现的了。

猜测微信实现消息显示的流程是这样的:

recv收到消息,组装完整包后,分发给消息处理函数

根据wxid找到要显示消息的列表项,如果不在已聊天消息列表,就新建一个项

在列表中显示消息,如果是表情显示[文字],语音显示为[语音],消息插入wxid对应消息队列,或者存入数据库

步骤3中肯定要写前面找到的MsgAddr内存,把最新消息显示到界面中,这个流程肯定在消息处理函数内部。

So,通过OD对MsgAddr下内存写入断点,回溯堆栈就可以找到消息处理函数。

具体操作如下:

OD挂载Wechat.exe进程后,在左下角内存窗口处Ctrl+G,输入找到的MsgAddr(11A11F34)回车,定位到该数据,然后再HEX数据处,右键弹出菜单,选择断点->内存写入。

断点设置完成后,测试发送文字消息,OD断住,代码窗口显示的就是修改MsgAddr的代码位置,如上图10CE412C处。

Alt+K查看当前堆栈。

 

1

2

3

4

5

6

7

调用堆栈

地址       堆栈       函数过程 / 参数                       调用来自                      结构

0012E068   106BD6F3   WeChatWi.10CE4110                     WeChatWi.106BD6EE             0012E064 //wcsncpy

0012E088   106BD769   WeChatWi.106BD67E                     WeChatWi.106BD764             0012E084

0012E09C   1011DD8B   WeChatWi.106BD753                     WeChatWi.1011DD86             0012E098

0012E0EC   10206C67   包含WeChatWi.1011DD8B                   WeChatWi.10206C64             0012E0E8

0012E600   1020E8F1   ? WeChatWi.10206460                   WeChatWi.1020E8EC             0012E5FC //界面操作

看到这个调用栈是不是感觉好少,分析起来肯定简单。但,其实是OD显示的并不全,此时真的很想用windbg。

在OD的右下角堆栈窗口,可以看到当前调用栈的参数和预览数据。F8单步(或者Alt+F8执行到返回)逐步的回溯每层堆栈。关注MsgAddr的数据是如何生成的,也就是找到数据来源,然后找到消息处理函数。

 

跟踪过程不赘述(需要熟悉汇编知识),直到看到的最顶层的WeChatWi.10206460处,发现是把收到的消息内容显示到聊天列表处的一个界面功能函数。

那这里不是可以拿到消息了吗,是的,普通文字消息已经可以拿到,但是语音内容不行。

通过观察内存窗口的数据,整理WeChatWi.10206460处的关于消息参数的大致结构。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//聊天列表框信息

struct chat_list_msg {

DWORD unk;//

wstring wxid;//

//wchar_t* wxid;//4

//int len;//8

//int maxlen;//c

DWORD unk1;//10

DWORD unk2;//14

wstring name;

//wchar_t* name;//18微信名

//int len;//1c

//int maxlen;//20

wstring msg; //

//wchar_t* msg;//3c

//int len;//

//int maxlen;

}

wstring msg字段就是文字消息内容,而语音消息则是预览中看到的[语音]两字,并没有实际能够听到的语音数据,所以还得继续往前找。

 

继续往上回溯了3层左右,进入了102DDC50,找到了语音消息的新信息。

 

1

2

3

4

5

6

7

8

9

10

struct msg_xx

{

char unk[0x40];//

wstring wxid1;//40

wstring wxid2;//4c

char unk1[0x10];//58

wstring msg;//68

char unk2[0x10];//74

;//84

}

在wstring msg处就是普通文字消息内容,而语音消息并不是我想象的就是直接语音的数据,而是…如下:

1

<msg><voicemsg endflag="1" cancelflag="0" forwardflag="0" voiceformat="4" voicelength="1176" length="1334" bufid="147445261304397871" clientmsgid="416261363964373964444633636200230013013119fdd53b1f494102" fromusername="wxid_xxxxxxxxx" /></msg>

真是一波三折,还不是语音的数据,而是关于语音信息的xml,有语音的大小,来自谁,在语音缓冲区中的id(bufid)等等信息。

继续往前找呗,最后回溯到了所有消息处理的分发函数10323FF0中。这个函数处理逻辑很复杂,我并没有很快就找到如何生成语音消息的xml,以及处理语音数据的函数。

一度卡住,重复分析了很多次。

后来又回神想到了逆向神器IDA,xml中数据如voicemsg肯定是模块中会在代码中用到,看看有没有有用的信息。

用IDA打开Wechatwin.dll,shift+F12分析出所有字符串,Ctrl+F找到关键字voicemsg,看来有戏。

 

真的是柳暗花明又一村。

点击字符串跳到代码窗口,按下x,跳到引用该数据的位置。

找到了解析语音xml数据和解码语音数据的关键函数。

1

2

3

4

5

6

7

8

9

10

11

f_parseVoiceXmlInfo_103148E0

text:103149DD 0E4 0F 84 74 02 00 00                             jz      loc_10314C57

.text:103149E3 0E4 68 D0 06 F0 10                                push    offset aVoicemsg ; "voicemsg"

.text:103149E8 0E8 8B CF                                         mov     ecx, edi

.text:103149EA 0E8 E8 31 28 3E 00                                call    f_xml_subnode_106F7220

.text:103149EF 0E4 85 C0                                         test    eax, eax

.text:103149F1 0E4 0F 84 60 02 00 00                             jz      loc_10314C57

.text:103149F7 0E4 8D 70 2C                                      lea     esi, [eax+2Ch]

.text:103149FA 0E4 68 C4 06 F0 10                                push    offset aClientmsgid ; "clientmsgid"

.text:103149FF 0E8 8B CE                                         mov     ecx, esi

.text:10314A01 0E8 E8 CA 3A 3E 00                                call    f_xml_getvalue_106F84D0

函数103148E0解析xml拿到几个字段的内容,返回上层函数调用一个语音解码的函数进行处理,而这个解码函数就会直接操作语音数据。

1

2

3

4

5

6

7

(*(void (__thiscall **)(int *, _DWORD, _DWORD, int *, signed int))(*v7

                                                                            + 28))(//

             v7,

             *(_DWORD *)(voice_msg + 48),      // 语音内容

             *(_DWORD *)(voice_msg + 52),      // 语音长度

             v17,

             v4);

函数103148E0回溯再看看,进入了分发函数10323FF0中,在一个循环中处理了多种流程,包括显示界面最新消息的流程和解码语音的流程。所以前面找的方向并没有问题,只是缺少认真分析数据和代码的耐心。

不过,目的都达到了,找到了数据处理函数,最后通过hook这个函数就能拿到语音数据。

另外可以看到语音数据中包含SILK_V3的字符,这种编码音频格式是Skpye曾经使用的一种编码方式,后来开源了。目前播放器并不能直接播放该编码音频文件,所以需要转码为MP3等格式。不过可喜的是已经有大佬完成了这个工作,并开源了工具silk-v3-decoder。所以把代码拿来整合一下,就可以完整的实现实时dump语音聊天数据,转换为mp3进行保存,完美。

0x3. 总结

这是第一次比较成功的应用CE,整个看来,确实省下来很多定位数据和函数的工作。

但CE并不是万能的,要找对方法,找对目标数据才可能成功,对于某些没有明显数据的功能,可能也是无能为力。

最终还是得提高对大型软件的逆向能力,总体实现思路的猜测以及调试验证。

最后,时间仓促,目前只是将保存语音的demo更新到到SuperWeChatPC项目中,后续会持续更新,欢迎关注。

项目地址:GitHub - anhkgg/SuperWeChatPC: 超级微信电脑客户端,支持多开、防消息撤销、语音消息备份...开放WeChatSDK


http://chatgpt.dhexx.cn/article/FcfcWAQV.shtml

相关文章

将微信语音消息转换为 mp3

获取语音文件&#xff08;.silk&#xff09; 需要在电脑上实现。首先&#xff0c;查看你的微信 Mac 版本将数据存放在哪个目录下&#xff0c;我的是在这个目录下&#xff1a; /Users/henry/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.te…

WX Backup - 免费微信聊天记录备份导出与查看工具 (可提取图片/视频/语音)

微信绝对是一个让人爱恨交织的 APP&#xff0c;它在国内几乎完全占据了人们的社交以及生活的方方面面&#xff0c;但腾讯却并没有为微信提供好用的「聊天记录」备份导出和查看的功能。 WX Backup 是一款完全免费的微信聊天记录备份导出工具&#xff0c;支持 Windows 和 Mac&…

微信语音文件转换mp3

1、先找到手机里面的音频文件&#xff08;.amr&#xff09; 2、下载软件silk2mp3 ①双击silk2mp3.exe ②选择文件 ③开始转换 3、本来以为电脑客户端中也能找到相应的文件&#xff0c;但是发现是加密过的&#xff0c;不能用&#xff1b;所以只能使用android手机找到对应文件…

怎么导出微信语音【亲测有效】

在手机上长按你想导出的语音&#xff0c;点收藏 来到我的-收藏&#xff0c;打开刚才收藏语音&#xff0c;右上角三个点点&#xff0c;点转存为笔记 ok放下手机 来到pc端微信 - 收藏&#xff0c;找到刚才的笔记 进去&#xff0c;选中 - 右键 - 复制 发给你的文件传输助手 找到…

微信语音转换成mp3文件保存的简单详细步骤

目录 读者手册 一、前言 二、操作步骤一 把语音转化为silk文件&#xff08;silk后缀的文件&#xff09; 1.长按语音收藏&#xff08;手机操作&#xff09; 2.找到主页收藏 3.找到收藏的语音 4.转存为笔记 5.点击笔记里面的语音&#xff08;下面全部电脑操作&#xff0…

如何导出你的微信语音

苏生不惑第145 篇原创文章&#xff0c;将本公众号设为星标&#xff0c;第一时间看最新文章。 关于微信之前写过以下文章&#xff0c;有兴趣可以点击查看&#xff1a; 那些你可能不知道的微信奇技淫巧 那些你可能不知道的网络冷知识奇技淫巧 一个骚操作&#xff0c;公众号粉丝破…

简单3步:微信语音转成mp3

ACM亚洲区域赛获奖者 北漂女程序员 喜欢就关注我吧&#xff01; 在家人眼里&#xff0c;我学的专业就是打杂的。 前天我的嫂子问我怎么把微信聊天语音转换成mp3格式保存分享。 咔咔咔&#xff0c;教程来了。 1&#xff0c;把微信语音信息保存下来 2&#xff0c;找到微信语音信息…

在电脑上微信无法语音聊天,微信听不到语音声音

联想笔记本Windows11微信3.7.6.44 新更新的window系统&#xff0c;有线耳机在其他网页和应用上播放语音都是正常的&#xff0c;耳机肯定没坏&#xff0c;唯独在微信上无法播放语音和语音电话。 解决办法&#xff1a; 1、右击开始菜单&#xff0c;&#xff08;就是Windows开机…

一秒语音是什么软件,微信一秒语音包软件

微信一秒语音包软件是一款专为使用微信聊天的伙伴设计的&#xff0c;汇集了海量聊天语音包素材&#xff0c;并且可以实时更新语音包素材&#xff0c;所以的语音素材内容实时上线热门语音包&#xff0c;操作方法简单&#xff0c;拥有男声、女声等语音&#xff0c;还可以在这里制…

PHP代码审计二(通用代码审计思路)

总结一下在PHP代码审计中常用到的代码审计思路 文章目录 敏感函数逆向回溯参数过程espcms注入挖掘案例 通读全文代码根据功能点定向审计BugFree重装漏洞案例 敏感函数逆向回溯参数过程 根据敏感函数来逆向追踪参数的传递过程&#xff0c;是目前使用的最多的一种方式&#xff…

php代码审计实战(一)

前言:这套漏洞好水,为什么审他呢&#xff1f;原因是虽然一直挖漏洞 也用白盒摸出过不少洞,但是还没有彻彻底底的通审过一套系统 所以就找了套简单的摸摸鱼 源码:熊海CMS_1.0 安装方法:这里是用宝塔直接搭建的 ①数据库 需要宝塔建立一个数据库导入那个数据库文件就好了 然后…

PHP代码审计环境配置教程

PHP代审环境配置 1.vscode的配置2.PHPstudy配置3.使用xdebug调试代码 1.vscode的配置 安装插件 code runner PHP debug 2.PHPstudy配置 软件管理 — PHP设置 — 开启XDebug调试组件 开启XDebug调试组件之后&#xff0c;可以看到php.ini文件底部多了如下几行&#xff1a; [X…

PHP代码审计系列(一)

PHP代码审计系列&#xff08;一&#xff09; 本系列将收集多个PHP代码安全审计项目从易到难&#xff0c;并加入个人详细的源码解读。此系列将进行持续更新。 extract变量覆盖 源码如下 <?php$flagextractFlag.txt; extract($_GET);if(isset($shiyan)){ $contenttrim(f…

php代码审计学习-baijiacms v4

php代码审计学习&#xff08;baijiacms v4代码审计-system任意命令执行&#xff09; 文章目录 前言一、危险函数查找二、访问测试三、 构造 payload&#xff0c;触发漏洞总结 前言 最近及将来一段时间都会利用空闲的时间学习PHP代码审计 记录代码审计学习过程&#xff0c;最近…

PHP代码审计之基础篇

最近在学PHP代码审计&#xff0c;那就将学习的笔记都整理一遍吧~ 前期准备&#xff1a; 当然&#xff0c;最基本的前提是至少大致学过PHP的语法。 1、安装相关软件&#xff0c;如Sublime text、 Notepad、editplus、 Seay源代码审计系统等 2、获得源码&#xff0c;可以到网上…

PHP代码审计-2

Fortify扫出来个反序列化&#xff0c;来看看吧 PHP反序列化用到的函数无非就是unserialize()、serialize()在unserialize()前会先调用__wakeup()方法&#xff0c;再看看在__wakeup()在哪&#x1f447; 来看看 load() 这个函数是干啥的&#x1f447;再来看看 getSource() 这个函…

【PHP代码审计】ThinkPHP代码审计

目录 0x001 开发方式0x002 审计流程1&#xff09;启用调试开关2&#xff09;版本查看3&#xff09;定位函数4&#xff09;测试是否存在漏洞5&#xff09;版本自身漏洞 0x001 开发方式 在审计源码时根据不同的开发方式对应不同的审计方法。 自写&#xff1a;有的站点虽然使用了…

PHP代码审计敏感函数合集

PHP代码审计 通常去代码审计的时候基本是正则的挖掘思路 通常代码审计的话&#xff0c;大部分就是通过关键的函数&#xff0c;和关键的变量去审计 ​ ​ 敏感函数 PHP操作数据库函数 mysqli_connect() //建立与MySQL数据库的连接 mysqli_connect_errno() //判断连接数…

代码审计思路之PHP代码审计

000 前言 最近也是边挖src边审计代码&#xff0c;总结下最近的php代码审计的一些思路&#xff0c;我一般按照顺序往下做&#xff0c;限于能力水平&#xff0c;可能会有不对或者欠缺的地方&#xff0c;希望各位师傅能够指导。 001 前期工作,需要的工具&#xff08;我使用的) …

PHP代码审计 -- 文件上传

工具&环境 工具&#xff1a;Seay源代码审计系统&#xff0c;文本编辑器一个 环境&#xff1a;phpstudy&#xff0c;网站源码是 zbzcms步骤 1&#xff0c; 将zbzcms网站源码放入phpstudy&#xff0c;根据网站安装引导完成网站搭建&#xff1b; 2&#xff0c;打开Seay&…