feat(huya): 真实getOtp语义全解(serviceTime+计数器+AppLoginData字段) - 直调路线就绪
This commit is contained in:
@@ -796,3 +796,13 @@ UdbAESUtilC1(…) + encrypt ← 后段
|
|||||||
### OTP 消息名差分
|
### OTP 消息名差分
|
||||||
hypasswordLogin/MsgLoginReq/LogLoginReq → mid 各异, tail 恒定 8b38f1 → appSign ≠ OTP 任何段
|
hypasswordLogin/MsgLoginReq/LogLoginReq → mid 各异, tail 恒定 8b38f1 → appSign ≠ OTP 任何段
|
||||||
### 下轮: setSafeDeviceId 直调后 getHDID 状态变化 + 0x64670 "hdid: " 装配函数直调
|
### 下轮: setSafeDeviceId 直调后 getHDID 状态变化 + 0x64670 "hdid: " 装配函数直调
|
||||||
|
|
||||||
|
## §11.30 真实 getOtp 调用语义全解 (R7) - 直调路线就绪
|
||||||
|
### OTP 双真实调用方 (BusinessCfg::getOtp!)
|
||||||
|
- 268ca0 (getOtp(y, string&, int&)) + **0x269324 (getOtp(AppLoginData&) = 登录路径!)**
|
||||||
|
- 269324 参数: x0=to_string(serviceTime)!, x1=2, x2=AESkeyMgr计数器(w25), x3=AppLoginData+0x40,
|
||||||
|
x4=AppLoginData+0x10, x5=全局串(0x484000+0xa0), x6=4, x7=out, [sp]=m(串)
|
||||||
|
- **可直调**: BusinessCfg::getInstance@0x281270 + getOtp(AppLoginData&)@0x26916c (T/W 符号)
|
||||||
|
- AppLoginData 字段布局: +0x40/+0x10/+0x8 (多 string), 全局材料=0x484000+0xa0
|
||||||
|
### OTP tail = f(c,d) 差分 (推翻"固定"结论) + 真实布局空输出 (参数微差待调)
|
||||||
|
### 下轮 (R8): getInstance→getOtp(AppLoginData) 直调, 金样本值注满结构 → 输出 vs ed0db8
|
||||||
|
|||||||
@@ -137,6 +137,45 @@ public class AesProbe {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String callOtpReal(String in, long counter, String s3, String s4, String s5, long mStack) {
|
||||||
|
UnidbgPointer pa = writeStdString(in);
|
||||||
|
UnidbgPointer ps3 = writeStdString(s3);
|
||||||
|
UnidbgPointer ps4 = writeStdString(s4);
|
||||||
|
UnidbgPointer ps5 = writeStdString(s5);
|
||||||
|
UnidbgPointer pout = writeStdString("");
|
||||||
|
UnidbgPointer pm = writeStdString("mstack");
|
||||||
|
try {
|
||||||
|
// 真实布局: (x0=in, x1=2, x2=counter, x3, x4, x5, x6=4, x7=out, [sp]=m)
|
||||||
|
module.callFunction(emulator, 0x32fa24L,
|
||||||
|
UnidbgPointer.nativeValue(pa), 2L, counter,
|
||||||
|
UnidbgPointer.nativeValue(ps3), UnidbgPointer.nativeValue(ps4), UnidbgPointer.nativeValue(ps5),
|
||||||
|
4L, UnidbgPointer.nativeValue(pout), UnidbgPointer.nativeValue(pm));
|
||||||
|
String out = readStdString(pout);
|
||||||
|
String shortIn = in.length() > 20 ? in.substring(0, 20) : in;
|
||||||
|
String mid = out.length() > 36 ? out.substring(4, 36) : out;
|
||||||
|
System.out.println("[otp-real] in=" + shortIn + " cnt=" + counter + " s3=" + s3.substring(0, Math.min(10,s3.length()))
|
||||||
|
+ " s5=" + s5.substring(0, Math.min(10,s5.length())) + " -> out=" + toHex(out) + " mid16=" + mid);
|
||||||
|
} catch (Throwable t) { System.out.println("[otp-real] err " + t.getMessage()); }
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String callOtpFull(String a, String b, String c, String d, long h2, long m2) {
|
||||||
|
UnidbgPointer pa = writeStdString(a);
|
||||||
|
UnidbgPointer pb = writeStdString(b);
|
||||||
|
UnidbgPointer pc = writeStdString(c);
|
||||||
|
UnidbgPointer pd = writeStdString(d);
|
||||||
|
UnidbgPointer pout = writeStdString("");
|
||||||
|
try {
|
||||||
|
module.callFunction(emulator, 0x32fa24L,
|
||||||
|
UnidbgPointer.nativeValue(pa), 2L, 0L,
|
||||||
|
UnidbgPointer.nativeValue(pb), UnidbgPointer.nativeValue(pc), UnidbgPointer.nativeValue(pd),
|
||||||
|
h2, m2, UnidbgPointer.nativeValue(pout));
|
||||||
|
String out = readStdString(pout);
|
||||||
|
System.out.println("[otp-full] c=" + c + " d=" + d + " h=" + h2 + " m=" + m2 + " -> " + toHex(out));
|
||||||
|
} catch (Throwable t) { System.out.println("[otp-full] err " + t); }
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
String callOtp(String a, String b) {
|
String callOtp(String a, String b) {
|
||||||
UnidbgPointer pa = writeStdString(a);
|
UnidbgPointer pa = writeStdString(a);
|
||||||
UnidbgPointer pb = writeStdString(b);
|
UnidbgPointer pb = writeStdString(b);
|
||||||
@@ -407,6 +446,29 @@ public class AesProbe {
|
|||||||
p.callOtp("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
p.callOtp("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
||||||
p.callOtp("hypasswordLogin", "owNMiaCgcHmqoTr3iRamFuHj");
|
p.callOtp("hypasswordLogin", "owNMiaCgcHmqoTr3iRamFuHj");
|
||||||
p.callOtp("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
p.callOtp("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
||||||
|
// 尾随参数差分: 变 c/d/h/m
|
||||||
|
p.callOtpFull("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "X", "Y", 3L, 4L);
|
||||||
|
p.callOtpFull("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "ABCDEFGH", "IJKLMNOP", 7L, 9L);
|
||||||
|
p.callOtpFull("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "5008", "13.4.22", 1L, 2L);
|
||||||
|
p.callOtpFull("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "ed0db8334cadd236c00cadf7e11ab5a5", "1e8bdf7d4f7a01d3", 5L, 6L);
|
||||||
|
// 金样本帧材料爆破: (c,d) = 帧字段, h=1..6
|
||||||
|
p.callOtpFull("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "13.4.22", "1.0.80138", 1L, 2L);
|
||||||
|
p.callOtpFull("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "13.4.22", "1.0.80138", 3L, 4L);
|
||||||
|
p.callOtpFull("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "127.0.0.1", "xiaomi", 1L, 2L);
|
||||||
|
p.callOtpFull("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "1e8bdf7d4f7a01d3", "7c5387e0539c023c31c4ff0e807e7256117385ee", 1L, 2L);
|
||||||
|
p.callOtpFull("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "7c5387e0539c023c31c4ff0e807e7256117385ee", "02df398797432eadefcc12767119ad5e80999389", 1L, 2L);
|
||||||
|
p.callOtpFull("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "13.4.22", "xiaomi", 1L, 2L);
|
||||||
|
p.callOtpFull("", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "13.4.22", "1.0.80138", 1L, 2L);
|
||||||
|
p.callOtpFull("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ", "13.4.22", "1.0.80138", 1L, 2L);
|
||||||
|
// 真实 getOtp 布局: (in=serviceTime串, cnt, s3, s4, s5, m) - 金样本值
|
||||||
|
p.callOtpReal("3251699", 0L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "1e8bdf7d4f7a01d3", 1L);
|
||||||
|
p.callOtpReal("3251699", 1L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "1e8bdf7d4f7a01d3", 1L);
|
||||||
|
p.callOtpReal("3251699", 2L, "300023887", "772ed992b0e161276f44ec63671e60155c506294", "1e8bdf7d4f7a01d3", 1L);
|
||||||
|
p.callOtpReal("300023887", 0L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "1e8bdf7d4f7a01d3", 1L);
|
||||||
|
p.callOtpReal("12916753251699", 0L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "1e8bdf7d4f7a01d3", 1L);
|
||||||
|
p.callOtpReal("0", 0L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "1e8bdf7d4f7a01d3", 1L);
|
||||||
|
p.callOtpReal("3251699", 0L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "7c5387e0539c023c31c4ff0e807e7256117385ee", 1L);
|
||||||
|
p.callOtpReal("3251699", 0L, "hy_300023887", "772ed992b0e161276f44ec63671e60155c506294", "13.4.22", 1L);
|
||||||
p.callOtp("LogLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
p.callOtp("LogLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
||||||
// SDID 块直解 (36B 证书的两个16B块 × 全部钥)
|
// SDID 块直解 (36B 证书的两个16B块 × 全部钥)
|
||||||
p.callDecodeAes("859acf6fad86b24ac479361c2de5132f", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
p.callDecodeAes("859acf6fad86b24ac479361c2de5132f", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
|
||||||
|
|||||||
Reference in New Issue
Block a user