Interacting with low level Linux libraries can make reversing, debugging and analyzing application much simpler.
Libraries, such as ptrace
, can allow us to attach to running processes and execute functions from the tracee (the process we attach to).
Since Android is basically a Linux operating system we can call some of these same libraries to trace android application processes.
For example, the following code can be compiled and ran to dump the register values of an attached process:
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/ptrace.h>
int main(int argc, char **argv) {
pid_t traced_process;
long rt;
struct user_regs_struct regs;
if(argc != 2) {
printf("usage: %s PID\n", argv[0]);
return -1;
}
traced_process = atoi(argv[1]);
rt = ptrace(PTRACE_SEIZE, traced_process, NULL, NULL);
if(rt != 0) {
printf("Failed to attach to process. Are you root?\n");
return -1;
}
ptrace(PTRACE_GETREGS, traced_process, NULL, ®s);
printf("RBP: %llx\nRBX: %llx\nRSI: %llx\nRIP: %llx\n", regs.rbp, regs.rbx, regs.rsi, regs.rip);
ptrace(PTRACE_DETACH, traced_process, NULL, NULL);
return 0;
}
If you compile this with gcc: gcc main.c -o dump-regs
and then execute it on a random process running on your machine: sudo ./dump-regs $PID
We will get a dump of some of the register values of the process:
$ sudo ./dump-regs 10245
RBP: 7f7be53dda98
RBX: 0
RSI: 0
RIP: 9
This works perfectly. The problem is that this program is compiled to run on a x86_64 system, not ARM. So we cannot simply transfer this program to our Android device and run it.
$ file dump-regs
dump-regs: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=36122682e0cf5cac23820af5c691d3b2c2aa374b, not stripped
Luckily, we can solve this issue with a build of GCC that supports cross compiling to ARM.
On Debian based distros, you should be able to install the packages gcc-arm-linux-gnueabi
and binutils-arm-linux-gnueabi
.
sudo apt install gcc-arm-linux-gnueabi and binutils-arm-linux-gnueabi
Now we have a build of GCC that supports compiling to ARM. However, some of the included headers are different on ARM than on x86_64 Linux so we need to make a few changes to our code before we can compile it. The main difference well note here is the user_regs
struct.
I'm not going to explain to difference between the registers of two different CPU architectures here but if you are curious I'd read up on ARM CPU architecture. This knowledge will come in handy when we get more into reversing some of the Android processes.
You can also look into the headers included for binaries compiled by each gcc
and arm-linux-gnueabi-gcc
to see some of the differences to see why our code had to change.
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/ptrace.h>
int main(int argc, char **argv) {
pid_t traced_process;
long rt;
#ifdef __arm__
struct user_regs regs;
#endif
#ifdef __x86_64__
struct user_regs_struct regs;
#endif
if(argc != 2) {
printf("usage: %s PID\n", argv[0]);
return -1;
}
traced_process = atoi(argv[1]);
rt = ptrace(PTRACE_SEIZE, traced_process, NULL, NULL);
if(rt != 0) {
printf("Failed to attach to process. Are you root?\n");
return -1;
}
ptrace(PTRACE_GETREGS, traced_process, NULL, ®s);
#ifdef __x86_64__
printf("RBP: %llx\nRBX: %llx\nRSI: %llx\nRIP: %llx\n", regs.rbp, regs.rbx, regs.rsi, regs.rip);
#endif
#ifdef __arm__
for(int i = 0; i < 18; i++) {
printf("REG[%d]: %lx\n", i, regs.uregs[i]);
}
#endif
ptrace(PTRACE_DETACH, traced_process, NULL, NULL);
return 0;
}
Now, lets compile for ARM: arm-linux-gnueabi-gcc main.c -o arm-dump-regs -static
We now have an ARM binary ready for running on our Android device!
$ file arm-dump-regs
arm-dump-regs: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=8b02c787af1e98e974720d1e6822c7ba99dd2e59, not stripped
And then, we can push to our Android device via ADB: adb push arm-dump-regs /data/local/tmp
[Note: Running this application requires Root on your device!]
And Run:
OnePlus3:/data/local/tmp # ./arm-dump-regs 2206
REG[0]: 888f4
REG[1]: 88914
REG[2]: 88908
REG[3]: 0
REG[4]: ffd3da73
REG[5]: 2f
REG[6]: ffd3da72
REG[7]: 10158
REG[8]: 4990c
REG[9]: 0
REG[10]: 87098
REG[11]: 88448
REG[12]: 10b80
REG[13]: 10b28
REG[14]: 10158
REG[15]: 88460
REG[16]: 10158
REG[17]: 0
O
And you'll see the register dump!
Top comments (2)
Hi! I followed all the steps, but on the final I get the next message (see imagen bellow)
also, my phone is Motorola One hyper, and is rooted.
dev-to-uploads.s3.amazonaws.com/i/...
Finally, it runs. But it doesn't show anything (dev-to-uploads.s3.amazonaws.com/i/...)