### Install Dependencies and Register MCP Server Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/USAGE.md This section outlines the setup process, including installing necessary Python packages and registering the WeChat MCP Server with Claude Code. ```bash # 1. 安装依赖 pip install -r requirements.txt # 2. 注册到 Claude Code claude mcp add wechat -- python C:\path\to\mcp_server.py # 3. 在 Claude Code 中直接对话 claude > 看看微信最近谁找我了 ``` -------------------------------- ### Install Dependencies Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Installs the necessary Python packages for the project. Run this command in your project directory. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install pycryptodome Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md Install the pycryptodome library if you encounter a 'No module named Crypto' error. This is a prerequisite for certain decryption operations. ```bash pip3 install pycryptodome ``` -------------------------------- ### Launch Web UI and Decrypt Databases Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Use `main.py` for a one-click startup that automatically configures, extracts keys, and starts the service. It can also perform a full database decryption to the `decrypted/` directory. ```bash python main.py python main.py decrypt python3 main.py decrypt ``` -------------------------------- ### macOS Terminal Commands for WeChat Decryption Setup Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md These bash commands guide you through identifying your WeChat version, locating account directories, checking database encryption status, and extracting decryption keys using a compiled C tool. ```bash # 1. 确认微信版本 ls ~/Library/Containers/com.tencent.xinWeChat/Data/Library/Application\ Support/com.tencent.xinWeChat/ # 如果看到 2.0b4.0.9 → 3.x 版本 # 如果看到其他 / Documents/xwechat_files → 4.x 版本 # 2. 找到你的账号目录 ls ~/Library/Containers/com.tencent.xinWeChat/Data/Library/Application\ Support/com.tencent.xinWeChat/2.0b4.0.9/ # 最大的那个目录就是你的主账号 # 3. 确认数据库是加密的 file ~/...//Message/msg_0.db # 应该显示 "data" 而不是 "SQLite 3.x database" # 4. 提取密钥 (必须在本机 Terminal!) # 方法 A: 使用 C 工具(推荐,见本 repo 的 find_all_keys_macos.c) cc -O2 -o find_all_keys_macos find_all_keys_macos.c -framework Foundation sudo ./find_all_keys_macos # 输出 all_keys.json,可直接用于解密 # 方法 B: 使用 Frida(需自行编写扫描脚本) # sudo frida -p $(pgrep -x WeChat) -l your_scan_script.js # 5. 运行解密(需配置 config.json 指向 db_storage 目录) python3 decrypt_db.py ``` -------------------------------- ### Start Web UI for Real-time Message Monitoring Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Launches a web server that polls for changes in WAL files and decrypts messages in near real-time. It pushes updates to the browser via SSE and supports various message types and previews. ```bash # 启动 python main.py # 自动提取密钥后启动 Web UI # 或直接 python monitor_web.py # 浏览器访问 http://localhost:5678 # HTTP API 端点 # GET /api/history - 最近消息列表(JSON) # GET /api/history?chat=群名 - 按群名/用户名过滤 # GET /api/history?since=1712000000 - 增量拉取(时间戳之后的消息) # GET /api/history?chat=群名&since=ts&limit=100 - 参数可组合 # GET /api/tags - 所有联系人标签及成员 # GET /api/tags?name=同事 - 按标签名过滤 # GET /stream - SSE 实时消息推送(text/event-stream) ``` -------------------------------- ### Configure OpenAI Transcription Backend Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Switches the voice transcription backend to OpenAI's API for potentially faster and more accurate results. Ensure you have 'openai' installed and provide your API key. This configuration is stored in config.json. ```json { "transcription_backend": "openai", "openai_api_key": "sk-..." } ``` -------------------------------- ### Web UI Real-time Monitoring Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt This section details how to start and use the Web UI for real-time monitoring of WeChat messages. It includes instructions for launching the server and accessing its HTTP API endpoints for message history and real-time streams. ```APIDOC ## Web UI Real-time Monitoring `monitor_web.py` Starts an HTTP server (default port 5678) that polls WAL file mtime changes every 30ms. Upon detecting writes, it performs a full DB decryption and WAL patch (~70ms), then pushes new messages to the browser via SSE, achieving an end-to-end latency of about 100ms. Supports inline image previews (XOR/V1/V2 formats), emoji CDN display, and rich media messages (link cards, files, mini-programs, quote replies, etc.). ### Usage ```bash # Start the server python main.py # Automatically extracts keys and starts the Web UI # Or directly python monitor_web.py # Access the Web UI in your browser http://localhost:5678 ``` ### HTTP API Endpoints - **GET `/api/history`**: Retrieves a list of recent messages (JSON). - **Query Parameters**: - `chat` (string, optional): Filter by chat name (group or username). - `since` (integer, optional): Retrieve messages since a specific Unix timestamp. - `limit` (integer, optional): The maximum number of messages to return. - **GET `/api/tags`**: Retrieves all contact tags and their members. - **Query Parameters**: - `name` (string, optional): Filter tags by name. - **GET `/stream`**: Provides a Server-Sent Events (SSE) stream for real-time message push (text/event-stream). ### Request Examples ```python import requests, json # Fetch recent messages resp = requests.get("http://localhost:5678/api/history") messages = resp.json() # Example response: # [{"time": "2025-03-03 10:25", "chat": "技术群", "sender": "张三", "text": "hello"}, ...] # Filter by chat name + incremental fetch resp = requests.get("http://localhost:5678/api/history", params={ "chat": "AI讨论群", "since": 1740000000, "limit": 50, }) # Real-time subscription via SSE import sseclient resp = requests.get("http://localhost:5678/stream", stream=True) client = sseclient.SSEClient(resp) for event in client.events(): msg = json.loads(event.data) print(f"[{msg['chat']}] {msg['sender']}: {msg['text']}") ``` ``` -------------------------------- ### Load and Iterate Through Chat Messages Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/chat_export_format.md Example Python code to load a chat export JSON file and iterate through messages, handling default values for optional fields like 'type' and 'content'. ```python import json from datetime import datetime with open("chat_export_transcribed.json") as f: data = json.load(f) is_group = data.get("is_group", False) for m in data["messages"]: mtype = m.get("type", "text") when = datetime.fromtimestamp(m["timestamp"]) sender = m["sender"] # "me" | 联系人/群成员名 | "" text = m.get("content", "") if mtype == "voice": text = m.get("transcription") or "[voice, untranscribed]" print(f"[{when:%Y-%m-%d %H:%M}] {sender or '(system)'}: {text}") ``` -------------------------------- ### Get Members of a Specific Contact Tag Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Fetches all members belonging to a specified contact tag. Supports fuzzy matching for the tag name. ```python result = get_tag_members(tag_name="同事") ``` -------------------------------- ### Get All Contact Tags Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Retrieves a list of all contact tags and the number of members associated with each tag. This function queries the 'contact_label' table. ```python result = get_contact_tags() ``` -------------------------------- ### Get New Messages Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Retrieves new messages that have arrived since the last call, by comparing with 'last_timestamp' in session.db. The first call returns all unread conversations. ```python result = get_new_messages() ``` -------------------------------- ### Get Recent WeChat Sessions via MCP Server Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Calls the `get_recent_sessions` tool through Claude Code to retrieve a summary of the N most recent conversations, including unread counts and timestamps. ```python # 在 Claude Code 中调用 result = get_recent_sessions(limit=10) # 返回文本示例: # 最近 10 个会话: # # [03-03 10:25] AI讨论群 [群] (7条未读) # 文本: 张三: Claude max 套餐给我干没了 # # [03-03 09:40] 文件传输助手 # 图片: (无内容) ``` -------------------------------- ### Python Script for WeChat 3.x macOS Database Decryption Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md This script decrypts WeChat 3.x macOS databases by automatically detecting and attempting various SQLCipher configurations. It requires the raw key and handles different page sizes and encryption modes (direct key or PBKDF2). Ensure pycryptodome is installed. ```Python #!/usr/bin/env python3 """WeChat 3.x macOS 数据库解密器""" import hashlib, hmac, struct, shutil from Crypto.Cipher import AES def decrypt_page(page_data, enc_key, page_no, page_size, reserve): """解密单个 page""" if page_no == 1: # 第1页: 前16字节是salt(明文), 后面才是加密数据 salt = page_data[:16] encrypted = page_data[16:page_size - reserve] iv = page_data[page_size - reserve:page_size - reserve + 16] else: encrypted = page_data[:page_size - reserve] iv = page_data[page_size - reserve:page_size - reserve + 16] cipher = AES.new(enc_key, AES.MODE_CBC, iv) decrypted = cipher.decrypt(encrypted) if page_no == 1: # 拼回 SQLite 头: "SQLite format 3\0" + 解密内容 + reserve填零 page = bytearray(b'SQLite format 3\x00' + decrypted + b'\x00' * reserve) # 清除 header offset 20 的 reserved-space 字段 # 加密时该字段 = reserve size,解密后需要归零,否则 SQLite 误判 usable page size page[20] = 0 return bytes(page) else: # Reserve 区填零(SQLite 不读取该区域,清零保持输出干净) return decrypted + b'\x00' * reserve def verify_hmac_page1(page_data, enc_key, page_size, reserve): """验证第1页的 HMAC-SHA1 (SQLCipher 3)""" salt = page_data[:16] mac_salt = bytes([b ^ 0x3a for b in salt]) mac_key = hashlib.pbkdf2_hmac('sha1', enc_key, mac_salt, 2, dklen=32) content = page_data[16:page_size - reserve] iv = page_data[page_size - reserve:page_size - reserve + 16] stored_hmac = page_data[page_size - reserve + 16:page_size - reserve + 36] msg = content + iv + struct.pack(' 有没有新消息 ``` -------------------------------- ### Compile and Use macOS Key Scanner (C) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Instructions for compiling and using the C version of the macOS key scanner, which utilizes Mach VM API to extract database encryption keys from WeChat process memory. Requires Xcode Command Line Tools and specific WeChat signing. ```bash sudo codesign --force --deep --sign - /Applications/WeChat.app ``` -------------------------------- ### Initialize ImageResolver for Decryption Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Initializes an ImageResolver instance for decrypting images. It requires WeChat base directory, decoded directory, a database cache instance, the AES key, and XOR key. ```python from key_utils import strip_key_metadata import json with open("all_keys.json") as f: keys = strip_key_metadata(json.load(f)) # db_cache 是 DBCache 实例(来自 mcp_server.py) resolver = ImageResolver( wechat_base_dir="D:\\xwechat_files\\wxid_xxx", decoded_dir="decoded_images", db_cache=db_cache, aes_key=aes_key, xor_key=0x88, ) result = resolver.decode_image(username="wxid_xxx", local_id=12345) # result = {"success": True, "path": "decoded_images/abc123.jpg", # "format": "JPEG", "size": 102400, "md5": "abc..."} ``` -------------------------------- ### Open WeChat Application Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-permission-guide.md This command opens the WeChat application. It is typically used after resigning the application to allow the user to log in again, which is required for the new signature to be fully effective for the running process. ```bash open /Applications/WeChat.app ``` -------------------------------- ### Database Structure Overview Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Provides a high-level overview of the SQLite databases generated after decryption, detailing key databases like session.db, contact.db, message databases, and media databases. ```plaintext decrypted/ ├── session/session.db # 会话列表(SessionTable: username, unread_count, summary, last_timestamp) ├── contact/contact.db # 联系人(contact: username, nick_name, remark, extra_buffer) │ # 联系人标签(contact_label: label_id_, label_name_, sort_order_) ├── message/ │ ├── message_0.db # 聊天记录分片(Msg_: local_id, local_type, create_time, │ ├── message_1.db # real_sender_id, message_content, WCDB_CT_message_content) │ ├── message_resource.db # 图片资源索引(packed_info 含 MD5,映射 local_id → .dat 路径) │ └── message_fts_*.db # 全文索引 ├── media_*/ │ └── media_*.db # 语音数据(VoiceInfo: chat_name_id, local_id, voice_data, create_time) ├── emoticon/emoticon.db # 表情包(kNonStoreEmoticonTable: md5, aes_key, cdn_url) ├── head_image/ # 头像 ├── favorite/ # 收藏 └── sns/ # 朋友圈 ``` -------------------------------- ### Manual MCP Server Configuration Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Manually configures the MCP server settings by editing the ~/.claude.json file. This is an alternative to the command-line registration. ```json { "mcpServers": { "wechat": { "type": "stdio", "command": "python", "args": ["C:\\Users\\你的用户名\\wechat-decrypt\\mcp_server.py"] } } } ``` -------------------------------- ### Search Contacts by Query Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Searches for contacts based on a query string that matches nicknames, remarks, or wxids. If the query is empty, it lists all contacts. Returns wxid, remark, and nickname. ```python result = get_contacts(query="张", limit=20) ``` -------------------------------- ### Load WeChat Configuration Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt The `load_config()` function reads path configurations from `config.json`. It automatically detects the WeChat data directory if not found and writes the result back to the config file. ```python from config import load_config cfg = load_config() # 返回示例: # { # "db_dir": "D:\\xwechat_files\\wxid_xxx\\db_storage", # "keys_file": "C:\\wechat-decrypt\\all_keys.json", # "decrypted_dir": "C:\\wechat-decrypt\\decrypted", # "wechat_process": "Weixin.exe", # "wechat_base_dir": "D:\\xwechat_files\\wxid_xxx", # "transcription_backend": "local", # "local_whisper_model": "base", # } # 手动覆盖配置文件路径:直接编辑 config.json # { # "db_dir": "D:\\xwechat_files\\你的微信ID\\db_storage", # "keys_file": "all_keys.json", # "decrypted_dir": "decrypted", # "wechat_process": "Weixin.exe" # } print(cfg["db_dir"]) print(cfg["wechat_base_dir"]) ``` -------------------------------- ### Verify Decrypted SQLite Database Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md Use this command to verify if the decrypted database file is a valid SQLite 3.x database. This helps confirm the decryption process was successful. ```bash sqlite3 decrypted/Message/msg_0.db "SELECT COUNT(*) FROM (SELECT name FROM sqlite_master WHERE type='table')" ``` -------------------------------- ### Run Chat Export Scripts Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/chat_export_format.md Commands to run the chat export and transcription scripts. The export script handles raw data, while the transcribe script uses Whisper for voice message transcription. ```bash .venv/bin/python3 export_chat.py [output.json] .venv/bin/python3 transcribe_chat.py [output.json] ``` -------------------------------- ### Register MCP Server for Claude Code Integration Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Provides commands to register the MCP Server with Claude Code, enabling direct querying of WeChat data within conversations. This can be done via the 'claude mcp add' command or by manually editing the .claude.json configuration file. ```bash # 注册到 Claude Code claude mcp add wechat -- python C:\\Users\\你的用户名\\wechat-decrypt\\mcp_server.py # 或手动编辑 ~/.claude.json # { # "mcpServers": { # "wechat": { # "type": "stdio", # "command": "python", # "args": ["C:\\Users\\你的用户名\\wechat-decrypt\\mcp_server.py"] # } # } # } ``` -------------------------------- ### Extract All Database Keys Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt This script scans WeChat process memory to find database encryption keys. It uses platform-specific methods (ReadProcessMemory, /proc//mem, Mach VM API) and verifies keys using HMAC-SHA512, saving them to `all_keys.json`. ```bash # Windows / Linux:直接运行 python find_all_keys.py # 输出 all_keys.json,格式如下: # { # "message/message_0.db": {"enc_key": "aabbcc...", "salt": "1122..."}, # "session/session.db": {"enc_key": "ddeeff...", "salt": "3344..."}, # ... # "_db_dir": "D:\\xwechat_files\\wxid_xxx\\db_storage" # 元数据,防止换账号复用旧密钥 # } # macOS:先编译 C 版扫描器 cc -O2 -o find_all_keys_macos find_all_keys_macos.c -framework Foundation # 重签名(首次及微信升级后各一次) sudo codesign --force --deep --sign - /Applications/WeChat.app # 运行(自动查找微信 PID,扫描内存,匹配 DB salt) sudo ./find_all_keys_macos # 或指定 PID sudo ./find_all_keys_macos 12345 # 输出同样是 all_keys.json,直接用 decrypt_db.py 解密: python3 decrypt_db.py ``` -------------------------------- ### Extract Image Keys (Windows/Linux Monitor) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Continuously monitors the WeChat process to extract AES keys for decrypting V2 format image files. It's recommended to open 2-3 images in WeChat before running this script. ```bash # 1. 在微信中打开查看 2-3 张图片(点击看大图) # 2. 立即运行密钥提取(持续监控版): python find_image_key_monitor.py ``` -------------------------------- ### Register MCP Server for Claude AI Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Registers the WeChat data query capability with Claude Code. This command assumes your Python script is located at the specified path. ```bash claude mcp add wechat -- python C:\Users\你的用户名\wechat-decrypt\mcp_server.py ``` -------------------------------- ### Extract Image Keys (Windows/Linux Single Scan) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Performs a single scan of the WeChat process memory to extract AES keys for decrypting V2 format image files. Run this immediately after viewing images in WeChat if the monitor script fails. ```bash # 或单次扫描版: python find_image_key.py ``` -------------------------------- ### Execute Key Extraction Script via SSH (Ad-hoc Signed WeChat) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-permission-guide.md When WeChat is ad-hoc signed (e.g., after applying patches), you can execute key extraction scripts directly via SSH using sudo. This scenario requires minimal additional permissions. ```bash sudo ./find_all_keys_macos ``` -------------------------------- ### Extract WeChat Image AES Key (Windows/Linux) Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Provides commands to extract the AES key for image decryption from WeChat processes. Use the monitor version for continuous monitoring or the single scan version for a one-time extraction. ```bash # 提取图片 V2 AES 密钥(Windows/Linux,从微信进程内存) # python find_image_key_monitor.py # 持续监控版(推荐) # python find_image_key.py # 单次扫描版 ``` -------------------------------- ### MCP Server API Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Documentation for the MCP Server, which integrates WeChat data querying capabilities with Claude Code. It lists the available tools for interacting with WeChat data, such as retrieving recent sessions, chat history, and searching messages. ```APIDOC ## MCP Server `mcp_server.py` Based on FastMCP (stdio transport), this server integrates WeChat data querying capabilities into Claude Code. After registration, you can directly call the following tools in conversations: `get_recent_sessions`, `get_chat_history`, `search_messages`, `get_contacts`, `get_contact_tags`, `get_tag_members`, `get_new_messages`, `get_voice_messages`, `decode_voice`, `transcribe_voice`, `decode_image`, `decode_file_message`, `decode_record_item`, `get_chat_images`. Internally, it uses `DBCache` (mtime driven, cross-process restart reuse) to decrypt databases on demand and incrementally patches WAL files. ### Registration ```bash # Register to Claude Code claude mcp add wechat -- python C:\Users\YourUsername\wechat-decrypt\mcp_server.py # Or manually edit ~/.claude.json # { # "mcpServers": { # "wechat": { # "type": "stdio", # "command": "python", # "args": ["C:\\Users\\YourUsername\\wechat-decrypt\\mcp_server.py"] # } # } # } ``` ### `get_recent_sessions(limit)` — Get Recent Sessions Retrieves summary information for the N most recent sessions, including the latest message, unread count, and timestamp, for a quick overview of active contacts and group chats. ```python # Call within Claude Code result = get_recent_sessions(limit=10) # Example text response: # Recent 10 sessions: # # [03-03 10:25] AI讨论群 [Group] (7 unread) # Text: 张三: Claude max plan is gone # # [03-03 09:40] File Transfer Assistant # Image: (no content) ``` ### `get_chat_history(chat_name, limit, offset, start_time, end_time, oldest_first)` — Get Chat History Retrieves message records by chat object name (supports fuzzy matching of remarks, nicknames, wxid), with support for time range filtering and pagination. Messages are automatically merged across shards. Images display the `local_id` for subsequent `decode_image` calls. ```python # Get the last 50 messages result = get_chat_history(chat_name="AI讨论群", limit=50) # Query within a time range and paginate (get March messages, 20 per page) result = get_chat_history( chat_name="AI讨论群", start_time="2026-03-01", end_time="2026-03-31", limit=20, offset=0, oldest_first=True, # Sort chronologically ) # Example text response: # Message history for AI讨论群 (20 messages returned, offset=0, limit=20) [Group Chat] # Time range: 2026-03-01 ~ 2026-03-31 # # [2026-03-01 10:31] 李四: My crayfish also use API access # [2026-03-01 10:45] 王五: [Image] (local_id=102345, ts=1740820056) ``` ### `search_messages(keyword, chat_name, start_time, end_time, limit, offset)` — Search Messages Performs keyword search across the entire database or within a specific chat object. `chat_name` can be empty (entire database), a single string, or a list of strings (for searching across multiple chat objects). Supports time range filtering and pagination, returning a maximum of 500 messages per request. ```python # Search entire database result = search_messages(keyword="Claude", limit=20) ``` ``` -------------------------------- ### Extract Encryption Keys using Frida (3.x / Universal) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md Attach Frida to the WeChat process to manually dump memory and search for the 32-byte raw key. This method is compatible with both 3.x and 4.x versions. ```bash sudo frida -p $(pgrep -x WeChat) -l scan_keys.js ``` -------------------------------- ### Verify SSH Full Disk Access (FDA) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-permission-guide.md After configuring FDA for SSH, this command checks if the SSH process can access protected TCC database files. Successful access indicates that FDA is correctly configured for SSH. ```bash cat ~/Library/Application\ Support/com.apple.TCC/TCC.db > /dev/null 2>&1 && echo "FDA: YES" || echo "FDA: NO" ``` -------------------------------- ### get_contacts Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Searches for contacts by a query string. Returns contact's wxid, remark, and nickname. ```APIDOC ## get_contacts(query, limit) ### Description Searches for contacts by a query string. Returns contact's wxid, remark, and nickname. If the query is empty, it lists all contacts. ### Method `get_contacts(query, limit)` ### Parameters #### Query Parameters - **query** (string) - Optional - The keyword to search for (matches nickname, remark, or wxid). If empty, lists all contacts. - **limit** (integer) - Optional - The maximum number of contacts to return. ### Request Example ```python result = get_contacts(query="张", limit=20) ``` ### Response Example ``` # Example response: # 找到 5 个联系人(搜索: 张): # # wxid_abc123 备注: 张三 昵称: 小张 # wxid_def456 备注: 张总 昵称: CEO ``` ``` -------------------------------- ### Interact with WeChat Web UI API Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Demonstrates how to fetch recent messages, filter history by chat and time, and subscribe to real-time message updates using the Web UI's HTTP API. ```python import requests, json # 拉取最近消息 resp = requests.get("http://localhost:5678/api/history") messages = resp.json() # [{"time": "2025-03-03 10:25", "chat": "技术群", "sender": "张三", "text": "hello"}, ...] # 按群名过滤 + 增量拉取 resp = requests.get("http://localhost:5678/api/history", params={ "chat": "AI讨论群", "since": 1740000000, "limit": 50, }) # SSE 实时订阅 import sseclient resp = requests.get("http://localhost:5678/stream", stream=True) client = sseclient.SSEClient(resp) for event in client.events(): msg = json.loads(event.data) print(f"[{msg['chat']}] {msg['sender']}: {msg['text']}") ``` -------------------------------- ### Derive Image Keys (macOS) Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/README.md Derives AES keys for decrypting V2 format image files on macOS by analyzing disk cache files. This method does not require scanning process memory and works without root privileges. ```bash python find_image_key_macos.py ``` -------------------------------- ### Extract WeChat Image AES Key (macOS) Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Instructions for extracting the AES key on macOS by deriving it from the disk kvcomm cache. No memory scanning is required. ```bash # 提取图片 AES 密钥(macOS,从磁盘 kvcomm 缓存派生,无需扫描内存) # python find_image_key_macos.py # 算法:aes_key = MD5(str(code) + cleaned_wxid)[:16],xor_key = code & 0xFF ``` -------------------------------- ### Terminate WeChat Process Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-permission-guide.md Ensures that the WeChat application is not running before attempting to resign it. Resigning a running application can lead to errors or an ineffective signature. ```bash kill $(pgrep -x WeChat) 2>/dev/null ``` -------------------------------- ### Decrypt WeChat Image .dat Files Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Handles three .dat image encryption formats: old XOR, V1 (AES-ECB + XOR), and V2 (AES-128-ECB + XOR). V2 requires deriving the key from process memory or cache. `ImageResolver` integrates DB queries with decryption logic. ```python from decode_image import decrypt_dat_file, is_v2_format, detect_xor_key, ImageResolver ``` -------------------------------- ### Search Messages by Keyword and Time Range Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Searches messages within a specified chat name and time range. Supports a single chat name or a list of chat names for combined searches. ```python result = search_messages( keyword="项目", chat_name="AI讨论群", start_time="2026-03-01", end_time="2026-03-07", limit=20, offset=0, ) ``` ```python result = search_messages( keyword="发票", chat_name=["财务群", "老板", "HR群"], start_time="2026-01-01", limit=50, ) ``` -------------------------------- ### Search for Contacts Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/USAGE.md Find contacts by searching for a part of their name. The system calls `get_contacts` with a query parameter. ```text > 帮我找一下姓张的联系人 ``` -------------------------------- ### Remote Resigning WeChat via SSH Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-permission-guide.md This sequence of commands outlines the process for resigning the WeChat application with an ad-hoc signature via SSH. This is necessary when WeChat has Apple's official signature and requires SSH access for key extraction. ```bash # 0. 前提:SSH 已有 FDA(上面的步骤) # 1. 确认微信已退出 kill $(pgrep -x WeChat) 2>/dev/null sleep 2 pgrep -x WeChat && echo "还在运行!" || echo "已退出" # 2. 清除扩展属性(可选,防止干扰) sudo xattr -cr /Applications/WeChat.app # 3. Ad-hoc 重签名 sudo codesign --force --deep --sign - /Applications/WeChat.app # 4. 验证签名 codesign -dv /Applications/WeChat.app 2>&1 | grep -E "Signature|flags" # 期望: flags=0x2(adhoc), Signature=adhoc # 5. 用户需在 GUI 上重新打开微信并登录 # (或者 SSH 执行 open,但用户仍需在 GUI 上完成登录) open /Applications/WeChat.app ``` -------------------------------- ### WeChat 3.x Decryption Parameters Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md Defines the SQLCipher 3 specific parameters required for decrypting WeChat 3.x databases, including page size, reserve size, KDF iterations, and HMAC algorithm. ```python # SQLCipher 3 parameters PAGE_SIZE = 1024 RESERVE = 48 # 16(IV) + 20(HMAC-SHA1) + 12(padding) KDF_ITER = 64000 HMAC_ALGO = 'sha1' HMAC_LEN = 20 ``` -------------------------------- ### Top-Level JSON Structure Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/chat_export_format.md The root of the chat export JSON. It includes chat metadata and a list of messages. Optional fields like 'is_group' are omitted when not applicable. ```json { "chat": "", "username": "", "exported_at": "YYYY-MM-DD HH:MM:SS", "is_group": true, "messages": [ ... ] } ``` -------------------------------- ### Check WeChat Signature Status Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-permission-guide.md Use this command to inspect the code signature of the WeChat application. This helps determine if the application has been modified or is using Apple's official signature, which affects permission requirements. ```bash codesign -dv /Applications/WeChat.app 2>&1 | grep -E "Signature|flags" ``` -------------------------------- ### Decrypt WeChat DAT Files Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Decrypts WeChat DAT files using either automatic XOR key detection or a provided AES key for V2 format. Requires the path to the DAT file and optionally the key. ```python dat_path = "D:\\xwechat_files\\wxid_xxx\\msg\\attach\\\\2025-01\\Img\\abc123_t.dat" print(is_v2_format(dat_path)) # True → V2 格式;False → 旧格式或 V1 # 旧 XOR 格式:自动检测 key 并解密 xor_key = detect_xor_key(dat_path) # 返回 int(如 0x88) 或 None if xor_key is not None: decrypt_dat_file(dat_path, "output.jpg", xor_key=xor_key) # V2 格式:需要 AES key(从 config.json image_aes_key 读取) aes_key = "cfcd208495d565ef" # 16 字节 hex 字符串(来自 find_image_key.py) decrypt_dat_file(dat_path, "output.jpg", aes_key=aes_key, xor_key=0x88) ``` -------------------------------- ### WeChat 4.x Decryption Parameters Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/macos-3x-vs-4x-decryption-guide.md Defines the SQLCipher 4 specific parameters required for decrypting WeChat 4.x databases, including page size, reserve size, KDF iterations, and HMAC algorithm. ```python # SQLCipher 4 parameters PAGE_SIZE = 4096 RESERVE = 80 # 16(IV) + 64(HMAC-SHA512) KDF_ITER = 256000 HMAC_ALGO = 'sha512' HMAC_LEN = 64 ``` -------------------------------- ### get_contact_tags / get_tag_members Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Manages contact tags. `get_contact_tags` lists all tags and their member counts. `get_tag_members` retrieves members of a specific tag. ```APIDOC ## get_contact_tags() / get_tag_members(tag_name) ### Description Manages contact tags. `get_contact_tags` lists all tags and their member counts. `get_tag_members` retrieves members of a specific tag, supporting fuzzy matching for the tag name. ### Methods - `get_contact_tags()`: Lists all contact tags and their associated member counts. - `get_tag_members(tag_name)`: Retrieves all members belonging to a specific tag. ### Parameters #### `get_tag_members` Parameters - **tag_name** (string) - Required - The name of the tag to retrieve members for. Supports fuzzy matching. ### Request Examples ```python # List all tags result = get_contact_tags() # Get members of a specific tag (fuzzy match supported) result = get_tag_members(tag_name="同事") ``` ### Response Examples ``` # Example response for get_contact_tags(): # 共 5 个标签,42 个关联: # [同事] 18人 # [家人] 6人 # [客户] 12人 # Example response for get_tag_members(): # 标签 [同事] 共 18 人: # wxid_xxx 张三 # wxid_yyy 李四 ``` ``` -------------------------------- ### Search WeChat Messages via MCP Server Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Performs keyword searches across all messages or within specific chats, supporting date range filtering and pagination. Can search across multiple chat names simultaneously. ```python # 全库搜索 result = search_messages(keyword="Claude", limit=20) ``` -------------------------------- ### Search Messages by Keyword Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/USAGE.md Find messages containing a specific keyword across all your chats. The system calls `search_messages` with the provided keyword. ```text > 搜一下谁提过"claude" ``` -------------------------------- ### Search Messages Across Multiple Chats Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/USAGE.md Perform a keyword search across multiple specified contacts or group chats within a given time frame. The `chat_name` parameter accepts a list of chat identifiers. ```python search_messages( keyword="项目", chat_name=["联系人A", "联系人B", "██项目群"], start_time="2026-03-01", end_time="2026-03-07", limit=20, offset=0, ) ``` -------------------------------- ### Decode File Message Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Locates local copies of file messages by parsing filenames and MD5 from chat history XML (appmsg type=6). It searches within the 'msg/file/YYYY-MM/' directory and uses MD5 for strong verification. 'decode_record_item' handles embedded files within forwarded messages (appmsg type=19). ```python history = get_chat_history(chat_name="工作群", limit=20) result = decode_file_message( chat_name="工作群", local_id=8888, create_time=1740833200, ) ``` ```python result = decode_record_item( chat_name="工作群", local_id=9999, item_index=0, create_time=1740900000, ) ``` -------------------------------- ### decode_image Source: https://context7.com/ylytdeng/wechat-decrypt/llms.txt Decrypts an image message using its `local_id`. It queries the message resource database for the MD5 hash, locates the corresponding `.dat` file, and decodes it. ```APIDOC ## decode_image(chat_name, local_id) ### Description Decrypts an image message using its `local_id`. It queries the `message_resource.db` for the MD5 hash, locates the corresponding `.dat` file, and automatically decodes it (XOR / V1 / V2), saving the output to the `decoded_images/` directory. ### Parameters #### Path Parameters - **chat_name** (string) - Required - The name of the chat where the image message is located. - **local_id** (integer) - Required - The local ID of the image message, obtained from `get_chat_history`. ### Request Example ```python # First, find the local_id of the image message history = get_chat_history(chat_name="AI讨论群", limit=20) # Example output: [2026-03-01 10:45] 王五: [图片] (local_id=102345, ts=1740820056) # Then, decode the image result = decode_image(chat_name="AI讨论群", local_id=102345) ``` ### Response Example ``` # Example response: # 解密成功! # 文件: C:\wechat-decrypt\decoded_images\abc123def456.jpg # 格式: JPEG # 大小: 102,400 bytes # MD5: abc123def456... ``` ``` -------------------------------- ### Filter Pending Voice Messages for Transcription Source: https://github.com/ylytdeng/wechat-decrypt/blob/main/docs/chat_export_format.md Python list comprehension to filter messages that are of type 'voice' and have not yet been transcribed (i.e., the 'transcription' field is missing). ```python pending = [m for m in data["messages"] if m.get("type") == "voice" and not m.get("transcription")] ```