banner
Silas

REAO

Be a better man
github

微信|資料庫解密

This article is based on Android WeChat 8.0.3.

Finding the Database File#

First, find the uin, located in the file /data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml:

image

The WeChat chat database is named EnMicroMsg.db and is located in a specific folder under data/data/com.tencent.mm/MicroMsg/, with the file name md5_32_low(imel + uin):

image

image

The WeChat database password is generated by concatenating the IMEI number and WeChat uin, and encrypting it with md5 to obtain a 32-bit lowercase password. The first 7 characters are used as the password.
Note: In special cases where the password is incorrect and WeChat cannot obtain the IMEI number, a fixed value of 1234567890ABCDEF will be used by default.

Initially, various SQLCipher viewing tools on the Mac platform were unable to open the database. I thought the algorithm had changed, but after analysis, it was found that using SQLCipher.exe on the Windows platform could open it.

Analysis Process#

WeChat uses the wcdb database. By referring to the WCDB documentation for Android integration, you can learn about the method for opening the wcdb database:

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(
    "path/to/database",     // DB path
    passphrase.getBytes(),  // WCDB password, parameter type is byte[]
    cipher,                 // Encryption description object created above
    null,                   // CursorFactory
    null                    // DatabaseErrorHandler
    // SQLiteDatabaseHook parameter is removed, specifying the parameter in cipher achieves the same purpose
);

Through analysis using jadx, there are several overloaded methods for openOrCreateDatabase, and they all internally use the SQLiteDatabase.openDatabase method.

By hooking this function using Frida and tracing the call stack, we can find the password generation rules.

Call Stack#

image

Tracing the call stack to find the location of password generation.

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);

By hooking the getMessageDigest method, we obtain:

Parameter: 1234567890ABCDEF-156*****65 (1234567890ABCDEF + uin) Here, j represents uin, which is not controversial. Let's continue analyzing C8811q.m22244dJ(true),
which returns 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 is a class that retrieves device information, and upon analysis, it seems quite complex. Let's stop here.

Related Files: https://pan.baidu.com/s/1WIZ_wdAFn_9tMZNxzC5i5Q Extraction code: xpnk

References#

  1. 记一次安卓微信数据库电脑端打开查看的问题
  2. Android 逆向分析实例 (三)- 解密微信 EnMicroMsg.db 数据库
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。