微信PC端各个数据库文件结构与功能简述 您所在的位置:网站首页 微信文件夹record是什么 微信PC端各个数据库文件结构与功能简述

微信PC端各个数据库文件结构与功能简述

2024-01-17 06:43| 来源: 网络整理| 查看: 265

异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复;本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告。本人所有文章仅在CSDN、掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是盗文!

相关内容:

微信PC端数据库文件解密_微信电脑版db文件解密_异想之旅的博客-CSDN博客微信PC端各个数据库文件结构与功能简述 - 根目录_微信用了哪些数据库_异想之旅的博客-CSDN博客

Multi文件夹中的文件解码和之前的其它数据库操作相同。

该文件夹中文件结构比较简单,只有三种:FTSMSG、MediaMSG和MSG。这里说是三种不是三个,是因为这里的数据库达到一定大小后会拆分。

FTSMSG

看过《总述》一文的应该很熟悉 FTS 这一前缀了——这代表的是搜索时所需的索引。

其内主要的内容是这样的两张表:

FTSChatMsg2_content:内有三个字段 docid:从1开始递增的数字,相当于当前条目的 IDc0content:搜索关键字(在微信搜索框输入的关键字被这个字段包含的内容可以被搜索到)c1entityId:尚不明确用途,可能是校验相关 FTSChatMsg2_MetaData docid:与FTSChatMsg2_content表中的 docid 对应msgId:与MSG数据库中的内容对应entityId:与FTSChatMsg2_content表中的 c1entityId 对应type:可能是该消息的类型其余字段尚不明确

特别地,表名中的这个数字2,个人猜测可能是当前数据库格式的版本号。

MediaMSG

这里存储了所有的语音消息。数据库中有且仅有Media一张表,内含三个有效字段:

KeyReserved0Buf

其中Reserved0字段与MSG数据库中消息的MsgSvrID一一对应。

第三项即语音的二进制数据,观察头部即可发现这些文件是以 SILK 格式存储的。这是一种微软为 Skype 开发并开源的语音格式,具体可以自行 Google。

下面是将 Buf 字段中的数据导出为文件的代码:

import sqlite3 def 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 = 1099511630953 import wave from pathlib import Path import pilk def 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 的缩写,代指服务器端存储的消息 IDType:消息类型,具体对照见表1SubType:消息类型子分类,暂时未见其实际用途IsSender:是否是自己发出的消息,也就是标记消息展示在对话页左边还是右边,取值0或1CreateTime:消息创建时间的秒级时间戳。此处需要进一步实验来确认该时间具体标记的是哪个时间节点,个人猜测的规则如下: 从这台电脑上发出的消息:标记代表的是每个消息点下发送按钮的那一刻从其它设备上发出的/收到的来自其它用户的消息:标记的是本地从服务器接收到这一消息的时间 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字段数值与含义对照表(可能可以扩展到其它数据库中同样标记消息类型这一信息的字段)

分类子分类对应类型10文本30图片340语音430视频470动画表情(第三方开发的表情包)491类似文字消息而不一样的消息,目前只见到一个阿里云盘的邀请注册是这样的。估计和 57 子类的情况一样495卡片式链接,CompressContent 中有标题、简介等,BytesExtra 中有本地缓存的封面路径496文件,CompressContent 中有文件名和下载链接(但不会读),BytesExtra 中有本地保存的路径498用户上传的 GIF 表情,CompressContent 中有 CDN 链接,不过似乎不能直接访问下载4919合并转发的聊天记录,CompressContent 中有详细聊天记录,BytesExtra 中有图片视频等的缓存4933/36分享的小程序,CompressContent 中有卡片信息,BytesExtra 中有封面缓存位置4957带有引用的文本消息(这种类型下 StrContent 为空,发送和引用的内容均在 CompressContent 中)4963视频号直播或直播回放等4987群公告4988视频号直播或直播回放等492000转账消息(包括发出、接收、主动退还)492003赠送红包封面100000系统通知(居中出现的那种灰色文字)100004拍一拍100008000系统通知(特别包含你邀请别人加入群聊)

本文参考资料(排名不分先后):

python使用技巧(二十七):音频WAV和PCM的互相转换_python pcm转mp3_源代码杀手的博客-CSDN博客foyoux/pilk: python silk codec binding 支持微信语音编解码


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有