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

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

 #include  #include  #include  void foo(){ printf("Hello World"); } int main(){ void (*bar)(void) = malloc(sizeof foo); memcpy(&bar, &foo, sizeof foo); bar(); return 0; } 

但运行它会出现总线错误: Bus error: 10 。 我正在尝试将函数foo的内容复制到内存bar空间,然后执行新创建的functionbar

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

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

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

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

内存malloc为您提供通常不可执行的内容。 跳到那里会导致总线错误( SIGBUS )。 假设您使用类似POSIX的系统,可以使用mmap为函数分配内存,使用导致内存区域可执行的标志,或者使用mprotect将区域标记为可执行文件。

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

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

此外,确定function的大小是有问题的。 考虑以下程序

 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 ); } 

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

Interesting Posts