Copy an existing function to the memory buffer

I am trying to load a function into the associated memory buffer and call it later, so I made a test case:

auto func() -> void{ asm( "nop;" "nop;" "nop;" "nop;" ); } auto main(int argc, char *argv[]) -> int{ void *exec_mem = mmap(nullptr, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); // check errors here memcpy(exec_mem, reinterpret_cast<const void*>(func), 5); // size is known (reinterpret_cast<void(*)()>(exec_mem))(); // function call munmap(exec_mem, getpagesize()); } 

Which works fine, but as soon as I try to make something even trivial, I get segfault.

I tried to perform a simple variable assignment as follows:

 int x; auto func() -> void{ x = 5; } 

and now my function calls segfaults. I have resized the buffer accordingly and am sure that the correct memory is being written to the buffer.

What important piece of information do I miss? Why can't I do this?

PS Please do not give me a lecture on unsafe code, this is a simple exercise for personal training.

+5
source share
1 answer

Ignoring the fact that this is a blatant undefined behavior, if you are assigning a global variable, the generated code will most likely use relative addressing to refer to the variable on some architectures.

That is, the function expects that x itself will be at the given address, and if you move it, everything will break.

This is what my GCC generates for your test function:

 x: .zero 4 .text .globl _Z4funcv .type _Z4funcv, @function _Z4funcv: .LFB2: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $5, x(%rip) nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc 

Pay attention to movl $5, x(%rip) , which means that the code uses its own address (stored in% rip) to calculate the position of x and store 5 in it.

So, there is no easy way to do what you are trying to do, unless you are sure that your function has position-independent code . And even then, he only asks for trouble.

+4
source

All Articles