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:
yml2213
2026-08-27 17:58:32 +08:00
parent 36b5d78050
commit 49c5c36c05
100 changed files with 8666 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""dfpReport 生成流程 python 验证模型。
目标: 用手头真实 wire 验证对格式的理解:
wire = HTTP POST / (wsapi.huya.com, okhttp/3.14.9)
+ body(taf/wup): 长度头 + servant + "dfpReport" + "tReq"
+ MAGIC(571882cf664bb39401ee) + cw
cw = [明文JSON ^ keystream][collection ^ keystream]
其中 keystream 是每帧独立随机流(未知生成器)。本脚本验证"格式+布局"理解,
并验证给定完整明文(JSON+collection)与keystream可精确重建真实wire。
"""
from __future__ import annotations
import json, binascii, struct, re
MAGIC = bytes.fromhex('571882cf664bb39401ee')
PREFIX_JSON = b'{"appId":"5008","appVer":"13.4.22"'
# 真机已验证的完整明文 JSON(含三元组)
REAL_JSON = ('{"appId":"5008","appVer":"13.4.22","appkey":"865a4924a40897ac1fcfe6b4c2cbb0e3",'
'"channel":"xiaomi","deviceId":"02df398797432eadefcc12767119ad5e80999389",'
'"deviceName":"M2102J2SC","hdid":"7c5387e0539c023c31c4ff0e807e7256117385ee",'
'"heightPixels":"2120","isCloud":0,"isForbidLog":1,"isHome":0,"isPre":0,'
'"openAppId":"","savePath":"/data/user/0/com.duowan.kiwi/files/huyaudb",'
'"sdkVer":"1.0.80138","servantName":"huyaudbwebui",'
'"shareAppDataPath":"/data/user/0/com.duowan.kiwi/files/huyaudb",'
'"systemInfo":"android","systemVer":"M2102J2SC,30,11",'
'"terminalType":1,"testEnv":0,"widthPixels":"1080"}')
def build_json(triple=None, device_name='M2102J2SC', system_ver='M2102J2SC,30,11'):
t = triple or dict(appkey='865a4924a40897ac1fcfe6b4c2cbb0e3',
channel='xiaomi',
deviceId='02df398797432eadefcc12767119ad5e80999389',
hdid='7c5387e0539c023c31c4ff0e807e7256117385ee')
return ('{"appId":"5008","appVer":"13.4.22","appkey":"%(appkey)s","channel":"%(channel)s",'
'"deviceId":"%(deviceId)s","deviceName":"'+device_name+'","hdid":"%(hdid)s",'
'"heightPixels":"2120","isCloud":0,"isForbidLog":1,"isHome":0,"isPre":0,'
'"openAppId":"","savePath":"/data/user/0/com.duowan.kiwi/files/huyaudb",'
'"sdkVer":"1.0.80138","servantName":"huyaudbwebui",'
'"shareAppDataPath":"/data/user/0/com.duowan.kiwi/files/huyaudb",'
'"systemInfo":"android","systemVer":"'+system_ver+'",'
'"terminalType":1,"testEnv":0,"widthPixels":"1080"}') % t
def parse_wire(wire):
"""从真实 wire 提取结构化字段. 返回 dict."""
body_start = wire.find(b'\r\n\r\n') + 4
body = wire[body_start:]
# taf 头: 4字节大端长度, 然后 TLV
# 简化解析: servant名
mi = body.find(MAGIC)
cw = body[mi+10:]
# JSON 密文段长度 + 明文校验
result = {
'body': body,
'cw': cw,
'magic_offset_in_body': mi,
'json_len': None, 'coll': None,
}
# 用已知JSON前缀恢复ks并反推JSON长度定位
if len(cw) >= len(PREFIX_JSON):
# JSON数据是明文XOR (明文可打印). 但我们不知道JSON结束位置(collection开始).
# 用"JSON固定长度"真机值(586)推断: 若明文JSON=XOR后全是可打印ascii且结构符合.
jlen = len(REAL_JSON.encode())
coll = cw[jlen:]
result['json_len'] = jlen
result['json_offset_in_cw'] = 0
result['coll'] = coll
return result
def verify_rebuild(wire):
"""验证: 用解析出的 cw, 从"明文JSON+keystream"能否精确重建 cw[:json_len]."""
p = parse_wire(wire)
cw = p['cw']
jb = REAL_JSON.encode()
jlen = len(jb)
# keystream = cw[:jlen] ^ jb
ks_json = bytes(cw[i]^jb[i] for i in range(jlen))
# 重建 encoded_json = jb ^ ks_json = jb (恒等, 因为ks由它们导出)
# 真正验证: 检查明文JSON在 cw 中位置对应的XOR是否=keystream连续(即JSON在此) — 无法独立验证,
# 但可验证: 明文JSON偏移与 ta f 头一致.
# 关键验证: keystream 在 JSON 段与 collection 段是否"同一生成器连续流".
# 我们对比 JSON 段 ks 和 collection 段(from某plaintext假设). 目前无collection明文故无法.
# 输出 keystream JSON段, 供分析.
return {
'jlen': jlen, 'cw_len': len(cw),
'ks_head': ks_json[:48].hex(),
'coll_len': len(p['coll']),
'ks_json_randomness': len(set(ks_json)),
}
def main():
frames = json.load(open('evidence/frame_real.json'))
wire = binascii.unhexlify(frames[0])
p = parse_wire(wire)
print("wire 总长: %d, body 长: %d, cw 长: %d" % (len(wire), len(p['body']), len(p['cw'])))
print("MAGIC 在 body 偏移: %d" % p['magic_offset_in_body'])
print("JSON 密文长度(586), collection 长度: %d" % len(p['coll']))
v = verify_rebuild(wire)
print("JSON keystream 前48B:", v['ks_head'])
print("keystream JSON段随机性(不同字节):", v['ks_json_randomness'], "/ 586")
# 打印 taf 头可读字符串
b = p['body']
for kw in [b'huyaudbwebui', b'dfpReport', b'android', b'tReq']:
print("body 含 '%s': @%d" % (kw.decode(errors='replace'), b.find(kw)))
if __name__ == '__main__':
main()