gogoWebsite

webViwe For security reasons, WebView is not allowed in privileged processes

Updated to 4 hours ago

Origin of the problem:

When we apply our app as a system application, that is, when we add it in the AndroidManifest file

android:sharedUserId=""

In this line, if we use webView, we will report an error: For security reasons, WebView is not allowed in privileged processes.

This is a security mechanism in the 8.0 code.

The solution is to search for information online through the Hook technology fundamental idea is to assign a value to sProviderInstance before an exception occurs, because in the getProvider method, it will be returned directly and will not throw an exception.

 static WebViewFactoryProvider getProvider() {
        synchronized (sProviderLock) {
            // For now the main purpose of this function (and the factory abstraction) is to keep
            // us honest and minimize usage of WebView internals when binding the proxy.
            if (sProviderInstance != null) return sProviderInstance;

            final int uid = ();
            if (uid == .ROOT_UID || uid == .SYSTEM_UID
                    || uid == .PHONE_UID || uid == .NFC_UID
                    || uid == .BLUETOOTH_UID) {
                throw new UnsupportedOperationException(
                        "For security reasons, WebView is not allowed in privileged processes");
            }

             oldPolicy = ();
            (Trace.TRACE_TAG_WEBVIEW, "()");
            try {
                Class<WebViewFactoryProvider> providerClass = getProviderClass();
                Method staticFactory = null;
                try {
                    staticFactory = (
                        CHROMIUM_WEBVIEW_FACTORY_METHOD, );
                } catch (Exception e) {
                    if (DEBUG) {
                        (LOGTAG, "error instantiating provider with static factory method", e);
                    }
                }

                (Trace.TRACE_TAG_WEBVIEW, "WebViewFactoryProvider invocation");
                try {
                    sProviderInstance = (WebViewFactoryProvider)
                            (null, new WebViewDelegate());
                    if (DEBUG) (LOGTAG, "Loaded provider: " + sProviderInstance);
                    return sProviderInstance;
                } catch (Exception e) {
                    (LOGTAG, "error instantiating provider", e);
                    throw new AndroidRuntimeException(e);
                } finally {
                    (Trace.TRACE_TAG_WEBVIEW);
                }
            } finally {
                (Trace.TRACE_TAG_WEBVIEW);
                (oldPolicy);
            }
        }
    }

This line of code can be seen through the source code if (sProviderInstance != null) return sProviderInstance; then there is the code that throws an exception.

So we need to make sProviderInstance not empty.

Looking for reflection methods online and found a good overall solution:
Plan 1:


public static void hookWebView() {
        int sdkInt = .SDK_INT;
        try {
            Class<?> factoryClass = ("");
            Field field = ("sProviderInstance");
            (true);
            Object sProviderInstance = (null);
            if (sProviderInstance != null) {
                ("sProviderInstance isn't null");
                return;
            }
            Method getProviderClassMethod;
            if (sdkInt > 22) {
                getProviderClassMethod = ("getProviderClass");
            } else if (sdkInt == 22) {
                getProviderClassMethod = ("getFactoryClass");
            } else {
                ("Don't need to Hook WebView");
                return;
            }
            (true);
            Class<?> providerClass = (Class<?>) (factoryClass);
            Class<?> delegateClass = ("");
            Constructor<?> providerConstructor = (delegateClass);
            if (providerConstructor != null) {
                (true);
                Constructor<?> declaredConstructor = ();
                (true);
                sProviderInstance = (());
                ("sProviderInstance:{}", sProviderInstance);
                ("sProviderInstance", sProviderInstance);
            }
            ("Hook done!");
        } catch (Throwable e) {
            (e);
        }

I searched for many blogs with this answer, so I was very excited about CV playing, but I found that when I executed it

Constructor<?> providerConstructor = (delegateClass);

This line of code will inevitably report a NoSuchMethod error. After carefully looking at the frameWork code, I found that the WebViewFactoryProvider class is an excuse class. There is no constructor method in it, so I will naturally report this error.

It’s Yitong Baidu again, and finally found another hook solution:

Plan 2:

private static String TAG = "hookWebView";
     public static void hookWebView(){
         int sdkInt = .SDK_INT;
         try {
             Class<?> factoryClass = ("");
             Field field = ("sProviderInstance");
             (true);
             Object sProviderInstance = (null);
             if (sProviderInstance != null) {
                 (TAG,"sProviderInstance isn't null");
                 return;
             }

             Method getProviderClassMethod;
             if (sdkInt > 22) {
                 getProviderClassMethod = ("getProviderClass");
             } else if (sdkInt == 22) {
                 getProviderClassMethod = ("getFactoryClass");
             } else {
                 (TAG,"Don't need to Hook WebView");
                 return;
             }
             (true);
             Class<?> factoryProviderClass = (Class<?>) (factoryClass);
             Class<?> delegateClass = ("");
             Constructor<?> delegateConstructor = ();
             (true);
             if(sdkInt < 26){//Lower than Android O version
                 Constructor<?> providerConstructor = (delegateClass);
                 if (providerConstructor != null) {
                     (true);
                     sProviderInstance = (());
                 }
             } else {
                 Field chromiumMethodName = ("CHROMIUM_WEBVIEW_FACTORY_METHOD");
                 (true);
                 String chromiumMethodNameStr = (String)(null);
                 if (chromiumMethodNameStr == null) {
                     chromiumMethodNameStr = "create";
                 }
                 Method staticFactory = (chromiumMethodNameStr, delegateClass);
                 if (staticFactory!=null){
                     sProviderInstance = (null, ());
                 }
             }

             if (sProviderInstance != null){
                 ("sProviderInstance", sProviderInstance);
                 (TAG,"Hook success!");
             } else {
                 (TAG,"Hook failed!");
             }
         } catch (Throwable e) {
             (TAG,e);
         }
     }

This solution perfectly solves this problem. Because a judgment was made in the middle, it was determined whether it was lower than version O or higher than version O.

Then I just need to call it in the oncreate method of the Activity. Remember to call it before setContentView, or before webVIew is created, otherwise an error will still be reported.

Plan 2 is reproduced from:/68xi/p/