Remote Debugging of Native Android ARM 64-bit Executables Using gdbserver

In this tutorial, compilation and remote debugging of a simple C program on a rooted Android with ARM 64-bit architecture is described. The computer's hostname is ArchLinux and the smartphone Asus Zenfone is running on Android 5.0.2:

Install a cross-compiler toolchain

Install Android NDK (Native Development Kit):

Install ARM 64-bit toolchain by giving the full path (/opt/arm64cross):

Add folder with binaries to the $PATH environment variable:

Check the compiler:

Compile a simple program

The "Hello, World!" program:

Makefile for helloworld.c program:

Put them into one folder and compile by running GNU make:

Examine the generated executable:

The generated file is actually a shared object because it was compiled using "-fPIE" flag and linked with "-pie" option to support position-independent code. This is a requirement of Android OS. Executables compiled without these options will not work! Otherwise you will get an error:

Here is an excerpt from gcc's manual page:

Note that "-mandroid" and "-mbionic" flags were not used here, and as it turns out, the generated executable works fine and is linked to a necessary "libc" correctly. Option "-g" will make the compiler embed debugging information into the executable.

Set up an SSH server on Android

On the Android device, install SimpleSSHD app from F-Droid or Google Play. Open the app and start the SSH server. By default it listens to port 2222. Now there is an authorization problem. It is solved by copying your public key to file "authorized_keys" in SimpleSSHD app's folder:

Now open ADB shell:

Switch user to root and copy the public key:

You may need to change the ownership and mode of "authorized_keys" file:

Remote debugging using gdbserver

Restart the SimpleSSHD server and copy the "helloworld" program as well as gdbserver to the Asus smartphone with IP address

Login using SSH client from the PC (ArchLinux) and start gdbserver running "helloworld" executable on Android:

Now start the gdb client on ArchLinux:

Connect to the remote gdbserver and set a breakpoint at the "main" function of the "helloworld" program:

Continue running and examining the code:

Disassemble the code and examine memory:

The gdbserver process in Android (SSH client window) should exit and print "Hello World!" message:

The screencast (text is copy-pastable) is shown below:

There is no need to use SSHD server, everything can be done through adb by establishing port forwarding to localhost: