This guide is a part of the series about third-party Android code debugging:
It’s a very simple guide, it can be “compressed” to a single sentence:
gdbserverfrom Android NDK to a rooted Android device via SSH, attach it to a running process and enjoy remote debugging with GDB.
If it’s enough for you, just stop reading this and start debugging. If you need more details, read the guide below :) Also, there is a good guide from @packm4d, read it as well.
This is what we need to start:
A rooted Android device. To be more precisely, we need a device running Android of version 5 or higher. Also,
adb shell sumust give us a root shell
Other rooted Android features, e.g. running
adbd on the device as root, are not really necessary.
We need a Mac with the latest OS X.
gdbserver are also available for Windows and Linux, so the guide (with some minor changes) is probably applicable to Windows and Linux as well.
Preparations are easy, just three simple steps:
First of all, we install SSHDroid on the Android device, run the app, allow root access and test SSH connection from the Mac to the device.
Then, if the latest Android NDK is not installed on the Mac, we install it. We need it to get
gdbserver for our Android CPU architecture and bitwise. Usually, it’s located in
<Android NDK directory>/prebuilt/android-<architecture and bitwise>/gdbserver/:
E.g. for Android device with AMR64 processor, we choose
<Android NDK directory>/prebuilt/android-amr64/gdbserver/gdbserver.
Finally, we use
scp to copy
/data/gdbserver/ on the Android device (if
/data/gdbserver/ does not exist, create it with SSH). We place
/data is writable on almost all Android devices, even if
adbd does not run as root and
adb root fails with “adbd cannot run as root in production builds” message.
Let’s connect GDB to an Android demon, for example, to
Connect the Mac and Android device to the same WiFi network
On the Mac, SSH the Android device and find the demon we want to debug (for example,
ps command, then go to
/data/gdbserver and run
./gdbserver *:6666 --attach <PID of installd>. In my console it looks like
On the Mac, run
gdb (on OS X, it’s located in
<Android NDK directory>/prebuilt/darwin-x86_64/bin/gdb) and execute
target remote <the Android device IP>:6666 in GDB console. As result, we get something similar to
In the same way, we can debug native code from
.so libs of running Android applications.
Note! If you do not see symbols in loaded modules, try the following:
/system/lib64for 64-bit devices) from your Android device to the local directory. If you debug a Java application with native methods, copy application’s
.solibraries to the local directory as well.
In GDB console, run
(gdb) set solib-search-path path/to/your/local_sys_copy/
In most cases, GDB reads the
.so libs from the local directories and loads the symbols, so you can set breakpoints on function names, find function addresses by names etc.
Commenting is not available in this blog, but you can write me a letter or message. Please, note that English is not my native language. I'm sorry for mistakes/missprints, if any.Prev: A brief C/C++ how-to-start guide for jailbroken iOS devices