微信PC端各个数据库文件结构与功能简述 - Multi文件夹
异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复;本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告。本人所有文章仅在CSDN、掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是盗文!
相关内容:
- 微信PC端数据库文件解密_微信电脑版db文件解密_异想之旅的博客-CSDN博客
- 微信PC端各个数据库文件结构与功能简述 - 根目录_微信用了哪些数据库_异想之旅的博客-CSDN博客
Multi
文件夹中的文件解码和之前的其它数据库操作相同。
该文件夹中文件结构比较简单,只有三种:FTSMSG
、MediaMSG
和MSG
。这里说是三种不是三个,是因为这里的数据库达到一定大小后会拆分。
FTSMSG
看过《总述》一文的应该很熟悉 FTS 这一前缀了——这代表的是搜索时所需的索引。
其内主要的内容是这样的两张表:
- FTSChatMsg2_content:内有三个字段
- docid:从1开始递增的数字,相当于当前条目的 ID
- c0content:搜索关键字(在微信搜索框输入的关键字被这个字段包含的内容可以被搜索到)
- c1entityId:尚不明确用途,可能是校验相关
- FTSChatMsg2_MetaData
- docid:与
FTSChatMsg2_content
表中的 docid 对应 - msgId:与
MSG
数据库中的内容对应 - entityId:与
FTSChatMsg2_content
表中的 c1entityId 对应 - type:可能是该消息的类型
- 其余字段尚不明确
- docid:与
特别地,表名中的这个数字2,个人猜测可能是当前数据库格式的版本号。
MediaMSG
这里存储了所有的语音消息。数据库中有且仅有Media
一张表,内含三个有效字段:
- Key
- Reserved0
- Buf
其中Reserved0
字段与MSG
数据库中消息的MsgSvrID
一一对应。
第三项即语音的二进制数据,观察头部即可发现这些文件是以 SILK 格式存储的。这是一种微软为 Skype 开发并开源的语音格式,具体可以自行 Google。
下面是将 Buf 字段中的数据导出为文件的代码:
import sqlite3def writeTofile(data, filename):with open(filename, 'wb') as file:file.write(data)print("Stored blob data into: ", filename, "\n")def readBlobData(key):try:sqliteConnection = sqlite3.connect('dbs/decoded_MediaMSG0.db')cursor = sqliteConnection.cursor()print("Connected to SQLite")sql_fetch_blob_query = """SELECT * from Media where Key = ?"""cursor.execute(sql_fetch_blob_query, (key, ))record = cursor.fetchall()for row in record:print("Key = ", row[0], "Reserved0 = ", row[1])file = row[2]print("Storing on disk \n")path = f'{row[0]}.silk'writeTofile(file, path)cursor.close()except sqlite3.Error as error:print("Failed to read blob data from sqlite table", error)finally:if sqliteConnection:sqliteConnection.close()print("sqlite connection is closed")readBlobData(1099511630953)
如果需要通过MSG
数据库中的MsgSvrID
找文件,则改一下 SQL 查询语句,再遍历所有数据库即可。
下面是将 silk 文件转为 wav 的代码(实现思路是先转为 pcm 再转 wav;wav 的采样率数据是个人试出来的):
KEY = 1099511630953import wave
from pathlib import Pathimport pilkdef pcm2wav(pcm_file, wav_file, channels=1, bits=16, sample_rate=24000):pcmf = open(pcm_file, 'rb')pcmdata = pcmf.read()pcmf.close()if bits % 8 != 0:raise ValueError("bits % 8 must == 0. now bits:" + str(bits))wavfile = wave.open(wav_file, 'wb')wavfile.setnchannels(channels)wavfile.setsampwidth(bits // 8)wavfile.setframerate(sample_rate)wavfile.writeframes(pcmdata)wavfile.close()duration = pilk.decode(f"{KEY}.silk", f"{KEY}.pcm")
# print("语音时间为:", duration)
Path(f"{KEY}.silk").unlink()pcm2wav(f"{KEY}.pcm", f"{KEY}.wav")
Path(f"{KEY}.pcm").unlink()
这两个代码没有加详细解释,自己读一下吧。
MSG
终于到了整个文件,不,整个工程最重要的位置了——聊天记录核心数据库!
内部主要的两个表是MSG
和Name2ID
。
其中Name2ID
这张表只有一列,内容格式是微信号
或群聊ID@chatroom
,作用是使MSG
中的某些字段与之对应。虽然表中没有 ID 这一列,但事实上微信默认了第几行 ID 就是几(从1开始编号)。
下面主要来说MSG
这张表(加粗是用于提醒自己内容待补充,并非是重要信息):
- localId:字面意思消息在本地的 ID,暂未发现其功用
- TalkerId:消息所在房间的 ID(该信息为猜测,猜测原因见 StrTalker 字段),与
Name2ID
对应。 - MsgSvrID:猜测 Srv 可能是 Server 的缩写,代指服务器端存储的消息 ID
- Type:消息类型,具体对照见表1
- SubType:消息类型子分类,暂时未见其实际用途
- IsSender:是否是自己发出的消息,也就是标记消息展示在对话页左边还是右边,取值0或1
- CreateTime:消息创建时间的秒级时间戳。此处需要进一步实验来确认该时间具体标记的是哪个时间节点,个人猜测的规则如下:
- 从这台电脑上发出的消息:标记代表的是每个消息点下发送按钮的那一刻
- 从其它设备上发出的/收到的来自其它用户的消息:标记的是本地从服务器接收到这一消息的时间
- Sequence:次序,虽然看起来像一个毫秒级时间戳但其实不是。这是 CreateTime 字段末尾接上三位数字组成的,通常情况下为000,如果在出现两条 CreateTime 相同的消息则最后三位依次递增。需要进一步确认不重复范围是在一个会话内还是所有会话。
- StatusEx、FlagEx、Status、MsgServerSeq、MsgSequence:这五个字段个人暂时没有分析出有效信息
- StrTalker:消息发送者的微信号。特别说明,从这里来看的话,上面的 TalkerId 字段大概率是指的消息所在的房间ID,而非发送者ID,当然也可能和 TalkerId 属于重复内容,这一点待确认。
- StrContent:字符串格式的数据。特别说明的是,除了文本类型的消息外,别的大多类型这一字段都会是一段 XML 数据标记一些相关信息。
- DisplayContent:对于拍一拍,保存拍者和被拍者账号信息
- Reserved0~6:这些字段也还没有分析出有效信息,也有的字段恒为空
- CompressContent:字面意思是压缩的数据,实际上也就是微信任性不想存在 StrContent 里的数据在这里(例如带有引用的文本消息等;这里的消息只能根据二进制分辨出包含什么,但是具体格式规范、如何取出数据本人不知)
- BytesExtra:额外的二进制格式数据
- BytesTrans:目前看这是一个恒为空的字段
这里面的猜测内容比较多,还有很多标注了应该进一步实验的还没有完成,是因为由于数据库解开后不可能随新收到的消息实时更新,而每次新发送一条消息也不知道它会出现在拆分后的哪个数据库中,因此实验效率极低。
表1:MSG.Type
字段数值与含义对照表(可能可以扩展到其它数据库中同样标记消息类型这一信息的字段)
分类 | 子分类 | 对应类型 |
---|---|---|
1 | 0 | 文本 |
3 | 0 | 图片 |
34 | 0 | 语音 |
43 | 0 | 视频 |
47 | 0 | 动画表情(第三方开发的表情包) |
49 | 1 | 类似文字消息而不一样的消息,目前只见到一个阿里云盘的邀请注册是这样的。估计和 57 子类的情况一样 |
49 | 5 | 卡片式链接,CompressContent 中有标题、简介等,BytesExtra 中有本地缓存的封面路径 |
49 | 6 | 文件,CompressContent 中有文件名和下载链接(但不会读),BytesExtra 中有本地保存的路径 |
49 | 8 | 用户上传的 GIF 表情,CompressContent 中有 CDN 链接,不过似乎不能直接访问下载 |
49 | 19 | 合并转发的聊天记录,CompressContent 中有详细聊天记录,BytesExtra 中有图片视频等的缓存 |
49 | 33/36 | 分享的小程序,CompressContent 中有卡片信息,BytesExtra 中有封面缓存位置 |
49 | 57 | 带有引用的文本消息(这种类型下 StrContent 为空,发送和引用的内容均在 CompressContent 中) |
49 | 63 | 视频号直播或直播回放等 |
49 | 87 | 群公告 |
49 | 88 | 视频号直播或直播回放等 |
49 | 2000 | 转账消息(包括发出、接收、主动退还) |
49 | 2003 | 赠送红包封面 |
10000 | 0 | 系统通知(居中出现的那种灰色文字) |
10000 | 4 | 拍一拍 |
10000 | 8000 | 系统通知(特别包含你邀请别人加入群聊) |
本文参考资料(排名不分先后):
- python使用技巧(二十七):音频WAV和PCM的互相转换_python pcm转mp3_源代码杀手的博客-CSDN博客
- foyoux/pilk: python silk codec binding 支持微信语音编解码
微信PC端各个数据库文件结构与功能简述 - Multi文件夹相关推荐
- 微信PC端各个数据库文件结构与功能简述 - 根目录
异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复:本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告.本人所有文章仅在CSDN.掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是 ...
- 微信PC端数据库文件解密
异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复:本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告.本人所有文章仅在CSDN.掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是 ...
- 使用微信PC端的截图dll库实现微信截图功能(C++ Builder实现)
使用微信PC端的截图dll库实现微信截图功能(C++ Builder实现) 网上有很多文章说"使用微信PC端的截图dll库实现微信截图功能",我用node实现截图也要用一下,于是找 ...
- 微信PC端有了新功能,快来看看你知不知道
你们知道微信PC端更新了吗?它新增了几个功能,有兴趣了解的朋友就接着往下看吧. 1.文件路径更清晰 微信之前的文件存储路径,都是一串乱码的文件夹,不便于我们查找和管理. 微信更新后,现在接收到的文件路 ...
- 微信PC端技术研究(2)-拿下语音
微信PC端技术研究-保存聊天语音 by anhkgg(公众号:汉客儿) 2019年1月31日 2.6.6.28 0x0. 前言 虽然一直知道CE,也用过一段时间,但一直用不好,可能太笨. 最近又学习了 ...
- 微信PC端技术研究(2)-保存聊天语音
微信PC端技术研究-保存聊天语音 转载地址: [原创]微信PC端技术研究(2)-保存聊天语音-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com 0x0. 前言 最近又学习了某位大佬用 ...
- 微信PC端测试版更新:新增视频号直播工具
你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 推荐:https://www.xttblog.com/?p=5155 明天就开始 ...
- win7下搭建小程序服务器,重磅!微信PC端支持小程序直接开启 适配Win7及以上系统...
原标题:重磅!微信PC端支持小程序直接开启 适配Win7及以上系统 腾讯科技讯 8月9日,腾讯科技在"微信开放社区"发现,微信正在测试"PC端支持打开小程序"能 ...
- 调试微信 PC 端的内置浏览器界面
2021-08-03 最新更新 好久没看,微信也更新了好几版.下面的方法并没有失效,不过上了 3.3.x 后的微信版本已经禁用了右键和查看 chrome://version 的功能了.进过实测,最后一 ...
最新文章
- 为什么我可以在Java中抛出null? [重复]
- C#里调用带输出参数的存储过程
- 一道关于回文的笔试题
- 判断是否为二叉排序树的递归算法_左神直通BAT算法笔记(基础篇)
- 多元正态分布的后验采样(包含程序)
- 深度linux安装make,linux下安装python3完整教程(依赖环境gcc,make,cmake,configure等详细解释)...
- 正则表达式---采集总结
- 那些自媒体视频剪辑素材是怎么找到的?
- 本机ip与外网ip(附带查询方法)
- 实际使用Windows 7中的Readyboost功能
- 微信小程序开发(7)---协同工作篇
- Gitea服务器ip变更项目无法创建、拉取、上传
- 再见2021,2022加油
- EKS使用AWS EFS CSI
- html5横竖条纹背景,CSS制作Web页面条纹背景样式的介绍
- shell的几个重要命令,主要参数,循环语句以及变量处理
- Redis高性能缓存数据库
- 5-TAMRA标记LYS赖氨酸,5-TAMRA-Lysine结构式及光谱图分享
- 【RFID实训】公交收费系统详细过程
- 【华为OD机试真题 JAVA】跳格子游戏
热门文章
- 一个计算机专业女孩的求学之路—七年之痒,痒之感悟
- scanf函数的用法
- 微分几何笔记(4) —— 二维三维空间中曲线的曲率以及环绕数
- 芯片之家一周精选,毛线上拉电阻?电容开花了?
- 基于偏振差分成像的图像去雾算法
- Joint Learning of Deep Retrieval Model and Product Quantization based Embedding Index
- SQL语句大全[基础]
- 开薪点惊艳中国HR服务峰会 摘得“2017中国HR服务产品创新”奖
- RTT-thread 邮箱的管理方式
- VMVare中CentOS图形化界面大屏显示的方法(调节屏幕分辨率)