From b60c7b78d1cbcab7998a60975bd2280ebc5e34b3 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 29 Aug 2026 02:34:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(huya):=20C2=E6=96=B0=E9=92=A5=E8=A1=A88x24?= =?UTF-8?q?B=E5=8F=91=E7=8E=B0=20+=20AppLoginData=E7=9C=9F=E5=B8=83?= =?UTF-8?q?=E5=B1=80(=E6=B5=81=E7=A8=8B=E7=A9=BF=E9=80=8F2691c0)=20+=20?= =?UTF-8?q?=E5=85=A8=E7=88=86=E7=A0=B4=E9=9B=B6=E5=91=BD=E4=B8=AD=E5=AE=9A?= =?UTF-8?q?=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/HUYA_HDID_ALGORITHM_GEN.md | 11 ++++++++ tools/unidbg/hydev/src/hydev/AesProbe.java | 30 +++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/HUYA_HDID_ALGORITHM_GEN.md b/docs/HUYA_HDID_ALGORITHM_GEN.md index 935ec2d..fee615c 100644 --- a/docs/HUYA_HDID_ALGORITHM_GEN.md +++ b/docs/HUYA_HDID_ALGORITHM_GEN.md @@ -828,3 +828,14 @@ hypasswordLogin/MsgLoginReq/LogLoginReq → mid 各异, tail 恒定 8b38f1 → a ### 堆窗 pre/post 差分法就绪 (getOtp-pre/post 双扫描框架) ### R10: ① hook 2691a4 读 x20 (分支条件) + 读 0x26916c-0x2691a4 前导定 AppLoginData 布局 ### ② 布局修正 → getOtp 走到 269324 → hook 抓 OTP 实参+OUT + +## §11.33 C2 新钥表 + AppLoginData 真布局 + getOtp 流程走通 (R10) +### C2(getInstance) 注入的 AESkeyMgr 新钥表 (堆 0x127ddbe0, 8×24B, 与已知11钥族完全不同!): + SHBfgytjtoikooru+hogji7ER / KNSDNjfohweeromn+mkladj3g / xnkdDFIERRIPT5df+hfgiJ0FD + NDFiroqpmvd4JDIJ+hidtiwex / fNoMrJhbEMXm8nHc+HXTNovaL / novwSHidrhDg1ADU+KLkejnHR + hgtuiouilbsdjwEH+HMYU5gjt / masldDSIFGJjdfio+5hkhsSDF + → 新钥 × enc/decode/md5/sha1/hmac 对 ed0db8 = 全零 +### AppLoginData 真布局 (jadx): hyOpenId@0(8B) + userId@8(24B) + userIdState@0x20(4B) + emailMask@0x28 + ... + → 重构后 getOtp 流程穿透: 26916c→…→2691c0 (x20=0 首串校验过) 不再早退! +### 未捕获: OTP 调用点 269324 hook 未触发 (流程在 2691c4-2692fb 未hook窗口内或 4542c0 getServiceTime 段) +### 状态: appSign 生成复刻仍未完成 - 差距仅剩"抓到 getOtp 内部真实 OTP 输出" diff --git a/tools/unidbg/hydev/src/hydev/AesProbe.java b/tools/unidbg/hydev/src/hydev/AesProbe.java index 3e2bf75..3234edf 100644 --- a/tools/unidbg/hydev/src/hydev/AesProbe.java +++ b/tools/unidbg/hydev/src/hydev/AesProbe.java @@ -251,7 +251,7 @@ public class AesProbe { com.github.unidbg.arm.backend.CodeHook th = new com.github.unidbg.arm.backend.CodeHook() { public void hook(com.github.unidbg.arm.backend.Backend backend, long address, int size, Object user) { System.out.println("[hook] hit @0x" + Long.toHexString(address)); - if (address == OTPC || address == ENTRY) { + if (true) { try { long a0 = backend.reg_read(Arm64Const.UC_ARM64_REG_X0).longValue(); long a1 = backend.reg_read(Arm64Const.UC_ARM64_REG_X1).longValue(); @@ -259,17 +259,25 @@ public class AesProbe { long a3 = backend.reg_read(Arm64Const.UC_ARM64_REG_X3).longValue(); long a6 = backend.reg_read(Arm64Const.UC_ARM64_REG_X6).longValue(); long a7 = backend.reg_read(Arm64Const.UC_ARM64_REG_X7).longValue(); - System.out.println("[hook-args] x0=" + Long.toHexString(a0) + " x1=" + a1 + " x2=" + Long.toHexString(a2) - + " x3=" + Long.toHexString(a3) + " x6=" + a6 + " x7=" + Long.toHexString(a7)); + long a4 = backend.reg_read(Arm64Const.UC_ARM64_REG_X4).longValue(); + long a5 = backend.reg_read(Arm64Const.UC_ARM64_REG_X5).longValue(); + long x23 = backend.reg_read(Arm64Const.UC_ARM64_REG_X23).longValue(); + long x20 = backend.reg_read(Arm64Const.UC_ARM64_REG_X20).longValue(); + System.out.println("[hook-args] x0=" + Long.toHexString(a0) + " x1=" + Long.toHexString(a1) + " x2=" + Long.toHexString(a2) + + " x3=" + Long.toHexString(a3) + " x4=" + Long.toHexString(a4) + " x5=" + Long.toHexString(a5) + " x6=" + a6 + + " x7=" + Long.toHexString(a7) + " x20=" + Long.toHexString(x20) + " x23=" + Long.toHexString(x23)); } catch (Throwable t) { System.out.println("[hook-args] err " + t); } } } public void onAttach(com.github.unidbg.arm.backend.UnHook unHook) {} public void detach() {} }; - emulator.getBackend().hook_add_new(th, OTPC, OTPC, null); emulator.getBackend().hook_add_new(th, ENTRY, ENTRY, null); - System.out.println("[hook] installed @0x26916c + @0x269324"); + emulator.getBackend().hook_add_new(th, module.base + 0x2691a4L, module.base + 0x2691acL, null); + emulator.getBackend().hook_add_new(th, module.base + 0x2691b0L, module.base + 0x2691c0L, null); + emulator.getBackend().hook_add_new(th, module.base + 0x2692fcL, module.base + 0x269330L, null); + emulator.getBackend().hook_add_new(th, module.base + 0x4543a0L, module.base + 0x4543a4L, null); + System.out.println("[hook] installed flow-traces"); scanHeapWindow("[getOtp-pre]"); // BusinessCfg::getInstance @0x281270 Number inst = module.callFunction(emulator, 0x281270L); @@ -280,10 +288,14 @@ public class AesProbe { com.github.unidbg.memory.MemoryBlock mb = emulator.getMemory().malloc(0x1000, false); UnidbgPointer pv = mb.getPointer(); pv.write(0, new byte[0x1000], 0, 0x1000); - writeStrAt(pv, 0x8, "hy_300023887"); - writeStrAt(pv, 0x20, "772ed992b0e161276f44ec63671e60155c506294"); - writeStrAt(pv, 0x38, "1e8bdf7d4f7a01d3"); - writeStrAt(pv, 0x50, "*hZrPb62GskrEeTYcLeUTL1fJ1OR8ky3x9qXQq0s6ICJV5v9T"); + // 真布局 (jadx): hyOpenId@0, userId@8, userIdState@0x20, emailMask@0x28, mobileMask@0x40 + pv.write(0, new byte[8], 0, 8); // hyOpenId=0 + writeStrAt(pv, 0x8, "hy_300023887"); // userId + pv.write(0x20, new byte[4], 0, 4); // userIdState=0 + writeStrAt(pv, 0x28, ""); // emailMask "" + writeStrAt(pv, 0x40, ""); // mobileMask "" + writeStrAt(pv, 0x58, ""); // passport "" + writeStrAt(pv, 0x70, "*hZrPb62GskrEeTYcLeUTL1fJ1OR8ky3x9qXQq0s6ICJV5v9T"); // 调用 getOtp(AppLoginData&) @0x26916c module.callFunction(emulator, 0x26916cL, thisPtr, UnidbgPointer.nativeValue(pv)); byte[] rb = new byte[0x60];