offsecnotes

Debug application code

by frankheat

Why would you want to debug an application?

Let’s have a look at three different scenario:

  1. As an attacker, you want to analyze and modify the app’s behavior. In this case, I prefer Frida because it is much simpler and works most of the time. However, sometimes an app can detect Frida. Of course, you can hook the method(s) that trigger the Frida detection to bypass it, but that’s often not simple. Moreover, debugging allows you to access local variables inside a method, which Frida does not allow.

  2. A user has a debuggable application installed on own device. If the application is debuggable you can:

    Note: This scenario is often impossible because no release application on the Play Store can have android:debuggable="true" [] []. It means that the user has installed the app from a third-party store.

  3. You might have the app Java source code. Again, this scenario is highly unlikely, but not impossible.


Prerequisites

You need to have an application debuggable. If the app is not debuggable you can []:


Debugging levels

You can debug an application to a different levels:


Debug smali code

If you don’t have the original Java code, you can debug the smali code. To do this, you can use IntelliJ/Android Studio + smalidea plugin or jadx.

jadx-gui guide

  1. Open the apk inside jadx-gui
  2. Click on debug button
  3. If you have the app opened, select the process. Otherwise you can launch app.
  4. Now you can set breakpoint, read and modify register value etc.

For more info: https://github.com/skylot/jadx/wiki/Smali-debugger.


Debug java code

You need to have the original java code. You can use tools like Android studio and jdb.

Android studio

This is the simpler approach. You can follow the official guide: Debug pre-built APKs.

Java Debugger (JDB)

  1. Set app to wait (optional).

    adb shell am set-debug-app -w app_package_name

    If we open the app, we’re going to get waiting for debugger.

  2. Find app process id.

    adb shell ps | grep -i app_package_name
  3. Set Up Port Forwarding.

    adb forward tcp:8000 jdwp:<PROCESS_ID>
  4. Start JDB.

    jdb -attach localhost:8000 -sourcepath <source_file>
    
    # If you set app to wait you also need to suspend all threads
    { echo "suspend" ; cat ; } | jdb -attach localhost:8000 -sourcepath <source_file>

    Tip: Other useful commands:

    # List all forward socket connections
    adb forward --list
    
    # Remove specific/all forward socket connection
    forward --remove LOCAL
    forward --remove-all

jdb command examples

# List loaded class
classes

# Show methods of a class
methods ClassName

# Set a breakpoint
# Even if the class NameClass has not yet been loaded,
# JDB will register the breakpoint and activate it 
# as soon as the class is loaded by the JVM.
stop in ClassName.NameMethod

# print source code
list

# Dumps the stack of the current thread
where

# list all commands
help