docs(huya): 模拟器存活闪退诊断报告与 Frida 探测脚本证据
- 诊断报告: attach 主进程静默退出/EGL 崩溃, 仅约 4s 窗口可抓帧 - scripts: attach/spawn/hook/emu 系列 Frida 脚本与抓帧/验证工具 - evidence: identity/reqchain/frame/inputbuf/magic_buf/propedge 抓取样本, emu_* 存活对比, diag_* 策略实验, baseline 裸测基准
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""精确定位三元组派生输入: hook __system_property_find + __system_property_read_callback,
|
||||
只记录 name(不读值避免乱码), 并 hook Build 类 Java 侧读取.
|
||||
目标: 找出 hdid/deviceId/appkey 由哪些系统属性派生.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import frida, time, subprocess, json
|
||||
REMOTE="127.0.0.1:31878"; PACKAGE="com.duowan.kiwi"
|
||||
RE=Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0")
|
||||
OUT=Path("/Users/yml/codes/douyu_login_py/evidence/propnames_" + time.strftime("%H%M%S") + ".json")
|
||||
JS=r"""
|
||||
'use strict';
|
||||
var names=new Set(); var dfpGot=false;
|
||||
function rcs(p,n){try{return p.readCString(n)||'';}catch(e){return '';}}
|
||||
function hexb(p,n){try{return Array.from(new Uint8Array(p.readByteArray(n))).map(b=>('0'+b.toString(16)).slice(-2)).join('');}catch(e){return '';}}
|
||||
// 1) NDK property接口
|
||||
try{
|
||||
var pf=Module.findExportByName('libc.so','__system_property_find');
|
||||
if(pf) Interceptor.attach(pf,{onEnter:function(a){var n=rcs(a[0],256); if(n&&!names.has(n)){names.add(n);send({type:'find',name:n});}}
|
||||
});
|
||||
}catch(e){send({type:'e',e:String(e)});}
|
||||
try{
|
||||
var pr=Module.findExportByName('libc.so','__system_property_read_callback');
|
||||
if(pr) Interceptor.attach(pr,{onEnter:function(a){var n=rcs(a[0],256); if(n&&!names.has(n)){names.add(n);send({type:'readcb',name:n});}}
|
||||
});
|
||||
}catch(e){send({type:'e',e:String(e)});}
|
||||
// 2) Java Build 字段访问 (System.getProperty / Build.MODEL等)
|
||||
try{
|
||||
Java.perform(function(){
|
||||
var Sys=Java.use('java.lang.System');
|
||||
Sys.getProperty.overload('java.lang.String').implementation=function(k){var v=this.getProperty(k); send({type:'sysprop',name:String(k),val:String(v)}); return v;};
|
||||
var B=Java.use('android.os.Build');
|
||||
var FINGERPRINT=B.FINGERPRINT.value; var MODEL=B.MODEL.value; var SERIAL=B.SERIAL.value; var MAN=B.MANUFACTURER.value;
|
||||
send({type:'build',MODEL:String(MODEL),FINGERPRINT:String(FINGERPRINT),SERIAL:String(SERIAL),MAN:String(MAN)});
|
||||
});
|
||||
}catch(e){send({type:'jerr',e:String(e)});}
|
||||
// 3) SSL_write dfp
|
||||
try{
|
||||
new ApiResolver('module').enumerateMatchesSync('exports:*!SSL_write').forEach(function(m){
|
||||
Interceptor.attach(m.address,{onEnter:function(a){var len=a[2].toInt32(); if(len<50||len>50000)return;
|
||||
var h=rcs(a[1],Math.min(len,1500)); if(h.indexOf('dfpReport')>=0){dfpGot=true;send({type:'dfp',len:len,hex:hexb(a[1],len)});}}});
|
||||
});
|
||||
}catch(e){send({type:'e',e:String(e)});}
|
||||
"""
|
||||
def main():
|
||||
d=frida.get_device_manager().add_remote_device(REMOTE)
|
||||
result={}
|
||||
for a in range(1,6):
|
||||
subprocess.run(["adb","-s","127.0.0.1:5555","shell","am","force-stop",PACKAGE],capture_output=True); time.sleep(1)
|
||||
pid=d.spawn([PACKAGE]); s=d.attach(pid)
|
||||
try:
|
||||
b=s.create_script((RE/"evidence/scripts/bypass_msaoaid_maps_skip_cleanup.js").read_text()); b.load()
|
||||
except: pass
|
||||
d.resume(pid)
|
||||
found=[]; build=None; dfp=None
|
||||
def on(m,dd):
|
||||
nonlocal build, dfp
|
||||
if m.get('type')=='error': print(f" JSErr {str(m)[:120]}",flush=True); return
|
||||
p=m.get('payload') or {}; t=p.get('type')
|
||||
if t=='find':
|
||||
# 只记设备/系统相关
|
||||
n=p['name']
|
||||
if n.startswith(('ro.','persist.','gsm.','init.','sys.')) : found.append(n)
|
||||
elif t=='sysprop': pass
|
||||
elif t=='build': build=(p.get('MODEL'),p.get('FINGERPRINT'),p.get('SERIAL'),p.get('MAN')); print(f"[att{a}] Build:",p,flush=True)
|
||||
elif t=='dfp': dfp=p['hex']; print(f"[att{a}] dfp len={p.get('len')}",flush=True)
|
||||
sc=s.create_script(JS); sc.on('message',on); sc.load()
|
||||
t0=time.time()
|
||||
while time.time()-t0<20:
|
||||
time.sleep(2)
|
||||
if dfp: time.sleep(3); break
|
||||
print(f"[att{a}] 属性共 {len(found)} 个; dfp={'got' if dfp else 'no'}",flush=True)
|
||||
if found:
|
||||
result['props']=sorted(set(found))
|
||||
if dfp: result['dfp_wire']=dfp
|
||||
try: d.kill(pid)
|
||||
except: pass
|
||||
if dfp: break
|
||||
time.sleep(1)
|
||||
json.dump(result,open(OUT,'w'),indent=2)
|
||||
print("saved",OUT,flush=True)
|
||||
if result.get('props'):
|
||||
print("=== 设备/系统属性读取清单 ===")
|
||||
for n in result['props']: print(" ",n,flush=True)
|
||||
if __name__=="__main__": main()
|
||||
Reference in New Issue
Block a user