Debugging Apps on Android Emulator Using GDB
This article shows how to debug a process running on a rooted Android device or emulator. Debugging a process is an essential task in order to find memory corruption like vulnerabilities in an application.
Prerequisites to follow the steps:
What should you learn next?
- Set up an Android Emulator
- NDK - This can be downloaded from the link below
What are we going to do here?
In simple steps, this is what we are going to do:
- Set up GDB Server on the emulator
- Connect to the GDB server from the client
- Start debugging
The first step is to push the gdb server to the emulator. We want to access it from any location on the device, so one way is to put it inside /system/bin directory.
Let's first get the shell on the device using "adb" and run "mount" command as shown below.
As we can see from the above figure, /system is mounted with "ro" permissions. Since we need to write some files into this, let's remount it using "rw" as shown below.
Let's now check with "mount" command.
If you notice, /system partition is now mounted with "rw".
It's time to push our gdbserver on to the emulator.
Navigate to NDK directory and identify the ARM binary location. In my case, it is inside "prebuilt/android-arm" directory as shown below.
Push gdbserver on the emulator using "adb push" command.
To cross-check if it is uploaded or not, get a shell on the device using "adb" and type the following command.
As we can see in the above figure, gdb server is running fine.
We can check gdbserver version as shown in the following figure.
In order to hook into a process using gdb, we need the process id. Let's find a sample process ID using "ps" command. In my case, I am finding the process id of an app running on the device. This is shown in the figure below.
As we can see, 1234 is the process id of the target process.
Following figure shows how to attach to this process using gdbserver.
Note: We can also directly hooking into a program using the following command.
gdbserver :8888 [filename] [arguments]
Now, that gdbserver is running. Once this done, we need to forward port 8888 using "adb forward" as shown below.
Once we are done with all the above steps, we are ready to start our precompiled gdb client.
We can launch the precompiled gdb client as shown below.
As we can see in the above figure, we will get a gdb console. Now, we need to connect to the gdbserver instance running on the emulator. We can do it as shown below.
Great! We can now interact with the target process. Let's list the registers.
FREE role-guided training plans
What you can do with this setup is up to your imagination. In a later article, I will show how we can find memory corruption vulnerabilities in NDK apps using GDB with the same setup.