feat(huya): getSDID新值族(36B base64常量证书) + A路径实验定界(APK可载Java不可调) + LoginFlow桥接harness

This commit is contained in:
yml2213
2026-08-29 02:10:57 +08:00
parent 87f061ac4f
commit 6bde9beec2
4 changed files with 194 additions and 0 deletions
@@ -403,6 +403,18 @@ public class AesProbe {
p.callOtp("1e8bdf7d4f7a01d3" + "13.4.22" + "1.0.80138" + "127.0.0.1" + "xiaomi", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
p.callOtp("5008" + "13.4.22" + "1.0.80138", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
p.callOtp("ed0db8334cadd236c00cadf7e11ab5a5", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
// 登录消息名 OTP 对拍 (mid 16B 与 ed0db8 对照)
p.callOtp("hypasswordLogin", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
p.callOtp("hypasswordLogin", "owNMiaCgcHmqoTr3iRamFuHj");
p.callOtp("MsgLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
p.callOtp("LogLoginReq", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
// SDID 块直解 (36B 证书的两个16B块 × 全部钥)
p.callDecodeAes("859acf6fad86b24ac479361c2de5132f", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
p.callDecodeAes("859acf6fad86b24ac479361c2de5132f", "owNMiaCgcHmqoTr3iRamFuHj");
p.callDecodeAes("859acf6fad86b24ac479361c2de5132f", "HuyaUdb1928374650qwertyuiop");
p.callDecodeAes("57c9d4e47c932df1f6a5d0ab4b3a2022", "ZMHAVPRaxJ3MtXDjduUnXAKQ");
p.callDecodeAes("57c9d4e47c932df1f6a5d0ab4b3a2022", "owNMiaCgcHmqoTr3iRamFuHj");
p.callDecodeAes("57c9d4e47c932df1f6a5d0ab4b3a2022", "HuyaUdb1928374650qwertyuiop");
p.dumpRegion("0x127ddbe0", 0x127ddf00L, 0x420);
p.dumpRegion("0x127ddf00", 0x127ddf00L, 0x200);
p.emulator.close();
@@ -147,6 +147,10 @@ public class HyDeviceId extends AbstractJni {
else if (i == 101 || i == 102) v = System.getProperty("hydev.android_id", "1e8bdf7d4f7a01d3");
else if (i == 106) v = "a71a0917ab6d0d6a61947a007591cfb97290f88972b047252c0ec7baddcd57df";
else if (i == 104 || i == 105) v = "";
else if (i == 99 || i == 103) v = "7c5387e0539c023c31c4ff0e807e7256117385ee";
else if (i == 5) v = "{\"install\":\"2024-08-24 10:00:00\"}";
else if (i == 107) v = "1e8bdf7d4f7a01d3"; // qimei16
else if (i == 108) v = "0a7dfaa882938a6ab502511452142c571e8bdf7d"; // qimei36 猜测
else if (i == 1) v = "5008";
else if (i == 2) v = "13.4.22";
else if (i == 3) v = "1.14.68";
@@ -350,6 +354,7 @@ public class HyDeviceId extends AbstractJni {
String guid = h.callString(0x20f8c8L, "getGUID");
String cdid = h.callString(0x20eb08L, "getCDID");
String hdid = h.callString(0x20f0c8L, "getHDID");
String sdid = h.callString(0x20ede8L, "getSDID");
String mid = h.callString(0x20fba8L, "getMID");
// 32hex 探针: 再调一轮以观察缓存 (若 init 后 getGUID 重取 = 缓存)
h.emulator.close();
+161
View File
@@ -0,0 +1,161 @@
package hydev;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.BackendFactory;
import com.github.unidbg.arm.backend.Unicorn2Factory;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.AbstractJni;
import com.github.unidbg.linux.android.dvm.BaseVM;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.DvmObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.memory.MemoryBlock;
import com.github.unidbg.pointer.UnidbgPointer;
import java.io.File;
/**
* A路径: APK 全 dex 加载 + 双 native 库 + 驱动 HuyaAuth 登录流
* 目标: 让 native 真执行 5008 帧编码(含 appSign 签发), 捕获每帧的 32hex
*/
public class LoginFlow extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
private final Module hydev;
private final Module udb;
LoginFlow(String apkPath, String hydevSo, String udbSo) throws Exception {
BackendFactory backend = new Unicorn2Factory(true);
emulator = AndroidEmulatorBuilder.for64Bit()
.setProcessName("com.duowan.kiwi")
.addBackendFactory(backend)
.build();
Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM(new File(apkPath));
vm.setJni(this);
vm.setVerbose(false);
DalvikModule dm1 = vm.loadLibrary(new File(hydevSo), false);
dm1.callJNI_OnLoad(emulator);
hydev = dm1.getModule();
System.out.println("[*] hydeviceid base=0x" + Long.toHexString(hydev.base));
DalvikModule dm2 = vm.loadLibrary(new File(udbSo), false);
dm2.callJNI_OnLoad(emulator);
udb = dm2.getModule();
System.out.println("[*] udbauthunify base=0x" + Long.toHexString(udb.base));
}
// ==================== JNI 桩 (保守: 记录 + 回 null/默认) ====================
private static String strArg(Object va, int idx) {
// 兼容: DvmObject 数组或 VaList — 用反射最省事? 不, 用通用 VaList 兼容写法
return null;
}
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:SObj] " + dvmClass.getClassName() + "->" + signature);
try {
return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
} catch (Throwable t) {
// 常见可空兜底
if (signature.endsWith("Ljava/lang/String;") || signature.endsWith("Landroid/content/Context;")
|| signature.endsWith("Ljava/lang/Object;")) {
return null;
}
throw new RuntimeException(t);
}
}
@Override
public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:Obj] " + dvmObject.getObjectType() + "->" + signature);
try {
return super.callObjectMethodV(vm, dvmObject, signature, vaList);
} catch (Throwable t) {
if (signature.endsWith("Ljava/lang/String;") || signature.endsWith("Landroid/content/Context;")) return null;
throw new RuntimeException(t);
}
}
@Override
public int callStaticIntMethodV(BaseVM vm, DvmClass dvmClass, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:SInt] " + dvmClass.getClassName() + "->" + signature);
return super.callStaticIntMethodV(vm, dvmClass, signature, vaList);
}
@Override
public int callIntMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:Int] " + dvmObject.getObjectType() + "->" + signature);
return super.callIntMethodV(vm, dvmObject, signature, vaList);
}
@Override
public boolean callStaticBooleanMethodV(BaseVM vm, DvmClass dvmClass, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:SBool] " + dvmClass.getClassName() + "->" + signature);
return super.callStaticBooleanMethodV(vm, dvmClass, signature, vaList);
}
@Override
public boolean callBooleanMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:Bool] " + dvmObject.getObjectType() + "->" + signature);
return super.callBooleanMethodV(vm, dvmObject, signature, vaList);
}
@Override
public long callStaticLongMethodV(BaseVM vm, DvmClass dvmClass, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
return super.callStaticLongMethodV(vm, dvmClass, signature, vaList);
}
@Override
public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
System.out.println("[JNI:SField] " + dvmClass.getClassName() + " " + signature);
try {
return super.getStaticObjectField(vm, dvmClass, signature);
} catch (Throwable t) {
return null;
}
}
@Override
public void callVoidMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:Void] " + dvmObject.getObjectType() + "->" + signature);
super.callVoidMethodV(vm, dvmObject, signature, vaList);
}
@Override
public void callStaticVoidMethodV(BaseVM vm, DvmClass dvmClass, String signature, com.github.unidbg.linux.android.dvm.VaList vaList) {
System.out.println("[JNI:SVoid] " + dvmClass.getClassName() + "->" + signature);
super.callStaticVoidMethodV(vm, dvmClass, signature, vaList);
}
@Override
public DvmObject<?> getObjectField(BaseVM vm, DvmObject<?> dvmObject, String signature) {
System.out.println("[JNI:Field] " + dvmObject.getObjectType() + " " + signature);
try {
return super.getObjectField(vm, dvmObject, signature);
} catch (Throwable t) {
return null;
}
}
public static void main(String[] args) throws Exception {
String apk = "/Users/yml/codes/douyu_login_py/apks/huya-13.4.22-115315-live.apk";
String hydevSo = "/Users/yml/codes/douyu_login_py/tools/unidbg/hydev/so/libhydeviceid_merged_r2.so";
String udbSo = "/Users/yml/codes/douyu_login_py/tools/unidbg/hydev/so/libudbauthunify_merged.so";
LoginFlow lf = new LoginFlow(apk, hydevSo, udbSo);
System.out.println("=== 解析 HuyaAuth ===");
DvmClass ha = lf.vm.resolveClass("com/huyaudbunify/HuyaAuth");
System.out.println("HuyaAuth resolved: " + ha);
ha.callStaticJniMethod(lf.emulator, "getInstance()Lcom/huyaudbunify/HuyaAuth;");
System.out.println("getInstance OK");
lf.emulator.close();
}
}