Search code examples
debuggingadb

How to get the disassembly code while debugging android application?


When I reverse engineer applications on x86, I can get the x86 assembly code while debugging, e.g. disassemble the opcode pointed by EIP/RIP to x86 assembly. But for android application, I always need some kind of source in advance to make the debugging useful. My question is, instead of doing a disassembly of the apk, can I get the java/smali code of the program that I'll debug in real time? In other words, can the debugger "disassemble" the code on the fly like what it can do on x86?

The reason I want that is because when I use the disassembled code of the APK, I only get the static disassembly code of the program, but what if the method is hooked?


Solution

  • I've been reversing for a little while and I never came across a live debugging tool for Smali bytecodes. However, it is really useful to have both static and dynamic analysis in our toolset when you have some complex targets. This is how I do it, it might help you out.

    1. Start by using Jadx to decompile the dex file(s) and convert Smali to Java. This way you get a general understanding of the app underlyings.
    2. If the app use native code you can also extracts the libs from /lib folder in the APK and analyse them, but since your question isn't about native code I will skip this subject.
    3. Now let's say you found some mysterious crypto function that encrypt data using a key, but the key is dynamically generated, you can't get it by just looking at the code, you need to hooks methods !
    4. My favorite tool for this on Android is Xposed. It is a framework that you install on your device (Usually need root) and it allows you to create module that will be loaded when your target app is loaded and hook any of its method (Even system methods).
    5. Let's say the mysterious crypto function is: String encrypt(String key, String data); Using Xposed we can do the following to dump the key:
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
    if (!lpparam.packageName.equals("com.target.app")) {
            return;
        }
    
    findAndHookMethod("com.target.app.CryptoClass", lpparam.classLoader, "encrypt", String.class, String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                Log.i("TargetApp_Hook", "Secret Key: " + param.args[0].toString());
            }
        });
    
    1. The key will now appear in your device logcat.

    You can use Xposed to hook before and after methods, replace methods, avoid a method call, call a method directly using your code and much more ! There is also a tool named Frida that let you hook Java code but also native code at the same time, it is simple to use and everything is wrapped through their custom Javascript API. However, I found Xposed to be more stable.