Compiling for ARM from x86-64
Tags: arm, reversing, android, linux
Published: 2019-04-01 19:21:10

---
title: Compiling for ARM from x86-64
published: true
description: Compiling code for ARM from a x86_64 based machine. This is give us a baseline for our process reversing posts later on.
tags: ARM,Reversing,Android,Linux
---

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:


```c
//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, &regs);

	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. 

```c
//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, &regs);

#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!