chore: 清理临时逆向脚本,保留 TNG 安装工具与 captcha 文档

删除未跟踪的一次性 _*.py 扫描脚本,并从仓库移除已过时辅助脚本。
This commit is contained in:
mars
2026-08-04 13:48:47 +08:00
parent bc51fb35cc
commit f9426d6b68
9 changed files with 246 additions and 77 deletions

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env python3
import re
import sys
import xml.etree.ElementTree as ET
path = sys.argv[1]
root = ET.parse(path).getroot()
def center(b):
m = re.match(r"\[(\d+),(\d+)\]\[(\d+),(\d+)\]", b or "")
if not m:
return None
x1, y1, x2, y2 = map(int, m.groups())
return (x1 + x2) // 2, (y1 + y2) // 2
for n in root.iter("node"):
t = n.get("text") or ""
pt = center(n.get("bounds"))
if pt and 600 <= pt[1] <= 800:
print(repr(t), pt, "PIN" in t.upper(), "6位" in t)

View File

@@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import re
import sys
path = sys.argv[1] if len(sys.argv) > 1 else r"reverse/dumps/ui_login_now.xml"
root = ET.parse(path).getroot()
for n in root.iter("node"):
rid = n.attrib.get("resource-id", "")
text = n.attrib.get("text", "")
desc = n.attrib.get("content-desc", "")
click = n.attrib.get("clickable")
bounds = n.attrib.get("bounds")
blob = (rid + " " + text + " " + desc).lower()
if any(k in blob for k in ("country", "ll_country", "+60", "calling", "flag")):
print("HIT", rid, repr(text), repr(desc), click, bounds)
if text and (("+" in text[:3]) or text.strip() in ("PIN",) or "Malaysia" in text):
print("TEXT", repr(text), bounds, click, rid)
# print clickable centers for ll_country
for n in root.iter("node"):
rid = n.attrib.get("resource-id", "")
if "ll_country" in rid and n.attrib.get("clickable") == "true":
m = re.match(r"\[(\d+),(\d+)\]\[(\d+),(\d+)\]", n.attrib.get("bounds", ""))
if m:
x1, y1, x2, y2 = map(int, m.groups())
print("TAP", (x1 + x2) // 2, (y1 + y2) // 2, rid)

View File

@@ -1,15 +0,0 @@
#!/usr/bin/env python3
import sys
import xml.etree.ElementTree as ET
path = sys.argv[1] if len(sys.argv) > 1 else "/sdcard/tng_ui.xml"
root = ET.parse(path).getroot()
for n in root.iter("node"):
t = (n.get("text") or "").strip()
rid = n.get("resource-id") or ""
desc = (n.get("content-desc") or "").strip()
c = n.get("clickable") == "true"
b = n.get("bounds") or ""
if t or rid or desc:
if t or "tv_" in rid or "country" in rid.lower() or "PIN" in (t + desc).upper():
print(f"text={t!r} rid={rid} desc={desc!r} click={c} {b}")

View File

@@ -1,15 +0,0 @@
import zipfile
import re
z = zipfile.ZipFile(r"reverse/dumps/tng_1.9.10_base.apk")
names = [n for n in z.namelist() if n.endswith(".dex")]
print("dex files", names)
pat = re.compile(rb"Lxwwqazamx/[^;\s]{1,60};")
found = set()
for n in names:
data = z.read(n)
for m in pat.findall(data):
found.add(m.decode("ascii", errors="ignore"))
print("xwwqazamx classes", len(found))
for c in sorted(found):
print(c)

View File

@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Download TNG eWallet XAPK from Uptodown eAPI (arm64-v8a)."""
from __future__ import annotations
import json
import re
import subprocess
import sys
import urllib.request
import zipfile
from pathlib import Path
UA = "Mozilla/5.0 (Linux; Android 13) Chrome/120.0.0.0 Mobile Safari/537.36"
APP_CODE = "1000382462"
VERSION = "1.9.10"
ARCH = "arm64-v8a, armeabi-v7a, x86_64"
BASE = "https://touch-n-go-ewallet.en.uptodown.com"
OUT_XAPK = Path("reverse/dumps/tng_1.9.10.xapk")
OUT_DIR = Path("reverse/dumps/tng_xapk_extracted")
def fetch(url: str) -> bytes:
req = urllib.request.Request(url, headers={"User-Agent": UA})
with urllib.request.urlopen(req, timeout=120) as resp:
return resp.read()
def fetch_text(url: str) -> str:
return fetch(url).decode("utf-8", "ignore")
def main() -> int:
versions = json.loads(fetch_text(f"{BASE}/android/apps/{APP_CODE}/versions/1"))
entry = next(x for x in versions["data"] if x["version"] == VERSION)
version_id = entry["versionURL"]["versionID"]
print(f"version {VERSION} fileID={entry['fileID']} kind={entry['kindFile']}")
dl_page = fetch_text(f"{BASE}/android/download/{version_id}")
m = re.search(r'class="button variants" data-version="(\d+)"', dl_page)
if not m:
print("variants data-version not found", file=sys.stderr)
return 1
data_version = m.group(1)
print("data_version", data_version)
files_json = json.loads(fetch_text(f"{BASE}/app/{APP_CODE}/version/{data_version}/files"))
content = files_json.get("content", "")
# parse variant rows from HTML fragment
rows = re.findall(
r'class="variant".*?data-file-id="(\d+)".*?<span>([^<]+)</span>',
content,
flags=re.S,
)
if not rows:
# fallback: any data-file-id near xapk
rows = re.findall(r'data-file-id="(\d+)"', content)
rows = [(rid, "?") for rid in rows]
print("variants", rows)
target_file_id = None
for fid, arch in rows:
if ARCH in arch or "arm64-v8a" in arch:
target_file_id = fid
print("pick", fid, arch)
break
if not target_file_id and rows:
target_file_id = rows[0][0]
print("fallback file_id", target_file_id)
if not target_file_id:
print("no file id", file=sys.stderr)
return 1
variant_page = fetch_text(f"{BASE}/android/download/{target_file_id}-x")
token_m = re.search(r'id="detail-download-button"[^>]*data-url="(-[^"]+)"', variant_page)
if not token_m:
token_m = re.search(r'data-url="(-[^"]+)"', variant_page)
if not token_m:
print("download token not found", file=sys.stderr)
return 1
token = token_m.group(1)
print("downloading XAPK...")
data = fetch(f"https://dw.uptodown.com/dwn/{token}")
OUT_XAPK.write_bytes(data)
print("saved", OUT_XAPK, "bytes", len(data))
with zipfile.ZipFile(OUT_XAPK) as z:
apks = [n for n in z.namelist() if n.endswith(".apk")]
print("apk splits", apks)
if not apks:
print("no apk inside xapk", file=sys.stderr)
return 1
if OUT_DIR.exists():
import shutil
shutil.rmtree(OUT_DIR)
OUT_DIR.mkdir(parents=True)
import zipfile as zf
with zf.ZipFile(OUT_XAPK) as z:
z.extractall(OUT_DIR)
apk_files = sorted(OUT_DIR.rglob("*.apk"))
adb = r"C:\Users\Administrator\AppData\Local\Android\Sdk\platform-tools\adb.exe"
cmd = [adb, "install-multiple", "-r"] + [str(p) for p in apk_files]
print("install:", " ".join(cmd))
r = subprocess.run(cmd, capture_output=True, text=True)
print(r.stdout)
print(r.stderr)
return 0 if r.returncode == 0 else r.returncode
if __name__ == "__main__":
raise SystemExit(main())