WeChat Message Sending — Attack Surface Analysis
Date: 2026-06-30 WeChat: 8.0.74, Android 16, Magisk root Context: After completing XHS BCIM architecture analysis, user wants same framework applied to WeChat.
1. Architecture
Java UI: ChattingUI (message compose → send)
↓
Java Storage: EnMicroMsg.db message table (status: sending)
↓
JNI Bridge: libMMProtocalJni.so (serialize + encrypt)
↓
mars Framework (C++ native):
libmarscomm.so — task dispatch, STN queue
libmarsquic.so — QUIC long connection
libproto.so — protobuf encode/decode
libMMProtocalJni.so — JNI entry point
↓ TCP/QUIC → WeChat Server
Protocol: Protobuf over mars long connection, ECDH key exchange + AES encryption. Key difference from XHS: mars is C++ native (not Java), protobuf (not JSON), encrypted (XHS BCIM isn't).
2. Local Assets Available
| Asset | Path | Status |
|---|---|---|
| EnMicroMsg.db | /MicroMsg/<hash>/ 20MB |
SQLCipher encrypted |
| UIN | auth_info_key_prefs.xml |
Extracted |
| Auth Key | auth_info_key_prefs.xml |
Protobuf binary |
| mars config | files/XNetLib/ |
Present |
| APK | /data/app/.../base.apk |
Extractable |
| Native libs | libmarscomm.so, libmarsquic.so, libMMProtocalJni.so, libproto.so |
Symbol analysis possible |
3. Attack Vectors (ranked by feasibility)
Path A: Database Injection ⭐ Most Promising
Hypothesis: WeChat stores pending messages in EnMicroMsg.db before mars picks them up. INSERTing a row with status=sending may trigger mars to send it automatically.
Steps:
- Copy + decrypt EnMicroMsg.db
- Inspect message table schema for status/send_state columns
- INSERT test message row
- Monitor if mars picks it up (check status change or network activity)
Risk: mars may verify message origin, but historical WeChat versions had this vulnerability.
Path B: LSPosed Java Hook (xhshook pattern)
Target classes (based on known WeChat structure):
com.tencent.mm.model.c— core message handlercom.tencent.mm.plugin.messenger.foundation.a.a.j— send interface- Note: heavily ProGuard-obfuscated, class names are single letters
Advantage: xhshook v3 framework proven, only need to find hook point. Disadvantage: Needs jadx decompilation first; class names obfuscated.
Path C: mars Task Queue Injection
Hook native mars::stn::NetSource::StartTask() to inject serialized protobuf tasks.
Requires: protobuf schema reverse engineering, Frida native hook.
Difficulty: High — C++ native, protocol may change.
Path D: HTTP Fallback API
WeChat uses HTTPS for CDN/assets. If message send has HTTP fallback, bypass mars entirely. Verification: jadx decompile + xhshook capture. Likelihood: Low — core messaging is mars-only by design.
Path E: Full Protocol Reverse Engineering
Hook libMMProtocalJni.so → capture proto before encryption → reverse schema → build messages.
Obstacles: WeChat anti-Frida (more mature than XHS libsentry), frequent proto changes.
4. Recommended Execution Order
Step 1: Decrypt EnMicroMsg.db → inspect message table for sending queue (30 min)
↓ IF DB injection works
Step 2: INSERT test message → verify send (1 hour)
↓ ELSE
Step 3: jadx decompile → find Java send entry → xhshook hook (days)
5. Comparison: XHS BCIM vs WeChat mars
| Aspect | XHS 私信 | WeChat 消息 |
|---|---|---|
| Transport | Longlink (Java) | mars (C++ native) |
| Encoding | JSON | Protobuf |
| Encryption | None extra | ECDH + AES |
| OkHttp blind | ✅ | ✅ |
| DB injection | Low (WCDB checks) | Medium (history) |
| Community docs | Almost none | Some (mars open-source) |
| Anti-tamper | libxyass + libsentry | More sophisticated |
| Hook surface | Java BCIMClientAdapterImpl | JNI + C++ native |
6. Key File Paths (for future jadx)
com/tencent/mm/model/c.java — core message
com/tencent/mm/modelmulti/ — message sync
com/tencent/mm/plugin/messenger/ — messenger plugin
com/tencent/mm/protocal/ — protocol layer
com/tencent/mm/network/ — networking (Java side)
7. mars Open-Source Reference
mars is open-source: https://github.com/Tencent/mars Key components:
mars::stn— Short Network Task (STN) modulemars::comm— common utilities, message queuemars::cdn— CDN module (used for image/file upload)mars::app— application layer callbacks
Understanding mars source helps identify hook points in WeChat's compiled libs.
8. DEX Analysis Results (WeChat 8.0.74 Tinker patch, classes12.dex)
From analyze_wechathook.py run on 2026-07-03:
gm0.j1 — DI container singleton:
- Static field
m: Lgm0/j1;— the singleton instance gm0.j1.i() → Lgm0/j1;— SINGLETON ACCESSOR (sget-object on field m).gm0.j1.g(Lkm0/c;)V— init method. Hooked but never fires in 8.0.74.
w11.r0 — NOT the real send path:
- Constructors:
(String,String,int,int,long)and(String,String,int,int,Object) - Never called by WeChat itself during normal send.
- Calling manually: NPE in main process, "Kernel not initialized" elsewhere.
sk.p0(String,int,String) — REAL send entry:
com.tencent.mm.ui.chatting.component.sk— SendTextComponent- Needs
dfield (Lyb5/d chat context) initialized — unavailable without ChattingUI open. - Full analysis:
frida-android-setup→references/wechat-internal-send-api.md
9. WeChat Restart Pitfall
Do NOT force-stop or restart WeChat without explicit user permission.
am force-stop + am start kills the login session. WeChat requires re-authentication
after restart. If using LSPosed module for tablet/alternate login, session loss means
manual re-login. Before any action that might restart WeChat, ask the user.