【问题标题】:How do I load and execute an ELF binary executable manually?如何手动加载和执行 ELF 二进制可执行文件?
【发布时间】:2011-09-27 03:26:55
【问题描述】:

假设二进制文件是 PIC,我如何将它加载到内存中并执行入口点? 我这样做是为了熟悉 ELF,所以不允许使用 execve

【问题讨论】:

  • 这是一项非常重要的任务,需要的不仅仅是 ELF 知识。您可能想要制作一个 ELF 文件解析器而不是一个成熟的加载器来熟悉该格式。无论如何,您都需要一个解析器来获取main 函数的地址。
  • 有趣的问题,但我不愿给出 +1,因为它非常简洁,并没有提供有关您的背景、您已经阅读或尝试过的内容等方面的太多信息......
  • 阅读内核源码,很清楚:stackoverflow.com/questions/8352535/…

标签: c elf


【解决方案1】:

这些是基本步骤:

  1. 阅读程序标头以查找 LOAD 指令并确定您需要的映射总长度(以页为单位)。
  2. 用总长度(可能大于文件长度)映射最低地址的 LOAD 指令,让mmap 为您分配一个地址。这将保留连续的虚拟地址空间。
  3. 使用MAP_FIXED 将重新挖掘的 LOAD 指令映射到此映射的部分顶部。
  4. 使用程序头文件找到DYNAMIC 向量,这会反过来为您提供重定位向量的地址。
  5. 应用重定位。假设您的二进制文件是静态链接的 PIE 二进制文件,它们应该完全包含 RELATIVE 重定位(只需添加基本加载地址),这意味着您不必执行任何符号查找或任何花哨的操作。
  6. 在堆栈上的数组中构造一个 ELF 程序入口堆栈,该堆栈由以下系统字大小的值序列组成:

    ARGC ARGV[0] ARGV[1] ... ARGV[ARGC-1] 0 ENVIRON[0] ENVIRON[1] ... ENVIRON[N] 0 0
    
  7. (此步骤需要ASM!)将堆栈指针指向这个数组的开头,并跳转到加载程序的入口点地址(可以在程序头中找到)。

【讨论】:

  • 呃,我认为它是位置无关代码的关键是它没有重定位 - 它有全局偏移表或其他任何东西。
  • @Random832,如果它不是 PIC,我是否仍然能够实现加载器并执行二进制文件?
  • @Random832:您总是有可能进行数据重定位。 static int x, *y=&x; 还能如何工作?当然,GOT 充满了搬迁。避免任何重定位的唯一方法是避免拥有任何全局数据。
  • @R..:我认为静态链接的非 PIE 可执行文件不需要任何重定位。
  • @R..:您还应该将auxv 数组传递给程序。
猜你喜欢
  • 2015-09-10
  • 2013-11-25
  • 2011-01-20
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多