#!/usr/bin/env python3 """ Hawk Hook(Frida)微信冒烟 — 通过 unified /hook/execute 调用,默认 hook_only。 前置: 1. SDK:`cd sdk/app && python3 -m uvicorn main:app --host 0.0.0.0 --port 8899` 2. 手机 Agent 已 WebSocket 上线,Frida 已注入/附着微信(Gadget 或 Root+frida-server) 3. 环境变量 DEVICE_ID(或下面默认值)与真机一致 用法: DEVICE_ID=dc9c23e00510 python3 hook_wechat_hwk_smoke.py # 发消息(改 TO_ID) DEVICE_ID=xxx TO_ID=文件传输助手 CONTENT=hook测试 python3 hook_wechat_hwk_smoke.py --send """ from __future__ import annotations import argparse import json import os import sys import urllib.error import urllib.request BASE = os.environ.get("SDK_BASE", "http://127.0.0.1:8899") DEVICE_ID = os.environ.get("DEVICE_ID", "dc9c23e00510") def post(path: str, body: dict, timeout: float = 60.0) -> dict: url = f"{BASE.rstrip('/')}{path}" data = json.dumps(body).encode("utf-8") req = urllib.request.Request( url, data=data, headers={"Content-Type": "application/json"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: return json.loads(resp.read().decode("utf-8")) except urllib.error.HTTPError as e: raw = e.read().decode("utf-8", errors="replace") try: return json.loads(raw) except json.JSONDecodeError: return {"code": e.code, "error": raw} except urllib.error.URLError as e: return {"code": 0, "error": str(e.reason)} def main() -> int: p = argparse.ArgumentParser() p.add_argument("--send", action="store_true", help="执行 send_message(需 TO_ID/CONTENT)") args = p.parse_args() steps = [ ("get_hook_status", {}), ("get_wechat_version", {}), ("get_process_info", {}), ("check_login_state", {}), ("get_profile", {}), ("get_contacts", {"limit": 5}), ] if args.send: to_id = os.environ.get("TO_ID", "") content = os.environ.get("CONTENT", "Hawk Hook 冒烟") if not to_id: print("请设置 TO_ID(好友备注/昵称或会话标识)", file=sys.stderr) return 2 steps.append(("send_message", {"to_id": to_id, "content": content})) print(f"BASE={BASE} DEVICE_ID={DEVICE_ID}\n") for action, params in steps: body = { "device_id": DEVICE_ID, "platform": "wechat", "action": action, "params": params, "hook_only": True, } r = post("/api/v3/hook/execute", body, timeout=120.0) ch = r.get("channel_used") data = r.get("data") ok = False if isinstance(data, dict): ok = data.get("success", data.get("code") == 200) print(f"=== {action} ===") print(json.dumps(r, ensure_ascii=False, indent=2)[:4000]) if not ok and r.get("code") not in (200,): print(f"[WARN] {action} 可能未成功,请查 Agent 日志 / Frida 是否附着微信", file=sys.stderr) print() return 0 if __name__ == "__main__": raise SystemExit(main())