Merge pull request #44 from yinli155/fix-webview-network-permission-android16

Fix WebView network permission on Android 15+
This commit is contained in:
Alex
2026-07-18 15:09:51 +05:30
committed by GitHub
3 changed files with 74 additions and 8 deletions
@@ -42,13 +42,11 @@ import top.niunaijun.blackbox.fake.service.IMediaSessionManagerProxy;
import top.niunaijun.blackbox.fake.service.IAudioServiceProxy;
import top.niunaijun.blackbox.fake.service.ISensorPrivacyManagerProxy;
import top.niunaijun.blackbox.fake.service.ContentResolverProxy;
import top.niunaijun.blackbox.fake.service.IWebViewUpdateServiceProxy;
import top.niunaijun.blackbox.fake.service.IMiuiSecurityManagerProxy;
import top.niunaijun.blackbox.fake.service.SystemLibraryProxy;
import top.niunaijun.blackbox.fake.service.ReLinkerProxy;
import top.niunaijun.blackbox.fake.service.WebViewProxy;
import top.niunaijun.blackbox.fake.service.WebViewFactoryProxy;
import top.niunaijun.blackbox.fake.service.MediaRecorderProxy;
import top.niunaijun.blackbox.fake.service.NetworkPermissionCompat;
import top.niunaijun.blackbox.fake.service.AudioRecordProxy;
import top.niunaijun.blackbox.fake.service.MediaRecorderClassProxy;
import top.niunaijun.blackbox.fake.service.SQLiteDatabaseProxy;
@@ -125,11 +123,8 @@ public class HookManager {
addInjector(new IAudioServiceProxy());
addInjector(new ISensorPrivacyManagerProxy());
addInjector(new ContentResolverProxy());
addInjector(new IWebViewUpdateServiceProxy());
addInjector(new SystemLibraryProxy());
addInjector(new ReLinkerProxy());
addInjector(new WebViewProxy());
addInjector(new WebViewFactoryProxy());
addInjector(new WorkManagerProxy());
addInjector(new MediaRecorderProxy());
addInjector(new AudioRecordProxy());
@@ -155,6 +150,7 @@ public class HookManager {
addInjector(new ITelephonyRegistryProxy());
addInjector(new IDevicePolicyManagerProxy());
addInjector(new IAccountManagerProxy());
addInjector(new NetworkPermissionCompat());
addInjector(new IConnectivityManagerProxy());
addInjector(new IDnsResolverProxy());
addInjector(new IAttributionSourceProxy());
@@ -293,8 +289,7 @@ public class HookManager {
public boolean areCriticalHooksInstalled() {
String[] criticalHooks = {
"IActivityManagerProxy",
"IPackageManagerProxy",
"WebViewProxy",
"IPackageManagerProxy",
"IContentProviderProxy"
};
@@ -783,6 +783,11 @@ public class IActivityManagerProxy extends ClassInvocationStub {
|| permission.equals(Manifest.permission.SEND_SMS)) {
return PackageManager.PERMISSION_GRANTED;
}
if (isNetworkPermission(permission)) {
Slog.d(TAG, "ActivityManager checkPermission: Granting network permission: " + permission);
return PackageManager.PERMISSION_GRANTED;
}
if (isAudioPermission(permission)) {
@@ -800,6 +805,19 @@ public class IActivityManagerProxy extends ClassInvocationStub {
}
}
@ProxyMethod("checkPermissionForDevice")
public static class checkPermissionForDevice extends MethodHook {
@Override
protected Object hook(Object who, Method method, Object[] args) throws Throwable {
String permission = (String) args[0];
if (isNetworkPermission(permission)) {
Slog.d(TAG, "ActivityManager checkPermissionForDevice: Granting network permission: " + permission);
return PackageManager.PERMISSION_GRANTED;
}
return method.invoke(who, args);
}
}
private static boolean isAudioPermission(String permission) {
if (permission == null) return false;
@@ -818,6 +836,16 @@ public class IActivityManagerProxy extends ClassInvocationStub {
|| permission.equals("android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE");
}
private static boolean isNetworkPermission(String permission) {
if (permission == null) return false;
return permission.equals(Manifest.permission.INTERNET)
|| permission.equals(Manifest.permission.ACCESS_NETWORK_STATE)
|| permission.equals(Manifest.permission.ACCESS_WIFI_STATE)
|| permission.equals(Manifest.permission.CHANGE_NETWORK_STATE)
|| permission.equals(Manifest.permission.CHANGE_WIFI_STATE)
|| permission.equals(Manifest.permission.CHANGE_WIFI_MULTICAST_STATE);
}
@ProxyMethod("checkUriPermission")
public static class checkUriPermission extends MethodHook {
@Override
@@ -0,0 +1,43 @@
package top.niunaijun.blackbox.fake.service;
import java.lang.reflect.Method;
import top.niunaijun.blackbox.fake.hook.IInjectHook;
import top.niunaijun.blackbox.utils.Slog;
public class NetworkPermissionCompat implements IInjectHook {
private static final String TAG = "NetworkPermissionCompat";
private static volatile boolean sInstalled;
@Override
public void injectHook() {
install();
}
@Override
public boolean isBadEnv() {
return !sInstalled;
}
public static void install() {
if (sInstalled) {
return;
}
synchronized (NetworkPermissionCompat.class) {
if (sInstalled) {
return;
}
try {
Class<?> permissionManager = Class.forName("android.permission.PermissionManager");
Method disablePermissionCache = permissionManager.getDeclaredMethod("disablePermissionCache");
disablePermissionCache.setAccessible(true);
disablePermissionCache.invoke(null);
sInstalled = true;
Slog.d(TAG, "disabled framework permission cache");
} catch (Throwable e) {
Slog.w(TAG, "install failed: " + e.getMessage(), e);
}
}
}
}