diff --git a/docs/虎牙hyCred签发-侦察笔记.md b/docs/虎牙hyCred签发-侦察笔记.md index 8c64fac..8bd9b0b 100644 --- a/docs/虎牙hyCred签发-侦察笔记.md +++ b/docs/虎牙hyCred签发-侦察笔记.md @@ -152,3 +152,11 @@ sendMessage(0x1001, json) 载荷(char*直读): - 六字段与静态预测完全吻合; 空对象/空数组原样传 剩余: 响应侧(doMSG a2偏移待修, cred响应未读到) + 信封包装层。 证据: evidence/cred_issue_trace.json + +## Round9: bean为指针对象, 改挂getCred出口 + +saveLoginData bean(1536B dump)=C++对象, cred在堆上经指针引用, 非内联。 +最直接抓点: BusinessCfg::getCred(ulong,string&out)@0x265524 + -> onLeave 读 out(x2) std::string 即152字符hyCred原文。 +scripts/hook_beandump.py 已建(时序模板可复用), 下轮改钩子地址重跑一次登录即得。 +另: 响应JSON键已确认含"cred"键(0x1c36e8)。 diff --git a/evidence/beandump.json b/evidence/beandump.json new file mode 100644 index 0000000..3503984 --- /dev/null +++ b/evidence/beandump.json @@ -0,0 +1 @@ +[{"type": "armed"}, {"type": "bean", "data": "909bd27778000000209dd277780000006f65b851170100001dee9a14002000001868795f33303030323338383700465371794f7270363254c1000000000000009800000000000000409a8b37790000b400f49137790000b440f49137790000b440f49137790000b4709dd277780000001a3131393936363639313436373100732f666a56374c5a6f1868795f333030303233383837005243585662637946597006312e30007600869b7b226375726c223a22e799bbe5bd9561010000000000005801000000000000805a4e22780000b4023100756465223a222d312e30222c226c6f6e67697475641a3030312a2a2a2a2a2a3735323400223a22222c227573650000616374696f6e223a5b7b226964223a223234222c227400009aca7900000000402e7e7800000000c00f0000000000a5742438a0010000000000000000000000000000000000000100000001000000090000000000000002000000780000001868795f333030303233383837002e342e32322609312e30707f4722780000b4707f4722780000b40100000000000000e09bd2777800000000000000000000000000000000000000000099ca7900000000d03d7e780000008fbf0fd1dcf9747500003d7e780000002000000000000000d0ca3d7e780000000000cf77780000006095d2777800000020fd8e3b780000b400008e3b780000b40096d27778000000e808d4777800000000008e3b780000b420ca3d7e780000008fbf0fd1dcf9747500003d7e78000000d8db99ca7900000000d03d7e7800000000008e3b780000b420000000000000004072ab3b780000b403000000030000008104000000000000780400000000000000063222780000b4000000000000000000000000000000000000000000000000dc0eb17778000000c8ac8937790000b48fbf0fd1dcf97475804549b2740000b4c0ac8937790000b400cb3d7e78000000d825b1777800000000402e7e7800000000c00f0000000000f8cf3d7e78000000f893d577780000000100000b00000000010000090000000000f84c22780000b420fd8e3b780000b420fd8e3b780000b400f84c22780000b420cb3d7e78000000c436b4777800000000f84c22780000b4a0cb3d7e7800000060cb3d7e78000000ccd3b0777800000050d28137790000b400d03d7e7800000000f84c22780000b440d28137790000b400f84c22780000b4a0cb3d7e78000000b0cb3d7e7800000040dbb0777800000000d03d7e7800000028dbb0777800000000f84c22780000b4c076b398750000b4c0e36798750000b440d28137790000b400000000000000008fbf0fd1dcf9747520cc3d7e7800000078d9b07778000000c0cc3d7e78000000b841a4ca79000000c0cc3d7e780000007f5400000000000050d28137790000b468d28137790000b400d03d7e7800000040d28137790000b450cc3d7e7800000064ddb07778000000c0cc3d7e780000008fbf0fd1dcf9747550cc3d7e780000006cddb077780000000354000000000000c0cc3d7e78000000c838a4ca7900000090d28137790000b470cc3d7e780000000c39a4ca79000000c0cc3d7e78000000c0cc3d7e7800000090cc3d7e780000008c3a9eca79000000c0cc3d7e78000000000000000000000000000000000000000000000000000000c0ac0c7b78000000000000000000000000b00c7b78000000b8af0c7b78000000c03c8c7678000000c07c2871780000008954000003540000000000000000000000302e7e78000000c09c0f000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ddb0777800000090d28137790000b40000000000000000041200800000000000b0592b790000000040087078000000c0cc3d7e78000000010000000000000000302e7e7800000000e00f000000000000402e7e7800000000c00f0000000000737461636b5f616e645f746c733a3231363431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, {"type": "bean", "data": "909bd27778000000209dd277780000006f65b851170100001dee9a14002000001868795f33303030323338383700465371794f7270363254c1000000000000009800000000000000409a8b37790000b400f49137790000b440f49137790000b440f49137790000b4709dd277780000001a3131393936363639313436373100732f666a56374c5a6f1868795f333030303233383837005243585662637946597006312e30007600869b7b226375726c223a22e799bbe5bd9561010000000000005801000000000000805a4e22780000b4023100756465223a222d312e30222c226c6f6e67697475641a3030312a2a2a2a2a2a3735323400223a22222c227573650000616374696f6e223a5b7b226964223a223234222c227400009aca7900000000402e7e7800000000c00f0000000000a5742438a0010000000000000000000000000000000000000100000001000000090000000000000002000000780000001868795f333030303233383837002e342e32322609312e30707f4722780000b4707f4722780000b40100000000000000e09bd2777800000000000000000000000000000000000000000099ca7900000000d03d7e780000008fbf0fd1dcf9747500003d7e780000002000000000000000d0ca3d7e780000000000cf77780000006095d2777800000020fd8e3b780000b400008e3b780000b40096d27778000000e808d4777800000000008e3b780000b420ca3d7e780000008fbf0fd1dcf9747500003d7e78000000d8db99ca7900000000d03d7e7800000000008e3b780000b420000000000000004072ab3b780000b403000000030000008104000000000000780400000000000000063222780000b4000000000000000000000000000000000000000000000000dc0eb17778000000c8ac8937790000b48fbf0fd1dcf97475804549b2740000b4c0ac8937790000b400cb3d7e78000000d825b1777800000000402e7e7800000000c00f0000000000f8cf3d7e78000000f893d577780000000100000b00000000010000090000000000f84c22780000b420fd8e3b780000b420fd8e3b780000b400f84c22780000b420cb3d7e78000000c436b4777800000000f84c22780000b4a0cb3d7e7800000060cb3d7e78000000ccd3b0777800000050d28137790000b400d03d7e7800000000f84c22780000b440d28137790000b400f84c22780000b4a0cb3d7e78000000b0cb3d7e7800000040dbb0777800000000d03d7e7800000028dbb0777800000000f84c22780000b4c076b398750000b4c0e36798750000b440d28137790000b400000000000000008fbf0fd1dcf9747520cc3d7e7800000078d9b07778000000c0cc3d7e78000000b841a4ca79000000c0cc3d7e780000007f5400000000000050d28137790000b468d28137790000b400d03d7e7800000040d28137790000b450cc3d7e7800000064ddb07778000000c0cc3d7e780000008fbf0fd1dcf9747550cc3d7e780000006cddb077780000000354000000000000c0cc3d7e78000000c838a4ca7900000090d28137790000b470cc3d7e780000000c39a4ca79000000c0cc3d7e78000000c0cc3d7e7800000090cc3d7e780000008c3a9eca79000000c0cc3d7e78000000000000000000000000000000000000000000000000000000c0ac0c7b78000000000000000000000000b00c7b78000000b8af0c7b78000000c03c8c7678000000c07c2871780000008954000003540000000000000000000000302e7e78000000c09c0f000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ddb0777800000090d28137790000b40000000000000000041200800000000000b0592b790000000040087078000000c0cc3d7e78000000010000000000000000302e7e7800000000e00f000000000000402e7e7800000000c00f0000000000737461636b5f616e645f746c733a3231363431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}] \ No newline at end of file diff --git a/scripts/hook_beandump.py b/scripts/hook_beandump.py new file mode 100644 index 0000000..d5c644c --- /dev/null +++ b/scripts/hook_beandump.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +"""抓 hyCred 签发链: 挂 saveLoginData(落盘) + LoginCred handler(vtable探测)。 + +用法: 脚本跑起来后, 在手机上 手动退出登录 -> 重新登录 一次。 +捕获: 登录态JSON明文(含cred字段) / saveLoginData 入参 / LoginCred handler 触发。 +""" +from __future__ import annotations + +import json +import subprocess +import time +from pathlib import Path + +import frida + +RE = Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0") + +JS = r""" +var base = Process.getModuleByName('libudbauthunify.so').base; +send({type:'armed'}); +function hx(p,n){ try{ return Array.from(new Uint8Array(p.readByteArray(n))).map(x=>('0'+x.toString(16)).slice(-2)).join(''); }catch(e){ return 'ERR:'+e; } } +Interceptor.attach(base.add(0x265a6c), { + onEnter: function(a){ send({type:'bean', data:hx(a[1],1536)}); } +}); +Interceptor.attach(base.add(0x265fb0), { + onEnter: function(a){ send({type:'bean', data:hx(a[2],1536)}); } +}); +""" + + +def main(): + d = frida.get_device_manager().add_remote_device('127.0.0.1:31877') + pid = d.spawn(['com.duowan.kiwi']) + s = d.attach(pid) + s.create_script((RE / "evidence/scripts/bypass_msaoaid_maps_art_callsite.js").read_text()).load() + s.create_script((RE / "evidence/scripts/mask_frida_maps_only.js").read_text()).load() + d.resume(pid) + time.sleep(11) + s.create_script((RE / "evidence/scripts/patch_guard_block_termination.js").read_text()).load() + print('armed. >>> 请在手机上退出登录并重新登录 <<<') + + sc = s.create_script(JS) + events = [] + def on_msg(m, _): + if m.get('type') == 'error': + print('JS ERR:', str(m)[:200]); return + if m.get('type') != 'send': + return + p = m.get('payload') or {} + t = p.get('type') + events.append(p) + if t == 'vt_attached': + print(f"[vt] {p['name']} slot{p['slot']} @+{p['fp']}") + elif t == 'saveLD_str': + print(f"[saveLD_str] str={p['str']['t']}:{p['str']['len']}\n bean={p['bean_head']}\n bt={p['bt']}") + elif t == 'saveLD_bean': + print(f"[saveLD_bean] flag={p['flag']}\n bean={p['bean_head']}\n bt={p['bt']}") + elif t == 'cred_unpack': + print(f"[cred_unpack] in={p['in']['t']}:{p['in']['len']}:{p['in']['v'][:160]} <- {p['ra']}") + elif t == 'bigaes': + print(f"[bigaes] len={p['x2']['len']} head={p['x2']['v'][:120]}") + elif t == 'vtable': + print(f"[VT!] {p['name']}#{p['slot']} a1={p['a1']} bt={p['bt']}") + sc.on('message', on_msg) + sc.load() + deadline = time.time() + 300 + while time.time() < deadline: + time.sleep(3) + if any(e.get('type') == 'saveLD_bean' for e in events): + time.sleep(10) + break + Path('/Users/yml/codes/douyu_login_py/evidence/beandump.json').write_text(json.dumps(events)) + from collections import Counter + print('saved:', Counter(e.get('type') for e in events)) + + +if __name__ == '__main__': + for attempt in range(4): + try: + main() + break + except frida.InvalidOperationError as e: + print('detached:', e) + subprocess.run(['adb', 'shell', 'am', 'force-stop', 'com.duowan.kiwi']) + time.sleep(3)