在C中取消引用函数指针以访问CODE内存

the*_*ith 7 c memory function-pointers memcpy bus-error

我们在这里处理C. 我只是想到了这个想法,想知道是否有可能访问存储函数的内存中的点foo,并将函数的内容复制到内存中的另一个点.具体来说,我正在努力让以下工作:

#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;
}
Run Code Online (Sandbox Code Playgroud)

但运行它会导致总线错误:Bus error: 10.我试图将函数的内容复制foo到一个内存空间bar然后执行新创建的函数bar.

除了查看这样的事情是否可能之外,没有其他原因可以揭示C语言的复杂性.我没想到它有什么实际用途.

我正在寻找指导让这个工作,或以其他方式被告知,有理由,为什么这不起作用

编辑查看一些答案并了解读取,写入可执行内存,我突然意识到可以通过写入可执行内存来在C中动态创建函数.

fuz*_*fuz 8

使用标准C,您尝试执行的是实现定义的行为,并且无法移植.在给定的平台上,您可以使这项工作成功.

内存malloc给你通常不可执行.跳到那里会导致总线错误(SIGBUS).假设您在类似POSIX的系统上,为函数分配内存mmap和使标志导致内存区域可执行或用于mprotect将区域标记为可执行.

你还需要更加小心你提供的内存量,你不能简单地采用函数的大小,并期望它是函数的长度,sizeof不是为了提供这种功能.您需要使用其他方法找出函数长度.

  • @FUZxxl:请阅读句子的后半部分:"......,其中的内容可以代表值".这与CPU空间无关.(但要求分离**允许**支持,例如在实施中).请注意,对于内存保护单元,您可以实现大致相同的功能,只需使用比使用固定哈佛方法更精细的纹理.这也是`sizeof(function)`产生指针大小而不是函数大小的原因 - 函数不是对象. (2认同)

use*_*109 6

在现代桌面上,虚拟内存管理器会妨碍您.内存区域有三种访问类型:读取,写入执行.在代码段仅具有执行权限的系统上,memcpy将失败并出现总线错误.在更典型的情况下,只有代码段具有执行权限,您可以复制该函数,但不能运行,因为包含的内存区域bar将没有执行权限.

此外,确定功能的大小是有问题的.考虑以下程序

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 );
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上,输出x:(8 4) foo:(1 1)表明获取sizeof函数指针或函数本身不是受支持的操作.