wechat-messaging-attack-surface.md 5.78 KB

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:

  1. Copy + decrypt EnMicroMsg.db
  2. Inspect message table schema for status/send_state columns
  3. INSERT test message row
  4. 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 handler
  • com.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.

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) module
  • mars::comm — common utilities, message queue
  • mars::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 d field (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.