wechat-clean
释放你的安卓微信内部存储空间,一键解放微信存储空间的工具。
https://github.com/ellermister/wechat-clean
介绍
主要原理:
通过解密微信的数据库,过滤出群聊天记录,并找出相关的缓存文件、图片、视频等,一并删除。最后,删除这些数据库记录,从而缩减数据库的大小。
为什么会做这个?
由于记忆力有限,可能不想删除所有的聊天记录,而是希望保留联系人记录,以便在需要时可以参考上下文。
然而,微信甚至不像 QQ 那样,可以手动点击接收图片。微信默认会接收所有群组的消息、图片和视频缓存等,群里聊的每一个字节都存到了你的手机里。
此外,微信的文件分类管理非常混乱,这些文件甚至被隐藏在 /data
目录中,只有具备 root 权限的用户才能进行处理。即使你有 root 权限,也无法轻易找出哪些文件可以删除,哪些文件不能删除。
长期以来,虽然你的联系人资料可能并不占用太多存储空间,但群组的资料却可能占据了大部分空间。
为什么你不退群?
没有习惯退群,即使退了,群组之前的记录仍会像狗皮膏药一样永远存储在你的手机中,无法轻易清除。
为什么不用内置聊天管理?
内置的聊天管理功能根本无法满足清理需求,缺乏一键选择群组的功能。
经过测试,即使勾选了清理选项,导出数据后你会发现数据库和缓存中仍然存在数据,内置功能并没有完全清理干净,就像删除了一个软连接一样。(测试自 8.0.2 版本)
功能:
清理所有群产生的聊天记录、图片、视频和音频缓存,从而缩减数据库大小。
可选择只清理联系人,这一功能一般用不上。
顺便清理其他目录:小程序、基础缓存、检查更新残留、record 缓存、avatar 缓存、FTS5Index*、webview 内核缓存、wepkg 缓存等。
清理其他表项:公众号推送列表、转发通知消息、已经删除的关联记录表、用户头像关联缓存等。
效果
这是搞了好几天的成果,虽然结果还是很大,但已经减少了十几 GB 的体积!好在是可以弄成一键工具进行清理了。
编译
文件编译
env GOOS=android GOARCH=arm64 CC=C:\android-ndk-r25c-windows\android-ndk-r25c\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android30-clang GOARM=7 CGO_ENABLED=1 go build
push
adb push wechat-clean /data/local/tmp
备份
推荐钛备份,可以全量备份版本及用户数据
下载:https://play.google.com/store/apps/details?id=com.keramidas.TitaniumBackup&hl=zh&gl=US
命令行手动备份
截取自钛备份, 不包含 sdcard 数据
busybox tar -c /data/data/com.tencent.mm/. --exclude data/data/com.tencent.mm/./lib --exclude data/data/com.tencent.mm/./cache
开始
注意⚠️⚠️⚠️
Android 设备必须拥有 root 权限
使用前请先备份数据!
你必须为你自己数据清理过程中产生意外错误后自己负责,如执行中断、超范围删除等。
测试环境在 8.0.24 验证通过
执行流程
请先想办法获取你的数据库密码!
下载文件 wechat-clean 到
/data/local/tmp
中提权到 root 权限
su
给程序赋予执行权限
chmod +x wechat-clean
找到你的微信 32 位用户 ID
结束微信进程
ps -ef|grep com.tencent.mm|grep -v grep| awk '{print $2}'|xargs kill -9
执行扫描
./wechat-clean -id [32 位用户 ID] -key [7 位密码] -from groups -cmd scan
获取用户微信 32 位 ID
如果你只登陆过一个用户那非常简单,执行命令就能看到一个长度 32 位 ID 的目录
ls /data/data/com.tencent.mm/MicroMsg/
获取数据库 KEY
hook 方法获取
你可能需要学习 frida 相关基础知识和流程。
启动微信后,执行命令会输出密码
frida -U -n Wechat -l wechatdbpass.js
计算方式
需要找出你的 imei 和 uin,相关网上资料很多,但不一定能够计算出来。
如果你换过手机并迁移数据,这个 imei 可能早就就变了,并不是当前手机 IMEI。
import hashlib
imei = "866123456789111"
uin = "-123456789"
key = hashlib.md5( str( imei ).encode("utf8") + str( uin ).encode("utf8")).hexdigest()[ 0:7 ]
print(key)
其他用法
./wechat-clean -h
Wechat-Clean v20230716
Usage of ./wechat-clean:
-cmd string
scan/clean (default "scan")
-from string
groups/friends/all
-id string
user 32 length hex id
-key string
db key
-user int
Android user id
-vd string
Vacuum db full path
扫描
扫描垃圾文件只是读库读文件,是一个安全行为。
./wechat-clean -cmd scan -id [32 位用户 ID] -key [7 位密码] -from all
清理群相关记录
本程序最适合也只建议清理群消息。
./wechat-clean -id [32 位用户 ID] -key [7 位密码] -from groups -cmd clean
精简数据库
不会删除数据,只是释放已经删除数据的空间,同 sqlite 命令:vacuum
./wechat-clean -vd /data/data/com.tencent.mm/MicroMsg/*****/EnMicroMsg.db -key 1122334
vacuum 只会将已经删除记录空间释放,如果没有删除是无法缩减的。
sqlite + sqlcipher 在 Android 上执行 vacuum 时,会把数据库吞进内存处理,内存几乎是文件的 2 倍,然后涨到 2.5G 左右时被 OOM 或者其他系统机制干掉,具体原因不明。
对于数据库大于 1GB 的文件将在 clean 排程中跳过,你需要将 EnMicroMsg.db 通过 adb 复制到 windows 等,缩减后再放回去。
以下参考:
android #
cp /data/data/com.tencent.mm/MicroMsg/****/EnMicroMsg.db /data/local/tmp
win #
adb pull /data/local/tmp/EnMicroMsg.db .
./wechat-clean -vd /data/data/com.tencent.mm/MicroMsg/*****/EnMicroMsg.db -key 1122334
adb push EnMicroMsg.db /data/local/tmp
android #
cp /data/local/tmp/EnMicroMsg.db /data/data/com.tencent.mm/MicroMsg/****/EnMicroMsg.db
UI 界面手动清理
以服务器形式启动,通过手机或者同一个局域网下的电脑可以进行访问执行操作。
默认端口为 9999 请避免端口占用。
只需要如下参数即可启动:
./wechat-clean -id [32ID] -cmd server -key [7key]
支持操作:
搜索昵称备注
全选/取消全选所有好友
全选/取消权限所有群组
单选任意会话
其他
记录一些快捷指令
查看子目录占用大小
android:/data/data/com.tencent.mm # du -h -d 1
3.5K ./code_cache
499M ./files
2.0G ./MicroMsg
3.5K ./app_lib
3.5K ./app_dex
3.5K ./app_cache
3.5K ./app_recover_lib
1.4M ./shared_prefs
冻结恢复应用
在执行 clean 时程序会自动冻结你的程序并在完成后恢复,如果意外没有恢复,你可以手动执行。
冻结应用
adb disable com.tencent.mm
恢复应用
adb enable com.tencent.mm
IOS 用户
对于没有 root 的 Android 或者 IOS 用户来说无法实现,一般也没有必要天天清理,可以按照以下方法一年一清。
将使用的 IOS 微信备份到 PC 微信,选择全部聊天记录。
在已经 root 的 Android 设备上登录微信并恢复聊天记录到本地。
通过脚本清理群组聊天记录(建议提前备份有基础密钥的基础数据库,可以减少重新获取密钥的工作)
将清理后的微信备份到 PC 微信,如果该设备备份过,在 PC 端点击删除备份,否则是追加,会有垃圾的。
在 IOS 设备重装微信,登录后从 PC 微信恢复精简后的全部聊天记录。
或者许愿未来哪一天宇宙级产品经理愿意实现自定义备份功能了,就有解了!
数据表
以下给我自己看的!备忘录!!!
表名 描述 可清理 AppMessage 应用消息, 可能是通知, 邀请信息之类的, 有 title 和 description 字段 垃圾可清, 量大 fmessage_conversation 好友申请记录 无需清 rcontact 联系人和群组表,含昵称、原始 ID message 聊天记录 MediaDuplication 一部分外置资源图片, 5k 行 可清不存在的记录 ImgInfo2 图片总表 videoinfo2 视频总表 appattach 一部分下载的文件、一部分图文聊天记录的转发? 可清理,内容几百条 ChatroomNoticeAttachIndex 聊天记录转发产生的 HTM 文件,路径不存在可请 可清不存在的记录 EmojiInfo 表情、贴图表 CleanDeleteItem 删除的项目,看名字就可以删除 全清 img_flag 用户的头像映射 全清 BizTimeLineInfo 公众号的推送会话列表 全清 rconversation 最近会话列表 无需清
查找文件方法:
根据 type 区分文件类型
图片和视频
在 message 表找到对应记录,拿到 msgsvrid、msgId
通过 ImgInfo2 或者 VideoInfo2 查找 msgsvrid=236411111111111111;
找到缩略图、中图、大图、hevc 图的 filename,拿到 filename,图片的话在 image2 目录,文件名前 4 位是两级子目录名。
视频的话再去对应外置存储路径中如 video/230621111111111111.mp4 删除,可能也有 video/230621111111111111.jpg 为缩略图
也可以跳过中间表,直接用 imgpath 去找。如果要删除的话记得删除中间表的数据,也挺大的。
音频文件
在数据库拿到文件名 54155907092311111111111111
md5 之后 = c9529f3187f2afbbf742249baccac089
外置路径就是 = voice2/c9/52/msg_54155907092311111111111111.amr
message
type 猜解
1,文字消息
47,表情?
3, xml 内容 和 图片
822083633,回复的消息
49,图文消息、文件传输的消息
285212721,公众号的各种推送
10000,系统通知,加好友通知,群进成员通知,撤回通知
43,视频文件
34,音频文件
?查询数据时的联表备注
异常的 msglocalid
下面 SQL 通过 msgSvrId 关联 和 msglocalid 关联产生对比,其中 msgSvrId 能够关联出更多的数据
虽然这样的查询能够更全面的展示消息对应文件的存储路径,但是如果要删除可能会多删。
SELECT
m.msgId,
m.type,
m.imgPath,
m.talker,
img.bigImgPath,
img2.bigImgPath
FROM
'message' AS m
LEFT JOIN ImgInfo2 AS img ON img.msglocalid = m.msgId
LEFT JOIN ImgInfo2 AS img2 ON img2.msgSvrId = m.msgSvrId
WHERE
m.imgPath != ''
AND m.type = 3
ORDER BY
m.msgId DESC
这里通过不同字段关联了两次,在实际测试中存在一些数据:
通过 msglocalid 关联的 bigImgPath 是空的(理解为漏了)
而 msgSvrId 关联出来的 bigImgPath 非空且本地有图,但也大多没有 msglocalid,能想到的解释是非聊天室首次加载的后续根据 md5 信息无需再次加载即不需要维护,更或者是维护出现了断层。
是否 msglocalid 和 msgSvrId 关联出有效的数据路径是一致的?
如下 SQL 仅显示有效 msglocalid 关联结果与 msgSvrId 有效结果
SELECT * FROM (
SELECT
m.msgId,
m.type,
m.imgPath,
m.talker,
img.bigImgPath,
img.midImgPath
,img.msglocalid
,img2.bigImgPath as bigImgPath2
,img2.msglocalid
FROM
'message' AS m
LEFT JOIN ImgInfo2 AS img ON img.msglocalid = m.msgId
LEFT JOIN ImgInfo2 AS img2 ON img2.msgSvrId = m.msgSvrId
WHERE
m.imgPath != ''
AND m.type = 3
ORDER BY
m.msgId DESC
) AS F WHERE
bigImgPath!='' and bigImgPath!=bigImgPath2;
可以看到如下图所示,一个群组消息关联出 4 个不同的图片路径,hash 值也不太一样。
虽然数据量只有一条,但为了避免这种少量数据,还是将所有字段全部查出为好,最后去重。
一图多用
另外还存在一个图片在私人聊天和群组聊天中共同产生,即同样一张图首次加载后再次转发不再继续插入数据的现象:
SELECT msgSvrId,COUNT(*) as count FROM message group by msgSvrId HAVING count >1;
SELECT msgSvrId,COUNT(*) as count FROM ImgInfo2 group by msgSvrId HAVING count >1;
其中没有 msgSvrId
的图片的也不少,大多都是聊天室的图片,发信人和自己都不是好友的情况,所以基本可删。
可以通过如下 SQL 复现:
SELECT
*, substr(
reserved3,
0,
instr (reserved3, ":")
) AS r_username
FROM
ImgInfo2
LEFT JOIN rcontact AS rc ON rc.username = r_username
WHERE
msgSvrId IS NULL
ORDER BY
id DESC;
通过结果集观察,r_username 基本都是非好友关系,但并不能确认发信人所在聊天室是群组还是好友,它的msgSvrId
都是空的,除了朋友圈之外实在想不明白这种非好友的缓存图片的 msgSvrId
和 msglocalid
是为什么是空的,即使在群里也应该维护这两个字段才对。
结论
所以最终为了删除更多的数据, 避免遗漏会采用两个字段分别关联,查出所有文件字段。
通过 message 查找出的图片数量不足
通过上面 type=3 查找出消息的图片缓存及各种图片的数量和体积都小于实际存储的,通过差集反查发现部分数据是存在于数据库,但 type 为 49,即图文数据。
图文 XML 格式:
wxid_cbg000000000000:
<?xml version="1.0"?>
<msg>
<img aeskey="00000000000000000000000000000000" encryver="1" cdnthumbaeskey="00000000000000000000000000000000" cdnthumburl="00000000000000000000000000000000" cdnthumblength="6056" cdnthumbheight="131" cdnthumbwidth="150" cdnmidheight="0" cdnmidwidth="0" cdnhdheight="0" cdnhdwidth="0" cdnmidimgurl="00000000000000000000000000000000" length="31425" cdnbigimgurl="00000000000000000000000000000000" hdlength="31425" md5="00000000000000000000000000000000" />
<platform_signature></platform_signature>
<imgdatahash></imgdatahash>
</msg>
rcontcat
type 字段猜解
0,公众号小程序
1,自己及企业号
2,群
3,好友及公众号
4,好像是群成员,巨多垃圾
33,官方服务;漂流瓶,朋友圈,广播助手,QQ 信箱提醒,小程序客服讯息,语音通话之类的
67,不确定是特别关注还是拉黑的名单
259,不知道,包含 3 个正常联系人?有趣!
513,不知道,包含 1 个正常联系人
515,不知道,包含 2 个正常联系人
2049,文件传输助手
1114113,不知道,包含 1 个正常联系人
8388611,不知道,包含 59 个联系人
verifyFlag
可能不准确,在 type = 3 的情况下:
0,好友
8,公众号
24,也是公众号
56,微信团队
776,自媒体公众号
官方服务
应用名称 用户名 QQ 信箱提醒 qqmail 漂流瓶 floatbottle 摇一摇 shakeapp 附近的人 lbsapp 语音记事本 medianote 腾讯新闻 newsapp Facebook 协助工具 facebookapp 查看 QQ 朋友 qqfriend 广播助手 masssendapp 朋友圈 feedsapp 新视频通话 voipapp 订阅账号消息 officialaccounts 语音通话 voicevoipapp 语音输入 voiceinputapp LinkedIn linkedinplugin 服务通知 notifymessage 小程序客服消息 appbrandcustomerservicemsg 我的小程序消息 appbrand_notify_message WeChat 游戏下载 downloaderapp 客服消息 opencustomerservicemsg 新的朋友 fmessage
WxFileIndex3
文件类型查找
msgType = 1090519089
SELECT * FROM "WxFileIndex3" where msgType=1090519089;
目录
另外补充几个长年累月体积不小的目录、
:/data/data/com.tencent.mm # du -h -d 1
595M ./files 微信的一些基础资源目录
2.9G ./MicroMsg 用户数据
130M ./app_tbs_64 浏览器内核
杂七杂八的浏览器内核缓存和热更新,可以无脑删除。
102M ./app_xwalkplugin
179M ./app_xwalk_5169
228M ./lib-
278M ./cache
128M ./app_xwalk_4296
177M ./app_xwalk_5153
Comments