fix(tng): 修复地区选择黑屏并加固注册链 native abort 防护

This commit is contained in:
mars
2026-08-03 11:22:51 +08:00
parent 18ae42ec63
commit 193c04a24b
6 changed files with 274 additions and 84 deletions

View File

@@ -227,10 +227,9 @@ public final class TngRootBypassHook {
hookRegistrationFlowGuard(lpparam);
hookSplashForceLogin(lpparam);
hookLoginDismissSplash(lpparam);
hookDialogNoHwAccel();
hookActivityLifecycleDiag(lpparam);
hookHardwareRendererSetName();
hookBottomSelectDialogSafe(lpparam);
hookBottomSelectDialogDiag(lpparam);
hookActivityLifecycleDiag(lpparam);
hookPromonApService(lpparam);
hookPromonBroadcastReceiver(lpparam);
hookAppAttachForceLogin(lpparam);
@@ -528,9 +527,30 @@ public final class TngRootBypassHook {
}
}
/**
* 区号选择弹窗诊断。勿关 HW 加速——Android 16 上会导致列表黑屏。
* ANR 由 HardwareRenderer.setName 拦截兜底。
*/
private static void hookBottomSelectDialogDiag(XC_LoadPackage.LoadPackageParam lpparam) {
try {
Class<?> clazz = XposedHelpers.findClass(
"my.com.tngdigital.common.widget.BottomSelectDialogFragment",
lpparam.classLoader);
XposedHelpers.findAndHookMethod(clazz, "onStart", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
XposedBridge.log(TAG + " BottomSelectDialogFragment.onStart");
}
});
XposedBridge.log(TAG + " hooked BottomSelectDialogFragment.onStart (diag only)");
} catch (Throwable t) {
XposedBridge.log(TAG + " BottomSelectDialog hook failed: " + t.getMessage());
}
}
/**
* ANR 栈Dialog.show → enableHardwareAcceleration → HardwareRenderer.setName → future.get 卡死。
* 兜底拦截 setName,避免 RenderThread 未就绪时主线程永久阻塞
* 拦截 setName;勿全局关 Dialog HW区号选择会黑屏
*/
private static void hookHardwareRendererSetName() {
try {
@@ -548,63 +568,6 @@ public final class TngRootBypassHook {
}
}
/** Dialog.show 走 HW 加速会等 RenderThread复进时 RenderThread 易 abort → 主线程 ANR。 */
private static void hookDialogNoHwAccel() {
try {
XposedHelpers.findAndHookMethod(Dialog.class, "show", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
try {
Dialog dialog = (Dialog) param.thisObject;
android.view.Window window = dialog.getWindow();
if (window != null) {
window.setFlags(
0,
android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
} catch (Throwable ignored) {
}
}
});
XposedBridge.log(TAG + " hooked Dialog.show (no HW accel)");
} catch (Throwable t) {
XposedBridge.log(TAG + " Dialog.show hook failed: " + t.getMessage());
}
}
/**
* 注册/登录页点「下一步」会弹国家区号 BottomSelectDialogFragment。
* HardwareRenderer.setName 已拦截 ANR此处仅关 Dialog HW 加速,保留区号选择。
*/
private static void hookBottomSelectDialogSafe(XC_LoadPackage.LoadPackageParam lpparam) {
try {
Class<?> clazz = XposedHelpers.findClass(
"my.com.tngdigital.common.widget.BottomSelectDialogFragment",
lpparam.classLoader);
XposedHelpers.findAndHookMethod(clazz, "onStart", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
try {
Object dialog = XposedHelpers.callMethod(param.thisObject, "getDialog");
if (dialog instanceof Dialog) {
Dialog d = (Dialog) dialog;
if (d.getWindow() != null) {
d.getWindow().setFlags(
0,
android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
}
} catch (Throwable ignored) {
}
XposedBridge.log(TAG + " BottomSelectDialogFragment.onStart (safe, no HW)");
}
});
XposedBridge.log(TAG + " hooked BottomSelectDialogFragment.onStart (safe)");
} catch (Throwable t) {
XposedBridge.log(TAG + " BottomSelectDialog hook failed: " + t.getMessage());
}
}
/** Promon 隔离 Service打点确认 :goacqowmmt 进程 hook 已注入。 */
private static void hookPromonApService(XC_LoadPackage.LoadPackageParam lpparam) {
Class<?> svc = findPromonClass(lpparam.classLoader, "ap");
@@ -1201,19 +1164,27 @@ public final class TngRootBypassHook {
}
/**
* Promon lifecycle只吞异常,不 short-circuit——全拦会拖死 Splash→Login
* Promon lifecycle1.9.10 用 vhvlnqgy.u旧版用 w。只吞异常不全拦
*/
private static void hookPromonLifecycle(XC_LoadPackage.LoadPackageParam lpparam) {
Class<?> lifecycleClass = findPromonClass(lpparam.classLoader, "w");
if (lifecycleClass == null) {
XposedBridge.log(TAG + " Promon w lifecycle not found");
return;
}
Class<?> promonExc = findPromonClass(lpparam.classLoader, "W");
if (promonExc == null) {
promonExc = findPromonClass(lpparam.classLoader, "bd");
}
final Class<?> promonExcFinal = promonExc;
for (String simple : new String[]{"w", "u"}) {
hookPromonLifecycleClass(lpparam, simple, promonExcFinal);
}
}
private static void hookPromonLifecycleClass(
XC_LoadPackage.LoadPackageParam lpparam,
String simpleName,
Class<?> promonExc) {
Class<?> lifecycleClass = findPromonClass(lpparam.classLoader, simpleName);
if (lifecycleClass == null) {
return;
}
final String lifecycleName = lifecycleClass.getName();
try {
int hooked = 0;
@@ -1229,7 +1200,7 @@ public final class TngRootBypassHook {
return;
}
Throwable t = param.getThrowable();
if (isPromonThrowable(t, promonExcFinal)) {
if (isPromonThrowable(t, promonExc)) {
XposedBridge.log(TAG + " swallowed " + t.getClass().getSimpleName()
+ " in " + lifecycleName + "#" + method.getName());
param.setThrowable(null);
@@ -1243,7 +1214,8 @@ public final class TngRootBypassHook {
+ " " + lifecycleName + " lifecycle method(s) (afterHook only)");
}
} catch (Throwable t) {
XposedBridge.log(TAG + " Promon w lifecycle hook failed: " + t.getMessage());
XposedBridge.log(TAG + " " + lifecycleName + " lifecycle hook failed: "
+ t.getMessage());
}
}