58 lines
2.4 KiB
Python
58 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""R36: hook libz deflate/inflate — 抓 XXTEA 输入明文 + 隐藏加密路径 backtrace."""
|
|
import json, subprocess, time
|
|
from pathlib import Path
|
|
import frida
|
|
|
|
REMOTE="127.0.0.1:31878"; ADB="5dd8c93f"; PACKAGE="com.duowan.kiwi"
|
|
RE=Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0")
|
|
HERE=Path(__file__).resolve().parent.parent
|
|
OUT=HERE/"evidence"/("keytrace_"+time.strftime("%H%M%S")+".json")
|
|
|
|
def clear_turing():
|
|
for d in ("app_turingdfp","app_turingfd"):
|
|
subprocess.run(["adb","-s",ADB,"shell","su","-c",f"rm -rf /data/data/{PACKAGE}/{d}/*"],capture_output=True)
|
|
subprocess.run(["adb","-s",ADB,"shell","su","-c",f"find /data/data/{PACKAGE} -name 'resinfo*' -delete"],capture_output=True)
|
|
|
|
def main():
|
|
clear_turing()
|
|
d=frida.get_device_manager().add_remote_device(REMOTE)
|
|
subprocess.run(["adb","-s",ADB,"shell","am","force-stop",PACKAGE],capture_output=True)
|
|
time.sleep(1.5)
|
|
pid=d.spawn([PACKAGE]); print(f"[*] spawn pid={pid}",flush=True)
|
|
s=d.attach(pid)
|
|
from bypass_loader import load_bypass
|
|
load_bypass(s)
|
|
d.resume(pid)
|
|
result={}; got={"post":False,"out":False}
|
|
seen_fns=set()
|
|
def events_ok(p):
|
|
seen_fns.add(p.get('fn')); return True
|
|
def on(m,_):
|
|
if m.get("type")=="error":
|
|
txt=str(m)
|
|
if "ClassNotFoundException" in txt: return
|
|
print(f"[JS] {txt[:160]}",flush=True); return
|
|
p=m.get("payload") or {}
|
|
ev=p.get("event")
|
|
if ev=="post": got["post"]=True; print(f"[+] POST {p['num']}B",flush=True)
|
|
elif ev=="armed-hy": print("[*] hy chain armed",flush=True)
|
|
elif ev=="call":
|
|
if len(seen_fns)<99: pass
|
|
elif ev=="call" and events_ok(p): got["out"]=True
|
|
elif ev=="deflate-found": print(f"[*] deflate export in {p['mod']}",flush=True)
|
|
elif ev=="inflate-in": print(f"[+] inflate-in {p['len']}B via {p['mod']}",flush=True)
|
|
result.setdefault(ev or "misc",[]).append(p)
|
|
sc=s.create_script((HERE/"tools/frida/hook_keytrace.js").read_text())
|
|
sc.on("message",on); sc.load()
|
|
t0=time.time()
|
|
while time.time()-t0<150:
|
|
time.sleep(2)
|
|
if got["out"] and got["post"]: time.sleep(4); break
|
|
json.dump(result,open(OUT,"w"),indent=2)
|
|
print(f"[*] saved {OUT}",flush=True)
|
|
try: s.detach()
|
|
except Exception: pass
|
|
|
|
if __name__=="__main__": main()
|