README_Android.md
WeChat Android EnMicroMsg.db 解密读取工具链
文件清单
| 文件 | 用途 | 运行环境 |
|---|---|---|
wechat_android_key_hunter.js |
Frida 脚本:hook libWCDB.so 的 sqlite3_key / sqlite3_key_v2,截获 SQLCipher 密码 |
Android 微信进程 |
wechat_android_attach.py |
Python 控制脚本:attach 微信、收集 key、提取 DB、自动解密 | Termux / Debian proot / Mac |
search_server_android.py |
Web 搜索服务器:读取解密后的 EnMicroMsg.db,提供会话/联系人/聊天记录搜索 |
任意有 Python 的环境 |
工作原理
微信启动
↓
打开第一个加密 DB (PreDownloadCheck.db)
↓
libWCDB.so!sqlite3_key(db, "e03ce81", 7) ← Frida 在这里截获 key
↓
后续所有 DB (EnMicroMsg.db, WxFileIndex.db, ...) 复用同一 key
↓
adb shell su -c cat 复制 DB 文件到本地
↓
sqlcipher 解密:PRAGMA key="e03ce81"; PRAGMA cipher_compatibility=1; PRAGMA cipher_page_size=1024;
↓
SQLite 明文库 → search_server_android.py 提供 Web UI
关键发现(WeChat 8.0.72 on Android)
| 项目 | 值 |
|---|---|
| SQLCipher key | e03ce81(7 字符字符串密码,通过 sqlite3_key 传入) |
| cipher_compatibility | 1 |
| cipher_page_size | 1024 |
| Key 设置时机 | 打开第一个加密 DB 时调用一次 sqlite3_key,后续所有 DB 复用 |
| Java VM 可见性 | Java.available = false(微信有反注入,但 native hook 完全正常) |
| Hook 目标 so | libWCDB.so(内含 SQLCipher,sqlite3_key 符号可通过 mod.findExportByName() 定位) |
DB 结构(Android 版 vs macOS 版)
| | Android EnMicroMsg.db | macOS db_storage/ |
|--|------------------------|---------------------|
| 文件数 | 单文件 | 多个分库 |
| 消息表 | message(talker 字段区分对象) | Msg_<md5> 分表 |
| 联系人表 | rcontact | contact_contact.db 的 contact |
| 会话表 | conversation(可能为空) | session_session.db 的 SessionTable |
message 表关键字段
msgId— 消息 IDtype— 消息类型:1=文本, 3=图片, 49=链接/卡片, 10000=系统消息isSend— 0=收到, 1=自己发送createTime— 毫秒时间戳talker— 聊天对象:wxid_xxx(单聊)、xxx@chatroom(群聊)content— 消息内容。群聊格式:sender_wxid:\n<body>
rcontact 表关键字段
username— wxidnickname— 昵称conRemark— 备注名type— 1=好友, 2=群成员, 3=公众号deleteFlag— 0=正常
使用步骤
1. 环境准备
# 手机端:确认 frida-server 已运行(root)
adb shell "ps -A | grep frida-server"
# Debian proot 里安装 frida Python 包(版本匹配手机 frida-server)
pip install frida==17.9.10
# 安装 sqlcipher(用于解密)
# Debian: apt-get install sqlcipher
# Mac: brew install sqlcipher
2. 捕获 SQLCipher key
python3 wechat_android_attach.py
- 脚本会自动 kill 微信、重新启动、attach Frida
- 等待
KEY CAPTURED输出 - key 自动保存到
~/wxmoment/wechat_keys.json
3. 提取 DB 文件
python3 wechat_android_attach.py --extract-db
- 复制
EnMicroMsg.db+-shm+-wal到~/wxmoment/dbs/ - 必须复制 wal 文件,否则丢失最新数据
4. 解密 DB
python3 wechat_android_attach.py --decrypt
- 自动尝试字符串密码 / hex key + 多种 cipher 配置组合
- 输出:
~/wxmoment/dbs/EnMicroMsg.db.decrypted.db
5. 启动搜索服务器
python3 search_server_android.py ~/wxmoment/dbs/EnMicroMsg.db.decrypted.db
- 访问 http://localhost:5002
- 支持:会话列表、联系人浏览、聊天记录分页、全局搜索
手动解密(如需自定义)
sqlcipher EnMicroMsg.db
PRAGMA key = "e03ce81";
PRAGMA cipher_compatibility = 1;
PRAGMA cipher_page_size = 1024;
ATTACH DATABASE 'EnMicroMsg_plain.db' AS plain KEY '';
SELECT sqlcipher_export('plain');
DETACH DATABASE plain;
.quit
Frida 脚本 API 说明
wechat_android_key_hunter.js 的 Hook 点:
| Hook 函数 | 模块 | 用途 |
|---|---|---|
sqlite3_key |
libWCDB.so |
捕获密码/key |
sqlite3_key_v2 |
libWCDB.so |
捕获密码/key(带 db name) |
sqlite3_open_v2 |
libWCDB.so |
记录 DB 文件路径 |
sqlite3_exec |
libWCDB.so |
捕获 PRAGMA key / PRAGMA cipher_* |
发送的消息格式(JSON):
{"type": "key", "hex": "65303363653831", "len": 7, "via": "libWCDB.so!sqlite3_key", "path": "", "extra": {"native": true, "v2": false, "db": "0x77342ab938"}}
注意事项
- frida-server 版本必须匹配 Python frida 包版本(当前:17.9.10)
- 微信是多进程应用,主进程 PID 需要通过
pgrep -x com.tencent.mm获取最小 PID - spawn 模式会超时,所以使用
am force-stop+am start+attach(pid)的 early-bird 模式 - Java 层 hook 不可用,因为微信主进程对 Frida 隐藏了 JVM。所有 hook 都在 native 层完成
- DB 路径:
/data/data/com.tencent.mm/MicroMsg/<hash>/EnMicroMsg.db <hash>目录名:基于微信账号生成,每个账号不同