【问题标题】:How to load ELF image to memory and execute? [duplicate]如何将 ELF 图像加载到内存并执行? [复制]
【发布时间】:2013-11-09 12:07:04
【问题描述】:

我这几天一直在尝试解决这个问题。显然,我太缺乏经验,无法从各种示例中理解实际代码,无论我多么努力,我都找不到足够简单的解释来理解。这真的不是我的一杯茶。

我的问题是,我能否获得一个链接(或答案),其中包含一些非常易于理解的伪代码或如何执行以下操作的说明:

在c程序中,将另一个ELF可执行文件加载到内存中,设置内存和堆栈以及所有其他必要的变量,然后执行它。

我了解基本概念,但对我来说并没有融合在一起。我检查了许多其他来源,包括 StackOverflow 上的这里,它们都太复杂了,我的白痴大脑无法理解。

谢谢。

【问题讨论】:

  • 查看我对可能重复的答案:stackoverflow.com/a/10417930/379897 并注意,这样做只有在您编写操作系统时才有意义。对于正常使用,您可以通过 execve 函数(或其他 exec-family 函数)“加载精灵图像”。
  • 在用户级别没有简单的方法可以做到这一点。显然,内核做到了,ld.so.1 动态加载器也参与其中。但是模拟其中任何一个都不是微不足道的。
  • @R.. 我看到了那个帖子,但对我来说真的没有意义。我知道您必须将某些内容加载到内存中,但据我所知,这是完全可以理解的。该答案在一个特定问题上过于详细;我还不是很了解。
  • @Sefu:你真正想做什么?具体来说?你真的想模拟一个操作系统的执行器吗?或者你只是想运行一个程序?
  • @rici 我正在尝试编写一个给定可执行文件(elf)的程序,在用户空间中运行给定的可执行文件。据我了解,这意味着复制二进制代码,设置堆栈并将控制权传递给新程序。我只是不知道如何实现这一点。

标签: c linux memory executable elf


【解决方案1】:

在 Linux x86 上,execve 是 11 号系统调用,可以通过以下方式调用:

long execve(const char *filename, char *const argv[], char *const envp[]){
  long r;
  asm volatile("int $128" : "=a"(r):"a"(11),"b"(filename),"c"(argv),"d"(envp):"memory");
  return r;
}

大多数 libc 将如何实现它(虽然通过错误处理等更间接...)

要了解 execve 系统调用的工作原理,请查看 linux 内核源代码。

【讨论】:

    【解决方案2】:

    在c程序中,将另一个ELF可执行文件加载到内存中,设置内存和堆栈以及所有其他必要的变量,然后执行它。

    您不能在 C 程序中真正做到这一点,因为 C 程序已经加载到内存中(从它自己的 ELF 映像)并正在运行。这两个 ELF 映像会相互冲突,因此当您尝试映射新映像时,您会在中途搞砸旧(正在运行的)映像,并且无法正常工作。

    内核在执行映像时所做的第一件事是清除(清空)用户地址空间,因此可以加载新映像而不会发生任何冲突。

    话虽如此,您可以(通过仔细的链接脚本)安排构建两个没有冲突的 ELF 映像,以便第一个可以加载第二个并且两者可以同时存在于内存中。这本质上就是 ld.so(动态链接器)的工作方式——它链接到特殊地址,因此它可以与“正常”程序共存。但是任何两个“正常”的 ELF 可执行文件都希望位于同一个地址

    【讨论】:

    • 理论上,例如,他能否完成基本内核的工作,在内核的可执行可运行地址加载 ELF 文件(即可执行程序),它只是运行或绝不可能工作吗?
    • 这不是真的。那么,UPX 是如何做到这一点的呢?去看看它的来源。
    猜你喜欢
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多