复制和调用function

我想复制并调用一个函数,但调用缓冲区时,下面的代码段错误。 我需要改变什么? (Linux,x86)

#include <string.h> #include <malloc.h> #include <stdio.h> int foo () { return 12; } void foo_end () {} int main () { int s = (unsigned long long) foo_end - (unsigned long long) foo; int (*f) () = (int (*)()) malloc (s); memcpy ((void*) f, (const void*) foo, s); printf ("%d %d\n", f (), foo ()); } 

编辑:工作解决scheme:

 #include <string.h> #include <malloc.h> #include <stdio.h> #include <sys/mman.h> #include <unistd.h> int foo () { return 12; } void foo_end () {} int main () { int s = (unsigned long long) foo_end - (unsigned long long) foo; int (*f) () = (int (*)()) malloc (s); memcpy ((void*) f, (const void*) foo, s); long ps = sysconf (_SC_PAGESIZE); void *fp = (void*) ((unsigned long long) f & ~((unsigned long long) (ps-1))); if (mprotect ((void*) fp, ps, PROT_READ | PROT_WRITE | PROT_EXEC)) return -1; printf ("%d %d\n", f (), foo ()); } 

Solutions Collecting From Web of "复制和调用function"

可能您使用的操作系统不会授予数据段的执行权限。

一些环境将保护数据页面不被执行,以避免各种类型的安全问题(或者攻击它们)。

考虑调用mprotect()来启用该页面的执行并报告发生了什么。

哇,那个代码有这么多问题。

  1. 你不能知道这些函数在内存中是按顺序排列的,在它们之间没有填充
  2. 你不能知道指向两个函数的指针是可以减去的
  3. 你不能知道malloc()返回的malloc()可以被调用

总之,不要这样做。

更新:

在Linux中,我认为你可以使用mprotect()来设置一块内存的权限。 我认为这需要根,但显然不是(只要你在自己的进程记忆)。

这是嵌入式系统中的一个普遍问题。 这种技术通常用于从只读存储器复制到随机存取存储器(可读写)。 使用标准的C或C ++没有优雅和标准的解决方案。

一个更简单的解决方案是使用链接器来定义一些新的非标准段。 使用非标准的#pragma指示编译器将函数放入新的段中。 使用非标准的编译器指令来访问这个段的起始地址和结束地址。 这将允许您获取函数的大小。

目标的一个更安全的方法是创建具有可执行文件和写入属性的另一个段。 将函数段中的数据复制到此可执行段中。 设置一个函数指针来指向这个段的开始。 通过指针执行功能。

另一个解决方案是用汇编语言来执行。 通常,组装者会给你更多的自由(拍摄你的脚)来操作这样的内存。

另外,请查看您的操作系统加载程序,内存属性和保护方案。 某些操作系统可能会将这种行为限制为内核特权或更高。