banner
Silas

REAO

Be a better man
github

WeChat | Database Decryption

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 digits are used as the password.
Note: In special cases when the password is incorrect and WeChat cannot obtain the IMEI number, a fixed value of 1234567890ABCDEF will be used as the default.

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

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
    // The SQLiteDatabaseHook parameter has been removed, and the same purpose can be achieved by specifying the parameters in the cipher
);

Through analysis with 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, and there is no dispute. 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 obtains device information, and it seems quite complex to analyze. Let's stop here.

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

References#

  1. 记一次安卓微信数据库电脑端打开查看的问题
  2. Android 逆向分析实例 (三)- 解密微信 EnMicroMsg.db 数据库
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.