Copy the function to memory and execute it

I would like to know how in C in you can copy the contents of a function to memroy and execute it?

I am trying to do something like this:

typedef void(*FUN)(int *); char * myNewFunc; char *allocExecutablePages (int pages) { template = (char *) valloc (getpagesize () * pages); if (mprotect (template, getpagesize (), PROT_READ|PROT_EXEC|PROT_WRITE) == -1) { perror ("mprotect"); } } void f1 (int *v) { *v = 10; } // allocate enough spcae but how much ?? myNewFunc = allocExecutablePages(...) /* Copy f1 somewere else * (how? assume that i know the size of f1 having done a (nm -S foo.o)) */ ((FUN)template)(&val); printf("%i",val); 

thank you for your responses

+6
source share
5 answers

You seem to have figured out some of the protection flags. If you know the size of the function, now you can simply execute memcpy () and pass the address f1 as the source address.

One big caveat is that on many platforms you won’t be able to call any other functions from the one you are copying (f1), since relative addresses are hardcoded to the binary of the function and move it to another place where memory can do these relative addresses are bad.

+6
source

This works because function1 and function2 are the same size in memory. We need the length of function2 for our memcopy, so we need to do the following: int diff = (& main - & function2);

You will notice that you can edit function 2 to your liking, and it continues to work just fine!

By the way, a tricky trick. Without distraction, the g ++ compiler spits out an invalid conversion from void * to int ... But in fact, it compiles fine with gcc;)

Modified Sources:

 //Hacky solution and simple proof of concept that works for me (and compiles without warning on Mac OS X/GCC 4.2.1): //fixed the diff address to also work when function2 is variable size #include "stdio.h" #include "stdlib.h" #include "string.h" #include <sys/mman.h> int function1(int x){ return x-5; } int function2(int x){ //printf("hello world"); int k=32; int l=40; return x+5+k+l; } int main(){ int diff = (&main - &function2); printf("pagesize: %d, diff: %d\n",getpagesize(),diff); int (*fptr)(int); void *memfun = malloc(4096); if (mprotect(memfun, 4096, PROT_READ|PROT_EXEC|PROT_WRITE) == -1) { perror ("mprotect"); } memcpy(memfun, (const void*)&function2, diff); fptr = &function1; printf("native: %d\n",(*fptr)(6)); fptr = memfun; printf("memory: %d\n",(*fptr)(6) ); fptr = &function1; printf("native: %d\n",(*fptr)(6)); free(memfun); return 0; } 

Output:

 Walter-Schrepperss-MacBook-Pro:cppWork wschrep$ gcc memoryFun.c Walter-Schrepperss-MacBook-Pro:cppWork wschrep$ ./a.out pagesize: 4096, diff: 35 native: 1 memory: 83 native: 1 

Another point worth paying attention to: calling printf will call segfault, because printf is most likely not found due to incorrect addressing ...

+3
source

Hacky's solution and a simple proof of concept that works for me (and compiles without warning on Mac OS X / GCC 4.2.1):

 #include "stdio.h" #include "stdlib.h" #include "string.h" #include <sys/mman.h> int function1(int x){ return x-5; } int function2(int x){ return x+5; } int main(){ int diff = (&function2 - &function1); printf("pagesize: %d, diff: %d\n",getpagesize(),diff); int (*fptr)(int); void *memfun = malloc(4096); if (mprotect(memfun, 4096, PROT_READ|PROT_EXEC|PROT_WRITE) == -1) { perror ("mprotect"); } memcpy(memfun, (const void*)&function2, diff); fptr = &function1; printf("native: %d\n",(*fptr)(6)); fptr = memfun; printf("memory: %d\n",(*fptr)(6) ); fptr = &function1; printf("native: %d\n",(*fptr)(6)); free(memfun); return 0; } 
+1
source

I tried this problem many times in C and came to the conclusion that it cannot be solved using only the C language. My main turn was to find the length of the function to copy.

The standard C language does not provide any methods for obtaining the length of a function. However, you can use assembly language and "sections" to determine the length. Once the length is found, copying and executing is easy.

The simplest solution is to create or define a linker segment containing this function. Write an assembly language module for calculating and publicly declaring the length of this segment. Use this constant for function size.

There are other methods that include configuring the layout, for example, predefined areas or fixed locations and copying these locations.

In embedded earth systems, most of the code that copies the executable to RAM is written to the assembly.

0
source

This may be a hacking solution. Could you make a dummy variable or function immediately after the function (for copying), get the address of the dummy variable / function, and then take the address of the function to do the sum of the arithmetic using the addresses to get the size of the function? This is possible because the memory is distributed linearly and orderly (and not randomly). This will also save the ANSI C portable copy function, rather than delving into the build system code. I believe that C is flexible enough, you just need to think about it.

0
source

Source: https://habr.com/ru/post/1333565/


All Articles