# -*- coding: utf-8 -*- """Spawn TNG eWallet with Frida native exit blockers.""" import subprocess import sys import time from datetime import datetime from pathlib import Path import frida PKG = "my.com.tngdigital.ewallet" HERE = Path(__file__).resolve().parent LOGS_DIR = HERE.parent / "logs" / "frida" LOGS_DIR.mkdir(parents=True, exist_ok=True) SCRIPT = HERE / "trace_tng_native_exit.js" LOG = LOGS_DIR / ("tng_native_%s.log" % datetime.now().strftime("%Y%m%d_%H%M%S")) ADB = r"C:\Users\Administrator\AppData\Local\Android\Sdk\platform-tools\adb.exe" HOLD_SEC = 45 def on_message(message, data): mtype = message.get("type") if mtype == "send": line = message.get("payload") elif mtype == "log": line = message.get("payload", "") else: line = str(message) text = line if isinstance(line, str) else repr(line) print(text, flush=True) with open(LOG, "a", encoding="utf-8") as f: f.write(text + "\n") def adb(*args): return subprocess.run([ADB, *args], capture_output=True, text=True) def ensure_frida_server(): out = adb("shell", "su", "-c", "pgrep -x frida-server") if out.stdout.strip(): print("frida-server already running pid=%s" % out.stdout.strip()) return print("starting frida-server ...") adb("shell", "su", "-c", "pkill -9 frida-server; true") # run in background via nohup-like subprocess.Popen( [ADB, "shell", "su", "-c", "/data/local/tmp/frida-server -D"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) time.sleep(2) out = adb("shell", "su", "-c", "pgrep -x frida-server") if not out.stdout.strip(): raise RuntimeError("frida-server failed to start") print("frida-server pid=%s" % out.stdout.strip()) def main(): ensure_frida_server() adb("shell", "am", "force-stop", PKG) time.sleep(1) device = frida.get_usb_device(10) source = SCRIPT.read_text(encoding="utf-8") print("Spawning %s ..." % PKG) print("log=%s" % LOG) pid = device.spawn([PKG]) session = device.attach(pid) script = session.create_script(source) script.on("message", on_message) script.load() print("script loaded, resume pid=%s" % pid) device.resume(pid) alive = 0 for i in range(HOLD_SEC): time.sleep(1) # check process still alive out = adb("shell", "pidof", PKG) pids = out.stdout.strip() if not pids: print("DEAD after %ss" % (i + 1)) break alive = i + 1 if (i + 1) % 5 == 0: print("alive %ss pid=%s" % (alive, pids)) else: print("STABLE %ss pid=%s" % (HOLD_SEC, adb("shell", "pidof", PKG).stdout.strip())) # dump activity focus focus = adb("shell", "dumpsys", "activity", "activities") for line in focus.stdout.splitlines(): if "tngdigital" in line.lower() and ( "mResumedActivity" in line or "topResumedActivity" in line or "UserLogin" in line or "SecurityError" in line or "Splash" in line ): print("ACT: " + line.strip()) try: session.detach() except Exception: pass print("done alive=%ss log=%s" % (alive, LOG)) return 0 if alive >= 15 else 1 if __name__ == "__main__": sys.exit(main())