Files
live-hub-py/scripts/hook_emu_hdid_daemon.py
T
yml2213 49c5c36c05 docs(huya): 模拟器存活闪退诊断报告与 Frida 探测脚本证据
- 诊断报告: attach 主进程静默退出/EGL 崩溃, 仅约 4s 窗口可抓帧
- scripts: attach/spawn/hook/emu 系列 Frida 脚本与抓帧/验证工具
- evidence: identity/reqchain/frame/inputbuf/magic_buf/propedge 抓取样本,
  emu_* 存活对比, diag_* 策略实验, baseline 裸测基准
2026-08-27 17:58:32 +08:00

122 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""守护式抓取模拟器 32hex hdid: 持续 attach kiwi 主进程, hook getHdid/setSafeDeviceId.
App 闪退/重启也不怕 —— 循环枚举进程, 遇新主进程立即 hook。
找到 hdid(≠ed0db8 或任意32hex)后写入 /tmp/emu_hdid_found.txt 并退出。
"""
import time, json, sys
import frida
REMOTE = "127.0.0.1:31878"
FOUND = "/tmp/emu_hdid_found.txt"
JS = r"""
'use strict';
function readStdString(p){
if (p.isNull()) return null;
try{
var first = p.readU8();
if ((first & 1) === 0) {
var len = first >> 1;
return (len>0 && len<256) ? p.add(1).readUtf8String(len) : '';
} else {
var data = p.readPointer();
var len = p.add(8).readU64();
return (len>0 && len<1024) ? data.readUtf8String(len) : null;
}
}catch(e){ return null; }
}
function emit(t,m){ send({t:t,m:m}); }
function hex32(s){ return /^[0-9a-fA-F]{32}$/.test(s||''); }
var hooked=false;
function tryHook(){
if(hooked) return true;
var md = Process.findModuleByName('libudbauthunify.so');
if(!md) return false;
emit('mod','base='+md.base);
try{
Interceptor.attach(md.base.add(0x26A2E0), {
onEnter:function(a){ this.sd=readStdString(a[1]); this.hd=readStdString(a[2]); },
onLeave:function(){
var hd=(this.hd||''); var sd=(this.sd||'');
emit('SETSD', 'hdid='+hd+' sd='+sd.slice(0,32));
if(hex32(hd)) emit('FOUND_HDID', hd);
}
});
}catch(e){ emit('warn','setSd hook fail: '+e); }
try{
Interceptor.attach(md.base.add(0x26A484), {
onEnter:function(a){ this.thiz=a[0]; },
onLeave:function(){
try{
var s=readStdString(this.thiz.add(1088));
if(s) emit('GETHDID', ''+s);
if(hex32(s)) emit('FOUND_HDID', ''+s);
}catch(e){}
}
});
}catch(e){ emit('warn','getHdid hook fail: '+e); }
emit('ready','hooked');
hooked=true;
return true;
}
var tries=0;
function poll(){
tries++;
tryHook();
if(!hooked && tries<200){ setTimeout(poll, 250); }
}
poll();
"""
def main():
dev = frida.get_device_manager().add_remote_device(REMOTE)
seen = set()
found_hdid = None
start = time.time()
while time.time() - start < 600:
procs = []
try:
procs = dev.enumerate_processes()
except Exception:
time.sleep(2); continue
for p in procs:
if not p.name or 'kiwi' not in p.name:
continue
if ':cloudpatch' in p.name or ':logcat' in p.name:
continue
if p.pid in seen:
continue
seen.add(p.pid)
print(f"[{time.strftime('%H:%M:%S')}] 新主进程 pid={p.pid} {p.name}attach中...", flush=True)
try:
session = dev.attach(p.pid)
except Exception as e:
print(f" attach失败: {e}", flush=True)
continue
def on_msg(msg, data, pid=p.pid):
global found_hdid
if msg.get('type') == 'send':
pl = msg['payload']
t, m = pl['t'], pl['m']
if t == 'FOUND_HDID':
print(f"\n★★★★★★ 模拟器 hdid = {m} ★★★★★★", flush=True)
with open(FOUND, 'w') as f:
f.write(m)
return
print(f"[pid {pid}][{t}] {m}", flush=True)
elif msg.get('type') == 'error':
print(f"[pid {pid}] JSErr: {str(msg)[:150]}", flush=True)
try:
sc = session.create_script(JS)
sc.on('message', on_msg)
sc.load()
print(f" hook 已装 (pid {pid})", flush=True)
except Exception as e:
print(f" script失败: {e}", flush=True)
time.sleep(1.5)
print("10分钟超时结束", flush=True)
if __name__ == "__main__":
main()