Commit a393337d0d25bbb66708bde6c4b18c4766667249

Authored by yibo
1 parent 79da72d2

fix(wechathook): 微信 DB 多账号选库改用 MD5("mm"+uin) 定位当前账号

旧 `ls|head -1` 按字典序选库,多账号设备会选中非登录账号目录,
却用当前 uin 推的 key 去解 → 解密失败。改为先读 last_login_uin,
再用 目录名=MD5("mm"+uin) 精确定位登录账号库;定位不到才回退 head -1。
真机验证 uin=257966415 正确选中主账号 ec4f423b…(旧逻辑误选 653cdc…)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/vision/WeChatDb.kt
@@ -12,6 +12,7 @@ import java.security.MessageDigest @@ -12,6 +12,7 @@ import java.security.MessageDigest
12 * 端上解密打开微信 `EnMicroMsg.db`(SQLCipher,明文化后供 chat / contacts 等复用)。**纯本地,不经 Mac/Frida**。 12 * 端上解密打开微信 `EnMicroMsg.db`(SQLCipher,明文化后供 chat / contacts 等复用)。**纯本地,不经 Mac/Frida**。
13 * 13 *
14 * key 推导(真机验证):`MD5("1234567890ABCDEF" + uin)[:7]`(imei 用微信默认值;uin 从 shared_prefs 读)。 14 * key 推导(真机验证):`MD5("1234567890ABCDEF" + uin)[:7]`(imei 用微信默认值;uin 从 shared_prefs 读)。
  15 + * 选库(多账号):当前账号目录名 = `MD5("mm" + uin)`,不能用 `ls|head -1`(字典序会选错号 → key 套错库解密失败)。
15 * SQLCipher:`cipher_compatibility=1` + `page_size=1024`。两个 app-su 坑(--mount-master / 空 PATH)见 §七。 16 * SQLCipher:`cipher_compatibility=1` + `page_size=1024`。两个 app-su 坑(--mount-master / 空 PATH)见 §七。
16 * 详见 memory `wechat-android-decrypt`。 17 * 详见 memory `wechat-android-decrypt`。
17 */ 18 */
@@ -36,12 +37,16 @@ object WeChatDb { @@ -36,12 +37,16 @@ object WeChatDb {
36 val script = buildString { 37 val script = buildString {
37 append("export PATH=/system/bin:/system/xbin:\$PATH; ") 38 append("export PATH=/system/bin:/system/xbin:\$PATH; ")
38 append("BASE=/data/user/0/com.tencent.mm; ") 39 append("BASE=/data/user/0/com.tencent.mm; ")
39 - append("DB=\$(ls \$BASE/MicroMsg/*/EnMicroMsg.db 2>/dev/null | head -1); ") 40 + append("UIN=\$(grep -hoE 'last_login_uin\">[0-9-]+' \$BASE/shared_prefs/*.xml 2>/dev/null | grep -oE '[0-9-]+' | head -1); ")
  41 + // 多账号:当前登录账号的库目录名 = MD5("mm"+uin)。旧的 `ls|head -1` 会按字典序选错账号,
  42 + // 把主账号的 key 套到别的号的库上 → 解密失败。定位不到(uin 空/版本变)再回退 head -1。
  43 + append("DIR=\$(printf 'mm%s' \"\$UIN\" | md5sum | cut -c1-32); ")
  44 + append("DB=\$BASE/MicroMsg/\$DIR/EnMicroMsg.db; ")
  45 + append("[ -f \"\$DB\" ] || DB=\$(ls \$BASE/MicroMsg/*/EnMicroMsg.db 2>/dev/null | head -1); ")
40 append("[ -z \"\$DB\" ] && exit 3; ") 46 append("[ -z \"\$DB\" ] && exit 3; ")
41 append("cp \"\$DB\" $sp/en.db || exit 4; ") 47 append("cp \"\$DB\" $sp/en.db || exit 4; ")
42 append("[ -f \"\$DB-wal\" ] && cp \"\$DB-wal\" $sp/en.db-wal; ") 48 append("[ -f \"\$DB-wal\" ] && cp \"\$DB-wal\" $sp/en.db-wal; ")
43 append("[ -f \"\$DB-shm\" ] && cp \"\$DB-shm\" $sp/en.db-shm; ") 49 append("[ -f \"\$DB-shm\" ] && cp \"\$DB-shm\" $sp/en.db-shm; ")
44 - append("UIN=\$(grep -hoE 'last_login_uin\">[0-9-]+' \$BASE/shared_prefs/*.xml 2>/dev/null | grep -oE '[0-9-]+' | head -1); ")  
45 append("echo \"uin=\$UIN\"; ") 50 append("echo \"uin=\$UIN\"; ")
46 append("chown -R $uid:$uid $sp; chmod -R u+rwX $sp") 51 append("chown -R $uid:$uid $sp; chmod -R u+rwX $sp")
47 } 52 }