Android Jadx

0 views
Skip to first unread message

Azalee Freas

unread,
Aug 3, 2024, 5:12:43 PM8/3/24
to doormumolef

You might be wondering what fueled this curiosity so let me explain. I was in high school and was preparing for my advanced maths exam. I had recently learned that I could use a certain app to get step-by-step solutions to my problems. I was excited. I tried the app and it worked! It only required a one time purchase fee and that was it. I had a lot of questions about how the app worked under the hood:

I decided to have a fresh start at the problem and figure out if I even need to go as far as decompiling the APK. Maybe just a simple MITM attack would be enough to snoop the API calls and craft my own?

I currently have an iPhone so I installed the Android Emulator on my Linux machine and install the app on that. Then I launched mitmproxy and started intercepting the traffic from the emulator. Whenever I made a query, this API call was made:

So far so good. No need for learning how to reverse-engineer the app. Surely I can figure out what those query parameters are? As it turns out it was extremely hard to figure out how the sig parameter was being generated. Everything else seemed generic enough but sig was dynamic and changed with a change in input.

I tried modifying the input slightly just to check if the API was even checking the sig parameter. As it turns out, it was. The endpoint returned an invalid signature error even on the slightest change in input:

Note: While trying to proxy the android emulator requests via mitmproxy, you might see the error: Client connection killed by block_global. To fix this, make sure you run mitmproxy with the block_global flag set to false: mitmproxy --set block_global=false. You will also have to install the mitmproxy certificate on the device to decrypt the SSL traffic. Follow these instructions to do that.

Disclaimer: I do not condone piracy. This is merely an exercise to teach you how something like this works. The same knowledge is used to reverse malware apps and to disable certificate pinning in APKs. There will be places throughout the article where I will censor the name of the application or the package I am reversing. Do not do anything illegal with this knowledge.

The very first step is to get your hands on the APK file. There are multiple ways to do that. You can either use ADB to get an APK from an Android device (emulated or real) or you can use an online APK website to download a working version of the app. I opted for the latter option. Search on Google and you should be able to find a way to download APKs pretty easily.

This is the perfect time to use JADX to decompile the APK. The hosted version of JADX is pretty neat. You can access it here. Just give it the APK and it will give you a zip file containing the decompiled source.

This is equivalent to calling the hasNext method of java.util.Iterator. Z tells us that this call returns a boolean. p1 is called a parameter register and that is what the hasNext() is being called on. move-result v2 moves the return value of this method call to the v2 register.

I started my exploration from there. I used the output of JADX to explore where this parameter was being populated. This is where having the decompiled source code was really useful. The file structure in the apktool output and jadx output is the same so we can explore the output of JADX to help us figure out where to insert the debug statements in smali.

After exploring the Java output for a while I found the method that was generating the signature. The signature was just an MD5 hash of the rest of the query parameters which were being sent to the server:

The move-result-object call was moving the output of getParameters to the p1 register. This is where I needed a log statement (or so I thought). I did some research and according to StackOverflow I could do something like this:

Firstly, I changed .locals 6 to .locals 7. This is useful because instead of tracing which register I could safely use for my custom code, why not allow the function access to a new register? That way we can be sure that no original code in the method is using the new register.

zipalign is an archive alignment tool that provides important optimization to Android application (APK) files. The purpose is to ensure that all uncompressed data starts with a particular alignment relative to the start of the file.

I used an Android Emulator for this step. Specifically a Pixel 3XL emulator image with API 28 and Android Oreo. Make sure that you use an emulator Android image without Google Play. This is extremely important because otherwise in later steps ADB will give you an error saying adbd cannot run as root in production builds. You can find a detailed solution on StackOverflow.

While I was at it, I added some more debug statements in a couple of additional places in the same file but different methods. There was one method that was calling this getMd5Digest method and another that outputted the actual API URL with the query parameters. I added a debug statement in both of these.

This is amazing! Now I knew which parameters, and in what order, are being used to generate the MD5 hash. I quickly whipped out my trusty Visual Studio Code and wrote down a super simple Python script for generating this hash for me based on custom inputs. This is what I came up with:

This is where I stopped my exploration. The original aims were to figure out how the sig hash was being generated and how to reverse-engineer the API to make custom query calls. I was able to accomplish both of those aims and my curiosity was satisfied.

There might be situations where a function/method is using the maximum allowed registers and you have no idea how to output a debug log. In those scenarios, you have to be a bit more creative and do some register shifting. The following commands will be super useful in those cases:

That is all for today. If you learned something new in this post please subscribe to my weekly newsletter (scroll a bit further for the form) or the RSS feed for the website. You can also follow me on Twitter where I usually post an update about new articles.

If you liked what you read then I am sure you will enjoy a newsletter of the content I create. I send it out every other month. It contains new stuff that I make, links I find interesting on the web, and occasional discount coupons for my book. Join the 5000+ other people who receive my newsletter:

hi yasoob! am commenting to let you know how useful your tutorial has been to me, and am sure to many people as well.i ussually dont leave a comment once i have read an article. but with yours i felt it would be ungratefull on my part if i didnt thank youfor this wonderfull info. i hava so far decompiled one paid apk which am now using for free after succesfully modifying it and am in theprocess of modifying another. and throught the process i find myself coming back again and again to your article once i hit a rough spot.

every time I see this image, I am always amazed to see how fast the android works even though there are so many layers. we are going to do some basic of Frida, Jadx and Genymotion. basically, this article is a mix-up of setting up an android emulator, reverse engineering APKs and android debugging.

The first and obvious thing would be an android system so that we may run our applications. The best emulator for testing purposes is Genymotion. you must have heard about it because almost all bug hunters use this to find bugs in android applications. The best thing I found about this is that you can run any android version with customization.

you can even run an application from the ADB shell. To do so you will need to know the package name and the activity (intent) in that package. I have already told you the way to find packages in android using ADB. all we need is actions for a package. there are many ways to enumerate actions but the one I find simple is with the command `aapt`. you can install it using apt package manager in Kali Linux.

now that we know little basics of android emulator and ADB. we should move on to a debugger & decompiler JADX. I am using jadx-gui which I like more than the CLI version. you can download it from GitHub and build it.

There is a button (green bug icon) on the top bar of jadx-gui. you can use it to start debugging the application. but it requires the ADB service to have one or more devices to run the application on that.

now it is all about how much you know Javascript and Java. This is an interpreter just like Python, bash or Ruby. you can perform arithmetic operations here. you can even print some strings with console.log() function. There is a Java object you could use in many ways. before going to use it, there is a concept of the Android activity lifecycle. Maybe the android developers are already aware of it. there are some methods which are used when an activity is created, deleted, suspended etc.

for example, I want my application(activity) to look for notifications (request the server) when the application is started (onCreate). and I want my application to kill all the child processes it may have created while the process ends (onDestroy). If I go back into the jadx-gui output and view the MainActivity source, I can easily spot these methods.

In this post I gradually build knowledge and show you how to decompile an application with JADX and how to patch an application automaticallly with APKLab. I end the article by showing you how to patch and app manually with apktool, keytool and jarsigner.

This article is the first of a series where I use the kbg messenger Android CTF to demonstrate the basics of Android reverse engineering. The KGB messenger CTF contains 3 challenges that should be solved sequentially:

In this serie, I use the first challenge Alerts to introduce you to multiple Android Reverse engineering tools.In this post, I focus on the setup and solving the challenge with the basics of reverse engineering: decompiling and patching.

My setup consists of an Ubuntu 18.04 machine and a Samsung Galaxy S7 (SM-G930F) with a rooted LineageOS 14.1-20180712-NIGHTLY-herolte. You could also use an emulator if you don't have an Android phone to perform your tests.

c80f0f1006
Reply all
Reply to author
Forward
0 new messages