Files
live-hub-py/tools/unidbg/hydev/merge_decrypted.py
T
yml2213 70621cff8f feat(huya): unidbg 金测试打通 - 采集器加密可复现(androidId=PDSuHx..)/GUID=0a7dfa..一致
- 输入图定案: 库内零硬件文件读, 种子=ANDROID_ID+服务端hydeviceid_config+MID, 属性层无关(X1/X2)
- 真机全段解密 dump(phone_dump_hydev_full) + merge_decrypted 合入原文件 → unidbg 可直接加载
- unidbg(JDK21+patch) harness: JNI 桩(SharedPreferences日志化/Settings.Secure/NativeBridge)
  金测试: androidId 加密态与 getGUID 全部与真机一致
- 遗留: NativeBridge.b(100) 原生归属库未定(非hydeviceid/udb/device-util), 当前桩替顶
- 修正结论: '单机不可铸造'判断错误, GUID=b(100)=f(androidId密, config, MID) 输入全可控
2026-08-28 16:06:25 +08:00

48 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""把 FULL dump 的解密数据合并进 ORIGINAL .so (元数据完好, unidbg 直接可加载).
关键洞察: unidbg 加载原文件时会自己按 .rela.dyn 重定位(RELATIVE=base+addend,
GLOB_DAT/JUMP_SLOT=按符号解析) —— 重定位槽内容会被覆盖, 所以只需要把
"非重定位的加密数据"(字符串/密钥/常量)换成解密字节即可.
映射: dump 偏移(vaddr 轴) V -> 原文件偏移 = V - 0x1000 (V>=0x3b21c0) 否则 V.
随后把数据区里残留的运行期指针(>=0x4000000000)统一回退/清零.
用法: python3 merge_decrypted.py <original.so> <dump_full.so> <runtime_base> <out.so>
"""
from __future__ import annotations
import struct, sys
def main():
original, dump, base_s, out = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]
base = int(base_s, 16)
od = bytearray(open(original, 'rb').read())
dd = open(dump, 'rb').read()
print(f"[*] original size={len(od):#x} dump size={len(dd):#x} base={base:#x}")
def d2o(v):
"""dump 偏移(vaddr轴) -> 原文件偏移"""
return v - 0x1000 if v >= 0x3b21c0 else v
# 1) 复制解密数据: 覆盖 [0x30000, 0x3eb000) (rodata+data), 含 text 尾部(相同, 无害)
COPY = [(0x30000, 0x3eb000)]
for a, b in COPY:
for off in range(a, b):
pass # 慢, 用切片
# 切片方式: 逐块映射(避免逐字节)
dst_start, dst_end = 0x30000, min(0x3eb000, len(dd))
# 一次性: dump[0x30000:0x3b21c0) -> orig[0x30000:0x3b21c0) (v<0x3b21c0 1:1)
s1, e1 = 0x30000, 0x3b21c0
od[s1:e1] = dd[s1:e1]
# dump[0x3b21c0:0x3eb000) -> orig[0x3b11c0:0x3ea000)
s2, e2 = 0x3b21c0, min(0x3eb000, len(dd))
d2 = e2 - 0x1000
if d2 <= len(od):
od[s2 - 0x1000:d2] = dd[s2:e2]
print(f"[*] data merged: dump[{s1:#x}:{e1:#x}]->orig[{s1:#x}] ; dump[{s2:#x}:{e2:#x}]->orig[{s2-0x1000:#x}:{d2:#x}]")
open(out, 'wb').write(od)
open(out, 'wb').write(od)
print(f"[*] -> {out}")
if __name__ == '__main__':
main()