How can I execute a function from its memory address in C / assembly?

Viewed 236

I have the following assembly function (shown with objdump already)

0000000000000000 <add>:
   0:   b8 06 00 00 00          mov    $0x6,%eax
   5:   c3                      retq  

Now in C I made the following code:

#include <stdio.h>

typedef int (*funcp) (int x);

unsigned char foo[] = {0xb8,0x06,0x00,0x00,0x00,0xc3};

int main(void)
{
  int i;
  funcp f = (funcp)foo;
  i = (*f);
  
  printf("exit = %d\n", i);
  return 0;
}

In the global variable foo I typed the memory address of my function in assembly and tried to execute it but it does not return 6 as expected. How can I execute functions for their memory addresses? furthermore, where can i research more on the subject?

obs: sometimes I got the Segmentation fault (core dumped) error

1 Answers

The NX flag might be your 'friend' here. Parts of memory which are never meant to be executed as binary machine code can be marked as No-eXecute. See https://en.wikipedia.org/wiki/NX_bit . So, depending on architecture, operating system and settings, and even BIOS settings.

So this feature might be on or off. If NX is used on the data-section of your program, it will not run. You will need to mmap() a piece of memory with PROT_EXEC set, copy the data in, then run it.

For the following, I changed the binary to be an amd64 code (+1 func). When using the mmap() copy, it works. When directly calling foo, it fails (on my machine with NX active)

(code without err-check, freeing of mem, etc)

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

typedef int (*funcp) (int x);

unsigned char foo[] = {0x8d,0x47,0x01,0xc3};
//unsigned char foo[] = {0xc3,0xb8,0x06,0x00,0x00,0x00,0xc3};

int main(void)
{
  int i;

  void *mem2;

  mem2 = mmap(0,4096,PROT_WRITE|PROT_READ|PROT_EXEC,MAP_PRIVATE|MAP_ANONYMOUS|MAP_EXECUTABLE,-1,0);

  memcpy(mem2,foo,sizeof(foo));


  funcp f = (funcp)mem2;
  i = f(42);

  printf("exit = %d\n", i);
  return 0;
}
Related