Commit 996bc374ab4e644b8a1b207e329f3f06d4c34345
1 parent
f0161891
docs(lifelog): HANDOFF 加「微信聊天端上 SQLCipher 解密」小节
- key 纯端上推导 MD5("1234567890ABCDEF"+uin)[:7](imei 用默认值,uin 从 shared_prefs)
- SQLCipher 参数 cipher_compatibility=1/page_size=1024 + postKey hook + 候选 key 试开
- su 拷库 → 读 message 表 type=1 → wechat_messages;单人/批量接线
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Showing
1 changed file
with
18 additions
and
0 deletions
lifelog-recorder/HANDOFF.md
| ... | ... | @@ -260,6 +260,24 @@ Tier-0 PhotoFaceWorker (15min, battery-not-low) Tier-1 PhotoVlWorker (1 |
| 260 | 260 | |
| 261 | 261 | **落库 / 展示**:朋友圈图**不进相册**(「照片」tab 只放头像 + 真正人脸认出的合照);图按条存 `filesDir/moments/<wxid>/<createTimeMs>_<i>.jpg`,文字写 `moments` 表(`createTime` 存 ms)。朋友圈 tab 的 `MomentRow` 按 `createTimeMs` glob 回该条的图,渲染成微信式「正文 + 九宫格 + 时间」。幂等:头像 `getByPath` 去重、`moments.clearUser` + 目录清空重灌、开头 `idsByPathLike("%/moment_<wxid>_%")` 清旧版误导进相册的图。 |
| 262 | 262 | |
| 263 | +### 微信聊天:端上 SQLCipher 解密(v0.8,2026-06-10,P2 #6,纯本地不经 Mac) | |
| 264 | + | |
| 265 | +朋友圈库明文好读,**聊天库 `EnMicroMsg.db` 是 SQLCipher 加密**——过去只能靠 Mac 解密推 `wx_enroll/messages.json`。现在端上直接解密读,**key 纯端上可推导,不用 Frida**。代码 `vision/WeChatChatImporter.kt` + `PhotologViewModel.importChatFor()`。 | |
| 266 | + | |
| 267 | +**key 推导(真机验证 = 旧 Frida 抓到的 `e03ce81`)**: | |
| 268 | +``` | |
| 269 | +key = MD5(imei + uin).hex()[:7].lower() | |
| 270 | + imei = "1234567890ABCDEF" # 微信默认值:现代 Android(10+)读不到真 IMEI 时的回退,稳定 | |
| 271 | + uin = 215004919 # 从 com.tencent.mm/shared_prefs/*.xml 的 last_login_uin 读 | |
| 272 | +``` | |
| 273 | +> ⚠️ imei 用**默认值**而非真 IMEI 是关键。真 IMEI 算出来不对。`WeChatChatImporter` 候选 `["1234567890ABCDEF",""]` 逐个试开兜底。 | |
| 274 | + | |
| 275 | +**SQLCipher 参数(微信用旧版)**:`PRAGMA cipher_compatibility = 1` + `PRAGMA cipher_page_size = 1024`(在 `SQLiteDatabaseHook.postKey` 里设)。依赖 `net.zetetic:android-database-sqlcipher:4.5.4`。 | |
| 276 | + | |
| 277 | +**流程**:`su --mount-master`(两坑见 §七)拷 `MicroMsg/<hash>/EnMicroMsg.db`(+wal/shm) + echo uin → 算 key 候选 → `SQLiteDatabase.openDatabase(path, key, …, OPEN_READONLY, hook)`,能查 `sqlite_master` 即 key 对 → 读 `message` 表 `WHERE type=1 AND talker IN (?…)`(type=1 文本、talker=对方 wxid、isSend 0/1、createTime ms、content)→ 写 `wechat_messages`(`clearTalker` 先清再灌,幂等)。 | |
| 278 | + | |
| 279 | +**接线**:单人「⬇下载图片」顺带解密该人聊天;通讯录「🔄更新」**一次性解密整库**读所有 wxid(避免逐人重复解密整库,慢)。`message` 表结构等见 memory `wechat-android-decrypt`。 | |
| 280 | + | |
| 263 | 281 | --- |
| 264 | 282 | |
| 265 | 283 | ## §五 §六 待办(按优先级) | ... | ... |