Function body on the heap

The program has three sections: text, data and stack. The body of the function is in the text section. Can we let body functions live on a heap? Since we can more freely manipulate memory on the heap, we can get more freedom to manipulate functions.

In the following C code, I copy the text of the hello function to the heap, and then point to the function pointer. The program compiles gcc, but gives a "Segmentation Error" at startup.

Could you tell me why? If my program cannot be restored, could you please provide the ability to include the function in a bunch? Thank!

Turing.robot

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

void
hello()
{
    printf( "Hello World!\n");
}

int main(void)
{
    void (*fp)();

    int size = 10000;     //  large enough to contain hello()
    char* buffer;
    buffer = (char*) malloc ( size );
    memcpy( buffer,(char*)hello,size );
    fp = buffer;
    fp();
    free (buffer);

    return 0;
}
+3
source share
6 answers

. ... "", , . . . , , , . , ""? , , . , "hallo". , , .

+2

, , .

:

  • ... no pc-relative address, .,.
  • pc ( ), , , , printf(), .

. , , , ( ?), .

Adam, , , . , , .

clobbered memcpy().

- , , . memcpy- - , - :

f() { 
...
}

g() {
...
}

memcpy(dst, f, (intptr_t)g - (intptr_t)f)
+1

segfault, memcpy'ing , ""; 10000 , , , segfault, , .

, mmap() - , , , , .

, , (, Java JIT ), , , ( , , ). , , objdump , , "", , .

+1

Linux x86_64 gcc, .

?

, . JIT (Just-in-time). . this.

, .

, JavaScript, JIT-.

C- hello , . gcc, " " .

"Segmentation fault" .

:

 int size = 10000;     //  large enough to contain hello()

x86_64 , gcc hello, 17 :

0000000000400626 <hello>:
  400626:   55                      push   %rbp
  400627:   48 89 e5                mov    %rsp,%rbp
  40062a:   bf 98 07 40 00          mov    $0x400798,%edi
  40062f:   e8 9c fe ff ff          call  4004d0 <puts@plt>
  400634:   90                      nop
  400635:   5d                      pop    %rbp
  400636:   c3                      retq   

, 10 000 , "Segmentation fault".

-, malloc, , Linux x86_64, "Segmentation fault".

malloc brk, sbrk mmap. , mmap PROT_EXEC.

-, gcc hello, , , .

, 4 hello

40062f: e8 9c fe ff ff          call  4004d0 <puts@plt>

gcc puts printf, .

x86 , , call , , , , call , . Intel Vol, 2A 3-123, .

call.

, call e8 :

E8 - Call near, relative, displacement relative to next instruction. 32-bit displacement sign extended to 64-bits in 64-bit mode.

, .

, memcpy , call, , , , , "Segmentation fault".

, ? !

, :

  • , printf , , gcc .
  • , , .
  • mmap PROT_EXEC.
  • Pass printf heap_function, gcc call.

:

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


typedef int (*printf_t)(char* format, char* string);
typedef int (*heap_function_t)(printf_t myprintf, char* str, int a, int b);


int heap_function(printf_t myprintf, char* str, int a, int b) {
    myprintf("%s", str);
    return a + b;
}

int heap_function_end() {
    return 0;
}


int main(void) {
    // By printing something here, `gcc` will include `printf`
    // function at some address (`0x4004d0` in my case) in our binary,
    // with `printf_t` two argument signature.
    printf("%s", "Just including printf in binary\n");

    // Allocate the correct size of
    // executable `PROT_EXEC` memory.
    size_t size = (size_t) ((intptr_t) heap_function_end - (intptr_t) heap_function);
    char* buffer = (char*) mmap(0, (size_t) size,
         PROT_EXEC | PROT_READ | PROT_WRITE,
         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    memcpy(buffer, (char*)heap_function, size);

    // Call our function
    heap_function_t fp = (heap_function_t) buffer;
    int res = fp((void*) printf, "Hello world, from heap!\n", 1, 2);
    printf("a + b = %i\n", res);
}

main.c :

gcc -o main main.c && ./main
+1
memcpy( buffer,(char*)hello,size );

hello , . , . hello char* , . .

-1

malloc , null buffer = (char*) malloc ( size ); memcpy( buffer,(char*)hello,size );, , . ?

-1

All Articles