本文章基于 Android 微信 8.0.3
寻找数据库文件#
首先,寻找uin
, 位于/data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml
文件中:
微信聊天数据库名称为 EnMicroMsg.db,位于data/data/com.tencent.mm/MicroMsg/
下的某个特定文件夹中,文件名为md5_32_low(imel + uin)
:
微信数据库密码是由 IMEI 号和微信 uin 拼接,并使用 md5 进行加密成 32 位小写,取前 7 位为密码。
注意:如果密码不正确时,特殊情况下,如果微信拿不到 IMEI 号时,会默认一个固定值为 1234567890ABCDEF
一开始,使用 mac 平台的各种 SQLCipher 查看工具,都没能打开。还以为算法改了,分析了一波发现没错,使用 windows 平台的 SQLCipher.exe 能打开。
分析流程#
微信使用的数据库为 wcdb, 通过 WCDB 文档 Android 接入,可以了解 wcdb 打开数据库的方法:
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(
"path/to/database", // DB 路径
passphrase.getBytes(), // WCDB 密码参数类型为 byte[]
cipher, // 上面创建的加密描述对象
null, // CursorFactory
null // DatabaseErrorHandler
// SQLiteDatabaseHook 参数去掉了,在cipher里指定参数可达到同样目的
);
通过 jadx 分析,openOrCreateDatabase
存在比较多的重载方法,并且内部都使用了SQLiteDatabase.openDatabase
方法。
通过 frida hook 该函数并追溯调用栈,寻找密码的生成规则。
调用栈#
上溯调用栈,寻找密码生成的位置。
com.tencent.mm.storagebase.a.b:
this.key = C7959g.getMessageDigest((C8811q.m22244dJ(true) + j).getBytes()).substring(0, 7);
this.kiF = C67989f.m106126E(str, this.key, z);
通过对 getMessageDigest 方法 HOOK,获取到:
参数: 1234567890ABCDEF-156*****65 (1234567890ABCDEF + uin)此处 j 为 uin 其实没什么异议,继续分析一下 C8811q.m22244dJ (true) ,
返回值 552**********************ac9fbb6
public static String m22244dJ(boolean z) {
AppMethodBeat.m18334i(155720);
String str = gXe.get();
if (!Util.isNullOrNil(str)) {
AppMethodBeat.m18335o(155720);
return str;
} else if (z) {
AppMethodBeat.m18335o(155720);
return "1234567890ABCDEF";
} else {
AppMethodBeat.m18335o(155720);
return "";
}
}
gXe 是一个获取设备信息的类,看了一下分析起来比较复杂,就到这为止吧。
相关文件: https://pan.baidu.com/s/1WIZ_wdAFn_9tMZNxzC5i5Q 提取码: xpnk
参考资料#
1、记一次安卓微信数据库电脑端打开查看的问题
2、Android 逆向分析实例 (三)- 解密微信 EnMicroMsg.db 数据库