Debugging third-party machine code in Android

Jan 16, 2018

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:

Copy gdbserver from 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.

Prerequisites

This is what we need to start:


Note! gdb and 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

Preparations are easy, just three simple steps:

  1. 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.

  2. 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/:

    gbdserver-location

    E.g. for Android device with AMR64 processor, we choose <Android NDK directory>/prebuilt/android-amr64/gdbserver/gdbserver.

  3. Finally, we use scp to copy gdbserver to /data/gdbserver/ on the Android device (if /data/gdbserver/ does not exist, create it with SSH). We place gdbserver under /data because /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.

That’s it.

It’s all ready

Let’s connect GDB to an Android demon, for example, to installd:

  1. Connect the Mac and Android device to the same WiFi network

  2. On the Mac, SSH the Android device and find the demon we want to debug (for example, installd) with ps command, then go to /data/gdbserver and run ./gdbserver *:6666 --attach <PID of installd>. In my console it looks like

    debugserver-start

  3. 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

    gdb-console

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:


Wanna say something?

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
Next: Debugging third-party Android Java code on OS X