Created
October 29, 2020 01:23
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @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