feat(maribank): PH 注册 OTP 突破、SG bypass 与中文文档

菲律宾 SeaBank 在 Root+LSPosed+Shamiko 下 register 已通过并触发 OTP;扩展 SG 包名、加密前 Hook、Magisk 设备伪装脚本,并将 docs 整理为中文操作与风控说明。
This commit is contained in:
mars
2026-07-06 14:01:49 +08:00
parent d488a0759f
commit 81119e0ff9
29 changed files with 2248 additions and 102 deletions

View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
import subprocess
import zipfile
from pathlib import Path
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
DEXDUMP = Path(r"C:\Users\Administrator\AppData\Local\Android\Sdk\build-tools\37.0.0\dexdump.exe")
TARGETS = [
"Lcom/shopee/bke/lib/safemode/model/ErrorType;",
"Lcom/shopee/bke/lib/safemode/activity/SafeModeRecoverActivity;",
"Lcom/shopee/bke/lib/safemode/b;",
]
with zipfile.ZipFile(str(APK)) as zf:
for name in zf.namelist():
if not name.endswith(".dex"):
continue
data = zf.read(name)
if not any(t.replace("L", "").replace(";", "").encode() in data for t in TARGETS):
continue
tmp = Path(__file__).resolve().parent.parent / "tmp" / "sg_safemode.dex"
tmp.parent.mkdir(parents=True, exist_ok=True)
tmp.write_bytes(data)
out = subprocess.check_output(
[str(DEXDUMP), "-d", str(tmp)], universal_newlines=True, errors="replace"
)
for target in TARGETS:
if target.replace("L", "").replace(";", "") not in data.decode("latin1", errors="ignore"):
continue
print("=" * 60, name, target)
cap = False
for line in out.splitlines():
if f"Class descriptor : '{target}'" in line:
cap = True
elif cap and line.startswith(" Class descriptor") and target not in line:
break
if cap and ("name :" in line or "const-string" in line or "ErrorType" in line):
print(line.strip()[:140])

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
import re
import zipfile
from pathlib import Path
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
with zipfile.ZipFile(str(APK)) as zf:
data = b"".join(zf.read(n) for n in zf.namelist() if n.endswith(".dex"))
print("=== Adb / SafeMode related classes ===")
for m in re.finditer(rb"L[\w$/]*(Adb|ADB|SafeMode|safemode|Recover)[\w$/]*;", data):
c = m.group().decode()
if "shopee" in c or "bke" in c or "maribank" in c.lower():
print(c)
print("\n=== shpssdk bank ===")
for m in re.finditer(rb"Lcom/shopee/shpssdk[\w$/]*;", data):
print(m.group().decode())
print("\n=== api.seabank / maribank hosts ===")
for m in re.finditer(rb"https?://[a-zA-Z0-9._/-]{8,80}", data):
u = m.group().decode()
if "maribank" in u or "seabank" in u:
print(u)
print("\n=== login/register uapi ===")
for m in re.finditer(rb"/uapi/[a-zA-Z0-9_/-]+", data):
print(m.group().decode())

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
import re
import zipfile
from pathlib import Path
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
with zipfile.ZipFile(str(APK)) as zf:
data = b"".join(zf.read(n) for n in zf.namelist() if n.endswith(".dex"))
for pat in [
b"Does not support",
b"Turn Off ADB",
b"Wireless ADB",
b"ADB/Wireless",
b"support root",
b"RISK_USB_ADB",
b"RISK_WIFI_ADB",
b"KEY_ALLOW_ADB",
b"SafeModeRecover",
b"sg.com.maribank",
]:
print(pat.decode(), "->", data.count(pat))
print("\n--- UI strings ---")
for m in re.finditer(rb"[\x20-\x7e]{10,200}", data):
s = m.group().decode("ascii", "ignore")
sl = s.lower()
if ("adb" in sl and ("detect" in sl or "turn" in sl or "wireless" in sl or "debug" in sl)) or "does not support root" in sl:
print(s)
print("\n--- Application ---")
for m in re.finditer(rb"Lcom/shopee/bke/[\w$/]*Application[\w$/]*;", data):
print(m.group().decode())
print("\n--- ADB risk classes ---")
for m in re.finditer(rb"L[\w$/]*(adb|Adb|ADB)[\w$/]*;", data):
c = m.group().decode()
if "shopee" in c.lower() or "bke" in c.lower() or "shps" in c.lower():
print(c)

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
"""Quick DEX scan for MariBank SG detection / auth strings."""
import re
import sys
import zipfile
from pathlib import Path
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
if len(sys.argv) > 1:
APK = Path(sys.argv[1])
needles = [
b"ADB",
b"Wireless ADB",
b"USB debugging",
b"Wireless debugging",
b"Does not support root",
b"root device",
b"rooted",
b"jailbroken",
b"safemode",
b"SafeMode",
b"shpssdk",
b"SHPSSDK",
b"getRiskToken",
b"requestDefense",
b"BkeApplication",
b"errorcodehandler",
b"4067012",
b"4067004",
b"/uapi/",
b"/dfp/",
b"register",
b"login",
b"auth/precheck",
]
class_needles = [
rb"Lcom/shopee/bke/[\w$/]+;",
rb"Lcom/shopee/shpssdk[\w$/]*;",
]
with zipfile.ZipFile(str(APK)) as zf:
data = b"".join(zf.read(n) for n in zf.namelist() if n.endswith(".dex"))
print("APK:", APK.name, "dex bytes:", len(data))
print("\n=== string hits ===")
for n in needles:
c = data.count(n)
if c:
print(f" {n.decode(errors='replace')!r}: {c}")
print("\n=== api paths (sample) ===")
paths = sorted(set(m.group().decode() for m in re.finditer(rb"/v[0-9]/[a-zA-Z0-9_/-]{4,80}", data)))
for p in paths:
pl = p.lower()
if any(k in pl for k in ("auth", "login", "register", "otp", "dfp", "user", "mobile", "pin")):
print(" ", p)
print("\n=== shopee/bke classes (sample) ===")
classes = sorted(set(m.group().decode() for m in re.finditer(rb"Lcom/shopee/bke/[\w$/]{8,120};", data)))
keywords = ("safemode", "risk", "adb", "debug", "root", "error", "user", "digitalbank", "Application")
shown = 0
for c in classes:
cl = c.lower()
if any(k in cl for k in keywords):
print(" ", c)
shown += 1
if shown >= 40:
break
print(f" ... total bke classes: {len(classes)}")
print("\n=== context: ADB Detected ===")
idx = data.find(b"ADB")
while idx >= 0 and idx < len(data):
chunk = data[max(0, idx - 30) : idx + 80]
if b"Detect" in chunk or b"debug" in chunk.lower() or b"Wireless" in chunk:
s = re.sub(rb"[^\x20-\x7e]+", b" ", chunk).decode("ascii", "ignore").strip()
if len(s) > 20:
print(" ", s[:120])
idx = data.find(b"ADB", idx + 1)
if idx > 0 and data.find(b"ADB", idx + 1) == -1:
break