當WebView運行在特權進程時拋出安全異常,Hook方式解決方案(包含對Android 8.0的處理)


1.問題起源
報錯語句是:java.lang.UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes
因難以避免WebView存在安全漏洞,系統遭受攻擊,Android不允許特權進程應用使用WebView。如果使用了,便會拋出以上異常。
特權進程包括sharedUserId為ROOT_UID和SYSTEM_UID的進程,從Android O(8.0)開始共享PHONE_UID、NFC_UID、BLUETOOTH_UID的進程也屬於特權進程。
如果不幸,你的應用共享了以上的UserId,又有使用WebView,將會Crash掉,並拋出異常。下面提供一種Hook代碼的方法,可以不用修改sharedUserId
且避免Crash。
不過為了安全起見,還是不建議在Google規定的特權進程里繼續使用WebView。下面提供的方案僅供不方便很快去掉WebView,臨時
避免Crash使用。

2.解決方法
請自行搜索了解為什么會想起這樣解決,我是分析了Android8.0 frameworks源碼,對網上的方法進行了改進,以使其在Android 8.0(SDK版本號為26)上使用.
在你的Application OnCreate方法里調用下面的方法即可。
public static void hookWebView(){
        int sdkInt = Build.VERSION.SDK_INT;
        try {
            Class<?> factoryClass = Class.forName("android.webkit.WebViewFactory");
            Field field = factoryClass.getDeclaredField("sProviderInstance");
            field.setAccessible(true);
            Object sProviderInstance = field.get(null);
            if (sProviderInstance != null) {
                Log.i(TAG,"sProviderInstance isn't null");
                return;
            }

            Method getProviderClassMethod;
            if (sdkInt > 22) {
                getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
            } else if (sdkInt == 22) {
                getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
            } else {
                Log.i(TAG,"Don't need to Hook WebView");
                return;
            }
            getProviderClassMethod.setAccessible(true);
            Class<?> factoryProviderClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
            Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
            Constructor<?> delegateConstructor = delegateClass.getDeclaredConstructor();
            delegateConstructor.setAccessible(true);
            if(sdkInt < 26){//低於Android O版本
                Constructor<?> providerConstructor = factoryProviderClass.getConstructor(delegateClass);
                if (providerConstructor != null) {
                    providerConstructor.setAccessible(true);
                    sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance());
                }
            } else {
                Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD");
                chromiumMethodName.setAccessible(true);
                String chromiumMethodNameStr = (String)chromiumMethodName.get(null);
                if (chromiumMethodNameStr == null) {
                    chromiumMethodNameStr = "create";
                }
                Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass);
                if (staticFactory!=null){
                    sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance());
                }
            }

            if (sProviderInstance != null){
                field.set("sProviderInstance", sProviderInstance);
                Log.i(TAG,"Hook success!");
            } else {
                Log.i(TAG,"Hook failed!");
            }
        } catch (Throwable e) {
            Log.w(TAG,e);
        }
    }
 
 
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM