#!/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) try: b=s.create_script((RE/"evidence/scripts/bypass_msaoaid_maps_skip_cleanup.js").read_text()); b.load() except Exception as e: print(f"[*] bypass err {e}",flush=True) 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()