c++ - 是否可以将数组数字作为函数执行?

标签 c++ c linux elf

长话短说,我有一个整数数组,它表示具有一个函数的 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部分包含要重新定位的代码,因此代码不会按原样运行。使用objdumpreadelf命令来探索它。如果您确实想按照自己的方式加载它,则应该处理重定位信息,这是复杂的、特定于处理器的且乏味的。如果您确实想花几周时间来做这件事,请研究 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 链接选项 ldgcc

如果t.so已从某些 C++ 源代码编译,它应该声明

 extern "C" int myfunc(int,int);

因为name manglingg++ 完成

我的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/

相关文章:

c++ - c++ sizeof 运算符如何计算大小?

c++ - 关于 [expr.cond#6] 语句的一些混淆

c - 在 C 中写在单独的行上时,反斜杠\连接 printf 字符串如何?

c - 在 C 中创建一维结构数组的问题

c - 调试多线程应用程序中的信号处理

linux - 如何在没有uuencode的情况下使用html内容和xls附件发送邮件

C++ 列表迭代器在遍历时永远不会到达 end()

c++ - 如何根据模板类的基类专门化成员函数

linux - 在 Linux/Apache 上在后台运行 Cron 作业

c++ - 运算符 '...' 具有覆盖说明符但不覆盖基类成员