javascriptjavaandroidhookfrida

frida:hook a function but no response


I wrote a simple apk myself with a button that sends a request when pressed, this apk uses certificate verification, I tried to bypass it with hook, but it didn't work.

The following is part of the code for apk certificate verification.

X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Certificate returned by the server
                X509Certificate cf = chain[0];
                RSAPublicKey pubkey = (RSAPublicKey) cf.getPublicKey();
                String encoded = Base64.encodeToString(pubkey.getEncoded(), 0);
                Log.e("Certificate returned by the server:", encoded);

                // Reads the client's default certificate
                InputStream client_input = getResources().openRawResource(R.raw.baidu);
                CertificateFactory finalcf = CertificateFactory.getInstance("X.509");
                X509Certificate realCertificate = (X509Certificate) finalcf.generateCertificate(client_input);
                String realPubKey = Base64.encodeToString(realCertificate.getPublicKey().getEncoded(), 0);
                Log.e("client's default certificate:", realPubKey);

                cf.checkValidity();

                final boolean expected = realPubKey.equalsIgnoreCase(encoded);

                Log.e("Call stack", Log.getStackTraceString(new Throwable()));

                if (!expected) {
                    throw new CertificateException("Certificate inconsistency");
                }

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };


        SSLSocketFactory factory = null;

        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom());

            factory = sslContext.getSocketFactory();
        } catch (Exception e) {

   }

I output the call stack below when i press the button.

at com.nb.netdemo3.MainActivity$2.checkServerTrusted(MainActivity.java:77)
        at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:254)
        at com.android.org.conscrypt.ConscryptEngine.verifyCertificateChain(ConscryptEngine.java:1644)
        at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
        at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:568)
        at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1095)
        at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1079)
        at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
        at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
        at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
        at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:849)
        at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.access$100(ConscryptEngineSocket.java:722)
        at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:238)
        at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:217)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:336)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:300)

And i want to hook this function com.android.org.conscrypt.Platform.checkServerTrusted,here is the hook code

Java.perform(function () {
    var Platform = Java.use('com.android.org.conscrypt.Platform');
    Platform.checkServerTrusted.overload('javax.net.ssl.X509TrustManager', '[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'com.android.org.conscrypt.AbstractConscryptSocket').implementation = function (x509tm, chain, authType, socket) {
        console.log('\n[+] checkServer  ', x509tm, JSON.stringify(x509tm));
        //return this.checkServerTrusted(x509tm, chain, authType, socket);
    };
});

I used frida to hook, and when I hooked, when I pressed the button to send the request, there was no console.log. The version of frida is 16.0.1,my android version is 11,python version is 3.7.9.

I want to know why I can't hook this function called com.android.org.conscrypt.Platform.checkServerTrusted


Solution

  • Your hooking code is correct, but it just hooks the wrong overloaded version of checkServerTrusted, therefore you don't get an error but your code inside the hook is never executed:

    The class com.android.org.conscrypt.Platform contains two public implementations of checkServerTrusted:

    You have hooked the first version, but looking at the code in com.android.org.conscrypt.ConscryptEngine where checkServerTrusted is called (see your stack trace) you will see that the last argument is a this thus the second version is called where the last argument type is com.android.org.conscrypt.ConscryptEngine.

    So f you your hooking code to the following script it should work.

    Java.perform(function () {
        var Platform = Java.use('com.android.org.conscrypt.Platform');
        Platform.checkServerTrusted.overload('javax.net.ssl.X509TrustManager', '[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'com.android.org.conscrypt.ConscryptEngine').implementation = function (x509tm, chain, authType, engine) {
            console.log('\n[+] checkServer  ', x509tm, JSON.stringify(x509tm));
            //return this.checkServerTrusted(x509tm, chain, authType, socket);
        };
    });
    

    Note that the linked source code references do not belong to the Android version of your device, therefore the line numbers don't match and it would be possible that in your older version the code is different.

    If you want to get the exact code that is executed on your device you would have to extract the Android Framework libraries from your device and decompile them (not sure which files you would have to extract from /system/framework to get the conscrypt byte code).