【问题标题】:Working with ELF files使用 ELF 文件
【发布时间】:2013-03-23 11:58:03
【问题描述】:

我需要在我的 C 程序中处理简单的 ELF 文件。 我不能使用任何外部库,但我可以使用elf.h

让我们以 hello.o 文件为源:

int Hello() { return 3; }

如何在只有hello.o 文件的其他C 程序中访问Hello

我可能应该使用mmap 或类似的东西将它加载到内存中。最后我需要处理很多复杂的 ELF 文件,但我现在不知道如何开始。

更新: 我需要按照我描述的方式执行此操作,因为它是出于学习目的。 整个问题比我描述的要复杂。

对于这个问题假设我需要写方法:

int HelloFromElfO(const char* helloFile);

这将执行在helloFile 中实现的Hello 函数。

我不想要完整的答案。我不需要任何代码。我需要一些东西来开始。

我对 ELF 文件结构有基本的了解,但我不知道如何在没有任何解析器或类似的东西的情况下使用 C 语言处理二进制文件。

更新2: 好的,像 readelf 这样的应用非常复杂。所以也许我可以尝试这种方式:让我们再说一遍我有hello.o 映射到内存ptr。如何获得指向Hello 函数的指针?

如何从hello.o 获取任何结构化数据?我的意思是,不是纯字节,而是我可以使用的东西。

【问题讨论】:

  • 你没有选择简单地将它们变成共享对象,并依赖动态加载器?
  • @npe 这是学术问题。我需要这样做。
  • 尝试查看readelf 命令及其源代码,它应该显示如何从.o 文件中提取您需要的信息。也许还可以查看dlsym 源代码,因为它可以满足您的需求,但在 C 库中。
  • @teppic 谢谢!我考虑过其他更复杂的应用程序,例如链接器,但我没有考虑过轻量级的应用程序,例如 readelf 或 objdump。

标签: c linux elf


【解决方案1】:

这比您想象的要容易得多。 ELF 与您的问题无关(mmap() 甚至更远......)。 hello.o 不是 ELF 文件,它是 object 文件。

您可以将目标文件链接到您的可执行文件,然后您就可以访问Hello()。假设您已将程序编译为 yourCode.o 的目标文件,则将此 yourCode.ohello.o 链接

cc yourCode.o hello.o -o yourExecutable

here

编辑

如果你不想链接文件而是动态加载它,那么

  1. mmap()目标文件
  2. 在内存中获取Hello() 地址。您可以为此静态分析hello.o(例如使用objdump)并获取文件中的Hello()入口点偏移量。
  3. 将此偏移量与mmap()返回的地址相加得到Hello()地址。
  4. Hello() 地址映射到function pointer
  5. 调用函数。
  6. ???
  7. 利润

【讨论】:

  • 我知道。问题是我不想链接文件,我想动态加载它(我不想使用.so)。这是学术问题。我需要自己实现一些“动态链接”。
  • 请明确说明您不想在您的问题中链接,否则我们无法知道;)
  • 这里的答案适用于给定的Hello(),但不是一般情况:如果Hello() 引用其他函数(例如libc 函数)或全局数据,那么您将不得不应用重定位。使用__thread 数据会使事情变得更加复杂。
  • @EmployedRussian 你完全正确,这是 this 的例子。对于更复杂的目标文件,它比这更难。在this 项目中,如果您对更高级的示例感兴趣,其他开发人员和我成功地为 PSP 控制台这样做(尽管 PSP 可执行文件仍然比 PC 简单得多)。
  • @m0skit0 我不想在程序外分析文件。我不想处理所有 ELF 文件(带有 __thread 和更多功能),但我需要在不使用 objdump elfreader 等的情况下处理简单的 ELF。
猜你喜欢
  • 2011-03-16
  • 2016-06-20
  • 2023-03-15
  • 2014-03-08
  • 1970-01-01
  • 2021-12-17
  • 2011-03-07
  • 2013-03-29
  • 2011-04-02
相关资源
最近更新 更多