Skip to content

Instantly share code, notes, and snippets.

@tw-Frey
Created October 29, 2020 01:23
Show Gist options
  • Select an option

  • Save tw-Frey/a2a876e47c42382f165a1f48aefdac5f to your computer and use it in GitHub Desktop.

Select an option

Save tw-Frey/a2a876e47c42382f165a1f48aefdac5f to your computer and use it in GitHub Desktop.
For security reasons, WebView is not allowed in privileged processes ... It's a solution that hooks WebViewFactory first.
@android.annotation.SuppressLint({"DiscouragedPrivateApi", "PrivateApi"})
public static void HookWebView() {
int sdkInt = android.os.Build.VERSION.SDK_INT;
try {
Class<?> factoryClass = Class.forName("android.webkit.WebViewFactory");
java.lang.reflect.Field field = factoryClass.getDeclaredField("sProviderInstance");
field.setAccessible(true);
Object sProviderInstance = field.get(null);
if (sProviderInstance != null) {
android.util.Log.v("Faty", "sProviderInstance isn't null");
return;
}
java.lang.reflect.Method getProviderClassMethod;
if (sdkInt > 22) { // above 22
getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
} else if (sdkInt == 22) { // method name is a little different
getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
} else { // no security check below 22
android.util.Log.v("Faty", "Don't need to Hook WebView");
return;
}
getProviderClassMethod.setAccessible(true);
Class<?> factoryProviderClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
java.lang.reflect.Constructor<?> delegateConstructor = delegateClass.getDeclaredConstructor();
delegateConstructor.setAccessible(true);
if (sdkInt < 26) {//低于Android O版本
java.lang.reflect.Constructor<?> providerConstructor = factoryProviderClass.getConstructor(delegateClass);
//noinspection ConstantConditions
if (providerConstructor != null) {
providerConstructor.setAccessible(true);
sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance());
}
} else {
java.lang.reflect.Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD");
chromiumMethodName.setAccessible(true);
String chromiumMethodNameStr = (String) chromiumMethodName.get(null);
if (chromiumMethodNameStr == null) {
chromiumMethodNameStr = "create";
}
java.lang.reflect.Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass);
//noinspection ConstantConditions
if (staticFactory != null) {
sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance());
}
}
if (sProviderInstance != null) {
field.set("sProviderInstance", sProviderInstance);
android.util.Log.i("Faty", "Hook success!");
} else {
android.util.Log.e("Faty", "Hook failed!");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment