How to convert programs written for x86 to ARM?

cprogramming
programming
linux

#1

Hello!

I have a problem. I have been going through Ryan “elfmaster” O’Neill’s Learning Linux Binary Analysis, and have found two of his tools to be clever and very useful. Namely, ftrace and Extended Core File Snapshot.

I want to use these on an ARM processor. Can anyone point me in the right direction so that I can learn how to use these tools on ARM?

Do I have to recompile it from source on an ARM processor? A lot of the code seems x86 specific.


(oaktree) #2

If you’re talking about assembly, converting it would most likely require a port…

This is pretty much why higher-level languages, like C, were made.


#3

This code, for example:

#ifdef __x86_64__
    		esp = pt_reg.rsp;
    		eip = pt_reg.rip;
    		eax = pt_reg.rax;
    		ebx = pt_reg.rbx;
    		ecx = pt_reg.rcx;
    		edx = pt_reg.rdx;
    		esi = pt_reg.rsi;
    		edi = pt_reg.rdi;
    #else
    		esp = pt_reg.esp;
    		eip = pt_reg.eip;
    		eax = pt_reg.eax;
    		ebx = pt_reg.ebx;
    		ecx = pt_reg.ecx;
    		edx = pt_reg.edx;
    		esi = pt_reg.esi;
    		edi = pt_reg.edi;

I would need to change this to equivalent ARM arm?


#4

Well yeah but you would need to change alot more things (I’ve only looked at the ftrace).
for example the branch_table would need ARM opcodes instread of x86 opcodes.
Also like you noticed the user_regs_struct needs adjustments to be ARM compatible (usage of ARM registers instead of x86).You also need to change everything the author marked with #ifdef x86_64 as it simbolizes that the following code
only works on 64bit x86 code (and the code in the else statement only on 32bit x86 code).
The problem is that some structures and other things may be identical for x86 and x86-64 but different for ARM so you need to find those different parts as well and change them.

	switch (opts.arch) {
		case 32:
			ehdr32 = (Elf32_Ehdr *)mem;
			if (ehdr32->e_machine != EM_386)
				return 0;
			break;
		case 64:
			ehdr64 = (Elf64_Ehdr *)mem;
			if (ehdr64->e_machine != EM_X86_64 && ehdr64->e_machine != EM_IA_64)
				return 0;
			break;
	}

Is an example for that as it checks if the ELF is build for x86 or x86-64 which obviously isn’t the case for something build for ARM.
Also the getstr and getargs seem to depend on x86-64 architecture.

My ARM sadly isn’t good enough to tell you if there are any not easily spotable differences so I guess you could just change those #ifdef parts to fit the ARM architecture and then try to debug it.


#5

Actually all of this can be read from the ELF File header.


(Full Snack Developer) #6

Do you have the source? If so, cross-compile with something like GCC.


(pico) #7

@Leeky pointed out some of the issues. After looking a bit into ftrace, you will really have to change quite some code. Most of the ELF related stuff should be fine, but in addition to the jump opcodes you may also have to rework the break points (that uses a different instruction on ARM) and specially the getargs function that will be pretty different.

The ARM ABI is actually closer to x86_64 than to the 32bits counterpart, in the sense that parameters are passed in registers (in the normal case), but the way to resolve pointer is a bit different. For example, this is a call to a puts function on an ARM 32 bits (not Thumb).

00008604:   ldr	r0, [pc, #0x68] 
00008608:   bl	<[email protected]>

The first instruction load on r0 the first parameters (for x86_64 rdi is used instead), then it uses PC relative addressing, to load the pointer to the actual string to print. This translates in calculating the position of that pointer (PC + 0x68 + 4 = 0x8608 + 0x68 + 4 = 0x8670) and use the content of that position.

Summing up, it looks like quite some work to port the tool to ARM… but I would say you will learn a ton doing it :slight_smile:

At first glance I think using capstone will simplify a bit the parsing. For instance, it already classifies some mnemonics as jumps or calls automatically. However I have had issues working with Thumb code and specially when Thumb and ARM32 code is mixed.


#8

Thanks for the help and advice! I want to do something useful in which I will learn a lot. I have no idea how long this may take me, hehe, but it would just be sooo useful for ARM processors


(pico) #9

I’d be interested on such a tool whenever is ready :wink: