fix(tng): 修复区号页 HWUI 闪退并放行 Compose HW 绘制
拦截 HardwareRenderer.setName,校验/缓存 libandroid.so,避免软件绘制撞 hardware bitmap;附带 Money Packet hook 与 mitm 脚本。
This commit is contained in:
137
debug-server/tng_mmp_mitm_addon.py
Normal file
137
debug-server/tng_mmp_mitm_addon.py
Normal file
@@ -0,0 +1,137 @@
|
||||
#!/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()]
|
||||
Reference in New Issue
Block a user