Files
notiMessage/debug-server/tng_mmp_mitm_addon.py
mars 5378a34f58 fix(tng): 修复区号页 HWUI 闪退并放行 Compose HW 绘制
拦截 HardwareRenderer.setName,校验/缓存 libandroid.so,避免软件绘制撞 hardware bitmap;附带 Money Packet hook 与 mitm 脚本。
2026-08-04 12:26:27 +08:00

138 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
mitmproxy 插件:自动保存 TNG Money Packet 含 receiverList 的 API 响应。
用法:
mitmdump -s debug-server/tng_mmp_mitm_addon.py -p 8888
mitmweb -s debug-server/tng_mmp_mitm_addon.py -p 8888
手机 WiFi 代理 -> PC_IP:8888安装 mitmproxy CA 后打开 TNG 红包 Leaderboard。
命中响应会打印到终端,并写入 reverse/dumps/mitm_mmp/
"""
from __future__ import annotations
import json
import os
import re
from datetime import datetime
from mitmproxy import ctx, http
OUTPUT_DIR = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"reverse",
"dumps",
"mitm_mmp",
)
MMP_HINTS = (
"receiverlist",
"claimedamount",
"mmpreceiver",
"moneypacket",
"merchantmoneypacket",
)
HOST_HINTS = (
"ebuckler.com",
"tngdigital.com",
"alipaydev.com",
)
def _ensure_dir() -> None:
os.makedirs(OUTPUT_DIR, exist_ok=True)
def _looks_like_mmp(body: str) -> bool:
lower = body.lower()
if any(h in lower for h in MMP_HINTS):
return True
return "mmp" in lower and "amount" in lower
def _extract_receiver_list(obj):
"""递归找 receiverList 并格式化为 [(nickname, amount), ...]"""
rows = []
def walk(node):
if isinstance(node, dict):
if "receiverList" in node and isinstance(node["receiverList"], list):
for item in node["receiverList"]:
if not isinstance(item, dict):
continue
name = (
item.get("nickName")
or item.get("displayName")
or item.get("userName")
or item.get("receiverName")
or item.get("name")
)
amount = (
item.get("claimedAmount")
or item.get("receiveAmount")
or item.get("amount")
)
if name and amount is not None:
rows.append((str(name), str(amount)))
for v in node.values():
walk(v)
elif isinstance(node, list):
for v in node:
walk(v)
walk(obj)
return rows
class TngMmpCapture:
def __init__(self) -> None:
_ensure_dir()
self.count = 0
ctx.log.info(f"TNG MMP capture -> {OUTPUT_DIR}")
def response(self, flow: http.HTTPFlow) -> None:
if flow.response is None or not flow.response.content:
return
host = (flow.request.host or "").lower()
if not any(h in host for h in HOST_HINTS):
return
try:
text = flow.response.get_text(strict=False)
except Exception:
return
if not text or not _looks_like_mmp(text):
return
self.count += 1
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
safe_host = re.sub(r"[^\w.-]", "_", host)[:40]
path = os.path.join(OUTPUT_DIR, f"mmp_{ts}_{self.count}_{safe_host}.json")
summary_lines = [
f"[TNG-MMP #{self.count}] {flow.request.method} {flow.request.url}",
]
try:
data = json.loads(text)
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
rows = _extract_receiver_list(data)
if rows:
summary_lines.append(f" receiverList ({len(rows)} 条):")
for name, amount in rows:
summary_lines.append(f" {name} -> {amount}")
else:
summary_lines.append(" (JSON 已保存,未解析到 receiverList)")
except json.JSONDecodeError:
with open(path, "w", encoding="utf-8") as f:
f.write(text)
summary_lines.append(" (非 JSON已保存原文)")
summary_lines.append(f" saved: {path}")
ctx.log.info("\n".join(summary_lines))
addons = [TngMmpCapture()]