长话短说,我有一个整数数组,它表示具有一个函数的 ELF 二进制文件的 .text 部分。我想执行这个功能。我在尝试执行命令之前已运行此命令:
mprotect(function, sHeader.sh_size, PROT_EXEC | PROT_READ | PROT_WRITE);
认为它可能会解决权限问题,但当我尝试运行它时它仍然出现段错误:
int (*fp)(int, int) = (int (*)(int, int))getFunc("t.o");
int a = 2;
int b = 3;
cout << fp(a, b) << "\n";
但当我尝试运行它时它仍然出现段错误:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000603010 in ?? ()
有什么我错过的吗?
我尝试执行的函数的 objdump:
0000000000000000 <mult>:
mult():
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 89 75 f8 mov %esi,-0x8(%rbp)
a: 8b 45 fc mov -0x4(%rbp),%eax
d: 0f af 45 f8 imul -0x8(%rbp),%eax
11: 5d pop %rbp
12: c3 retq
最佳答案
安ELF目标文件包含 relocation信息,很可能是 .text
部分包含要重新定位的代码,因此代码不会按原样运行。使用objdump
和readelf
命令来探索它。如果您确实想按照自己的方式加载它,则应该处理重定位信息,这是复杂的、特定于处理器的且乏味的。如果您确实想花几周时间来做这件事,请研究 x86-64 ABI 。但使用dlopen
的.so
然后dlsym
更简单(因为 dlopen
在拥有 mmap
中的 t.so
-ed 段之后进行重定位),请参见下文。
x86-64 ABI 曾经位于 http://x86-64.org/documentation/abi.pdf但该网站今天无法运行
什么是getFunc
?你如何在你的t.o
内进行搬迁? ?为什么你不能拥有 t.so
共享对象(例如使用 gcc -Wall -fPIC -O -shared t.c -o t.so
编译)然后使用 dlopen(3) 加载它和dlsym(3)
例如
typedef int functionsig_t (int, int);
void* dlh = dlopen("./t.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "dlopen t.so failed with %s\n", dlerror());
exit(EXIT_FAILURE);
};
functionsig_t* fp = (functionsig_t*) dlsym(dlh, "myfunc");
if (!fp) {
fprintf(stderr, "dlsym myfunc failed with %s\n", dlerror());
exit(EXIT_FAILURE),
}
// now you can call fp
int res = (*fp) (1,2);
一旦fp
使用 t.so
中的任何函数返回且不存在调用堆栈帧你可以dlclose(dlh);
这将 munmap
来自t.so
的片段。您可以避免调用 dlclose
(这通常会造成进程地址空间的轻微泄漏;请参阅文件 /proc/1234/maps
以了解 pid 1234 的进程),特别是如果您不这样做 dlopen
大量共享对象。
如果t.so
插件从主程序调用函数,您希望该主程序与 -rdynamic
链接选项 ld
或gcc
如果t.so
已从某些 C++ 源代码编译,它应该声明
extern "C" int myfunc(int,int);
因为name mangling由 g++
完成
我的manydl.c程序显示你可以做几十万个dlopen
-s 在 Linux 进程中。它的工作原理是生成“随机”C 代码,并将其编译成一些 .so
,和dlopen
- 那个.so
文件,然后重复多次。
如果您不想承担编译 .c
的负担或.cc
代码写入 .so
插件,您可以考虑使用 LLVM 进行内存中即时代码生成, asmjit , libjit , GNU lightning等等...
关于c++ - 是否可以将数组数字作为函数执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14291381/