Most Android applications can be easily “patched” and reinstalled. The first thing we need to do is get an approximation of the application’s source code. Android applications are stored in the APK format, which is pretty much a ZIP file with some compiled resource files. We can use Apktool to un-package and translate the applications resources and code by running the command below.

$ apktool d <source.apk> -o <destination_directory>/

After decompiling the APK we should have a directory named dest that contains all of the resources that were in the source APK. Now that we have all of the resources we can search for common certificate pinning implementations. This usually involves searching for the strings “verify”, “check”, “TLS”, “SSL”, and “X509”. For our example we already now that we are going to be patching the certificate pinning class available in the OkHTTP3 library. A little bit of patience and a lot of googling landed me at this file in Square’s GitHub repository. Below I have included an excerpt of the method that verifies the pinned certificate so that our discussion is a little easier to follow.

As you can see on line 10 of the gist I included above (line 180 of the entire file I linked from Square’s github), if the hash matches the sha256 the certificate is verified and we return. There is even a really handy comment that says “Success!” in the source that made the reversing process a little more fun. Now that we know what the Java source looks like, it is easy to find and patch the smali code that was created for us by Apktool. Because this was a library that was imported by the APK when it was built, class names were preserved and I was able to find a file called “ CertificatePinner.smali” based of the original Java source “CertificatePinner.java”.

In the smali we can see that the check we performed in our previous GitHub gist on line 8 is now performed on line 12. Then on line 14 of this gist, the application uses if-nez if the return value that was stored in v10 on line 12 was non-zero. Since we want our application to use our sham certificate so that we can view client-server communications, we are going to swap that if-nez with a if-eqz. Then, when the application checks our certificate against the one that is pinned it will continue execution instead of exiting.

After we patched the smali code we just saw, we need to rebuild and reinstall the application. Below I outlined the steps that you could follow to wrap things up.

Recompile and recompress the application using Apktool.

$ apktool b <source_directory>/ -o <patched.apk>

2. Create a signing key using Keytool.

$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

3. Sign the resulting APK with Java’s JarSigner.

$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore <patched.apk> alias_name

4. Install the application on our device once more using Android’s ADB.