Reversing native Android using remote IDA Pro

I came across an interesting reverse engineering challenge. The executable had the flag encrypted and would decrypt it into memory and then exit. This is not that interesting at first sight, because one only needs to run the program in a debugger, put a breakpoint near the end and then identify the decrypted flag in memory. However, the devil is in the detail on this one.

Upon first analysis the file is a simple ELF executable:

$ file cryptoarm
cryptoarm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, no section header

This led me to run it in a 32 bit arm environment using qemu, as described here. But this just resulted in an error message:

bash: ./cryptoarm: cannot execute binary file: Exec format error

Apparently, binfmts does not recognize it. A little digging shows that the file is packed by the UPX packer:

It's easy to unpack using UPX, and after doing that, the binary is properly recognized and executed:

$ ./cryptoarm2
/system/bin/linker: No such file or directory
$ file cryptoarm2
cryptoarm2: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped

and it's now looking for /system/bin/linker, which means this is an Android executable. Since I don't know how to run this using qemu, the simplest thing seemed to be copying it to my phone and running it using adb. The storage, such as the sdcard on android is always mounted as noexec, so I'll copy the executable to an executable location such as /data/local/tmp

$ adb push cryptoarm /data/local/tmp
$ ./cryptoarm                                  
error: only position independent executables (PIE) are supported.

At around Android 4.1 or so security concerns led to only position independent executables being supported. So here I needed a really old phone, or some way of running old Android in an emulator. Android Studio comes to mind immediately, of course. So I installed one of the old (deprecated) system images in Android Studio and ran the binary in there:

adb.exe -s emulator-5558 shell mount -o rw,remount /
adb.exe -s emulator-5558 push cryptoarm2 /
adb.exe -s emulator-5558 shell
root@android:/ # ./cryptoarm2
Basic ARM Crypto challenge for Root-Me
Author: koma

Find the flag inside.


Next, we have to find a way to debug this and stop execution right before the program exits. And as the title suggests, IDA Pro is a great tool to perform this function. It is not obvious how to get IDA to make a network connection to a virtual Android instance. But after a bit of searching I found a great resource on how to set that up:

adb.exe -s emulator-5558 push android_server /
adb.exe -s emulator-5558 forward tcp:23946 tcp:23946
adb.exe -s emulator-5558 shell
root@android:/ # ./android_server
IDA Android 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017
Listening on

So now we have the IDA Pro server listening on Android, ready to receive the executable from the client:

So we can then just set a breakpoint close to the end of the execution and look for the flag in memory.

This is a good example of how IDA can be very helpful if the target executable has to run in a remote environment because it's malware or because it can't easily be run on a Windows/Linux/Mac.