feat(huya): hook突破(getOtp入口命中) + 275d0ff6排除(pre存在) + 结构校验判定点定位

This commit is contained in:
yml2213
2026-08-29 02:27:47 +08:00
parent f121f41f61
commit 702c6276fc
2 changed files with 64 additions and 22 deletions
+53 -22
View File
@@ -218,8 +218,59 @@ public class AesProbe {
return "";
}
void scanHeapWindow(String tag) {
byte[] win = new byte[0x10000];
int hits2 = 0;
for (long baseA = 0x12300000L; baseA < 0x13000000L && hits2 < 40; baseA += 0x10000L) {
UnidbgPointer hp2 = UnidbgPointer.pointer(emulator, baseA);
if (hp2 == null) continue;
try { hp2.read(0, win, 0, win.length); } catch (Throwable t) { continue; }
StringBuilder cur = new StringBuilder();
int st = -1;
for (int i = 0; i < win.length; i++) {
int b = win[i] & 0xff;
if ((b >= 0x20 && b < 0x7f)) { if (st < 0) st = i; cur.append((char) b); }
else {
if (cur.length() >= 30 && cur.chars().allMatch(c -> "0123456789abcdef".indexOf(Character.toLowerCase(c)) >= 0
|| "hZrPb62GskrEeTYcLeUTL1fJ1OR8ky3x9qXQq0s6ICJV5v9T".indexOf(c) >= 0)) {
System.out.println(tag + " @" + String.format("0x%x", baseA + st) + " = " + cur);
hits2++;
}
cur.setLength(0); st = -1;
}
}
}
System.out.println(tag + " done hits=" + hits2);
}
void callGetOtp() {
try {
// hook: getOtp 入口 + 内部 OTP 调用点
final long ENTRY = module.base + 0x26916cL;
final long OTPC = module.base + 0x269324L;
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) {
try {
long a0 = backend.reg_read(Arm64Const.UC_ARM64_REG_X0).longValue();
long a1 = backend.reg_read(Arm64Const.UC_ARM64_REG_X1).longValue();
long a2 = backend.reg_read(Arm64Const.UC_ARM64_REG_X2).longValue();
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));
} 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");
scanHeapWindow("[getOtp-pre]");
// BusinessCfg::getInstance @0x281270
Number inst = module.callFunction(emulator, 0x281270L);
long thisPtr = inst.longValue();
@@ -240,28 +291,8 @@ public class AesProbe {
StringBuilder sb2 = new StringBuilder();
for (byte bb : rb) sb2.append(String.format("%02x", bb));
System.out.println("[getOtp] call ok, struct: " + sb2);
System.out.println("[getOtp] done, scanning heap for outputs...");
byte[] win = new byte[0x10000];
int hits2 = 0;
for (long baseA = 0x12300000L; baseA < 0x13000000L && hits2 < 40; baseA += 0x10000L) {
UnidbgPointer hp2 = UnidbgPointer.pointer(emulator, baseA);
if (hp2 == null) continue;
try { hp2.read(0, win, 0, win.length); } catch (Throwable t) { continue; }
StringBuilder cur = new StringBuilder();
int st = -1;
for (int i = 0; i < win.length; i++) {
int b = win[i] & 0xff;
if ((b >= 0x20 && b < 0x7f)) { if (st < 0) st = i; cur.append((char) b); }
else {
if (cur.length() >= 30 && cur.chars().allMatch(c -> "0123456789abcdef".indexOf(Character.toLowerCase(c)) >= 0 || "hZrPb62GskrEeTYcLeUTL1fJ1OR8ky3x9qXQq0s6ICJV5v9T".indexOf(c) >= 0)) {
System.out.println("[getOtp-heap] @" + String.format("0x%x", baseA + st) + " = " + cur);
hits2++;
}
cur.setLength(0); st = -1;
}
}
}
System.out.println("[getOtp] heap-scan done hits=" + hits2);
scanHeapWindow("[getOtp-post]");
System.out.println("[getOtp] heap-scan done");
} catch (Throwable t) {
System.out.println("[getOtp] err: " + t);
}