Dereferencing function pointers in C to access COD

2019-02-13 08:17发布

We are dealing with C here. I'm just had this idea, wondering if it is possible to access the point in memory where a function is stored, say foo and copying the contents of the function to another point in memory. Specifically, I'm trying to get the following to work:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void foo(){
    printf("Hello World");
}

int main(){

    void (*bar)(void) = malloc(sizeof foo);
    memcpy(&bar, &foo, sizeof foo);


    bar();
    return 0;
}

But running it gives a bus error: Bus error: 10. I'm trying to copy over the contents of function foo into a space of memory bar and then executing the newly created function bar.

This is for no other reason than to see if such a thing is possible, to reveal the intricacies of the C language. I'm not thinking about what practical uses this has.

I'm looking for guidance getting this to work, or otherwise to be told, with a reason, why this won't work

EDIT Looking at some of the answers and learning about read, write, and executable memory, it just dawned upon me that it would be possible to create functions on the fly in C by writing to executable memory.

2条回答
女痞
2楼-- · 2019-02-13 08:38

With standard C, what you try to do is implementation defined behaviour and won't work portably. On a given platform, you might be able to make this work.

The memory malloc gives you is typically not executable. Jumping there causes a bus error (SIGBUS). Assuming you are on a POSIX-like system, either allocate the memory for the function with mmap and flags that cause the memory region to be executable or use mprotect to mark the region as executable.

You also need to be more careful with the amount of memory you provide, you cannot simply take the size of a function and expect that to be the length of the function, sizeof is not designed to provide this kind of functionality. You need to find out the function length using some other approach.

查看更多
不美不萌又怎样
3楼-- · 2019-02-13 08:40

On modern desktops, the virtual memory manager is going to get in your way. Memory regions have three types of access: read, write, and execute. On systems where code segments have only execute permission, the memcpy will fail with a bus error. In the more typical case, where only code segments have the execute permission, you can copy the function, but not run, because the memory region that contains bar will not have execute permission.

Also, determining the size of the function is problematic. Consider the following program

void foo( int *x )
{
    printf( "x:(%zu %zu) ", sizeof x, sizeof *x );
}

int main( void )
{
    int x = 0;
    foo( &x );
    printf( "foo:(%zu %zu)\n", sizeof foo, sizeof *foo );
}

On my system, the output is x:(8 4) foo:(1 1) indicating that taking the sizeof a function pointer, or the function itself, is not a supported operation.

查看更多
登录 后发表回答