Problem
WeChat 4.1+ (Linux/macOS) no longer caches raw database encryption keys in the x'<64hex_key><32hex_salt>' format in process memory. This breaks the memory scanning approach used by this project and all similar tools.
Related issues: #49, jackwener/wx-cli#30, Thearas/wechat-db-decrypt-macos#9
Root Cause
We performed exhaustive analysis:
- 387 million 16-byte-aligned HMAC brute-force candidates across all 20 WeChat processes → 0 hits
- Raw database salt bytes found in ephemeral subprocesses (alive for seconds, then exit)
- The
x'<hex>' patterns in main process memory contain different salts — they are not the database keys
The actual mechanism: WeChat 4.1+ stores a passphrase (not raw key) in memory. The enc_key is derived via:
enc_key = PBKDF2-SHA512(passphrase, db_salt, iterations=256000, dklen=32)
This is consistent with SQLCipher's standard PRAGMA key behavior — the passphrase is passed to sqlite3_key(), and SQLCipher internally derives the raw key. Previous versions cached the post-derivation raw key in x'<hex>' format (which skips PBKDF2). Version 4.1+ stopped doing that.
Solution
ELF Static Analysis + GDB Breakpoint + PBKDF2 Derivation
1. Auto-locate breakpoint via ELF analysis
Search .rodata for com.Tencent.WCDB.Config.Cipher, trace LEA RSI xrefs in .text, find function head. This gives the breakpoint virtual address automatically for any WeChat version — no manual reverse engineering needed.
Verified offsets:
- WeChat 4.1.1.4 Linux x86_64:
0x673A830
- WeChat 4.1.0.10:
0x658FC90
- WeChat 4.1.0.16:
0x6586C90
2. GDB breakpoint capture
Attach GDB to WeChat, set breakpoint, user re-logs in, read passphrase from *(void**)($rsi+8) (32 bytes). Detach immediately.
3. PBKDF2 derivation
For each database file, read its 16-byte salt from page 1, derive:
enc_key = hashlib.pbkdf2_hmac("sha512", passphrase, salt, 256000, dklen=32)
Result: 23/23 databases verified successfully on WeChat 4.1.1.4 Linux.
4. Caching
Save passphrase to disk (chmod 600). On subsequent runs, derive keys from saved passphrase — no GDB needed. If keys file already exists and validates, skip derivation entirely (instant startup).
Standalone Tool
We open-sourced this as: https://github.com/TANGandXUE/wcdb-key-tool
Single Python file, zero third-party dependencies (uses ctypes for libcrypto), auto-adapts to new versions.
Suggested Integration
The key change needed in find_all_keys_linux.py:
- After memory scan finds 0 matching keys, try loading saved passphrase + PBKDF2 derivation
- If no saved passphrase, fall back to GDB capture flow
- Add
elf_analyzer module for auto breakpoint offset detection
Happy to submit a PR if there's interest in integrating this approach.
Problem
WeChat 4.1+ (Linux/macOS) no longer caches raw database encryption keys in the
x'<64hex_key><32hex_salt>'format in process memory. This breaks the memory scanning approach used by this project and all similar tools.Related issues: #49, jackwener/wx-cli#30, Thearas/wechat-db-decrypt-macos#9
Root Cause
We performed exhaustive analysis:
x'<hex>'patterns in main process memory contain different salts — they are not the database keysThe actual mechanism: WeChat 4.1+ stores a passphrase (not raw key) in memory. The enc_key is derived via:
This is consistent with SQLCipher's standard PRAGMA key behavior — the passphrase is passed to
sqlite3_key(), and SQLCipher internally derives the raw key. Previous versions cached the post-derivation raw key inx'<hex>'format (which skips PBKDF2). Version 4.1+ stopped doing that.Solution
ELF Static Analysis + GDB Breakpoint + PBKDF2 Derivation
1. Auto-locate breakpoint via ELF analysis
Search
.rodataforcom.Tencent.WCDB.Config.Cipher, trace LEA RSI xrefs in.text, find function head. This gives the breakpoint virtual address automatically for any WeChat version — no manual reverse engineering needed.Verified offsets:
0x673A8300x658FC900x6586C902. GDB breakpoint capture
Attach GDB to WeChat, set breakpoint, user re-logs in, read passphrase from
*(void**)($rsi+8)(32 bytes). Detach immediately.3. PBKDF2 derivation
For each database file, read its 16-byte salt from page 1, derive:
Result: 23/23 databases verified successfully on WeChat 4.1.1.4 Linux.
4. Caching
Save passphrase to disk (chmod 600). On subsequent runs, derive keys from saved passphrase — no GDB needed. If keys file already exists and validates, skip derivation entirely (instant startup).
Standalone Tool
We open-sourced this as: https://github.com/TANGandXUE/wcdb-key-tool
Single Python file, zero third-party dependencies (uses ctypes for libcrypto), auto-adapts to new versions.
Suggested Integration
The key change needed in
find_all_keys_linux.py:elf_analyzermodule for auto breakpoint offset detectionHappy to submit a PR if there's interest in integrating this approach.