【问题标题】:Loading .so Files From Memory [duplicate]从内存加载.so文件[重复]
【发布时间】:2012-02-19 10:28:23
【问题描述】:

可能重复:
dlopen from memory?

我已经看到 Windows 的 DLL 文件是从内存缓冲区加载的,但我在 Linux 的任何地方都找不到它,“ld”源代码是我见过的最复杂的代码。所以:

有没有从内存中加载 .so 文件的例子?就算是简单的我也能完成?我只是不知道从哪里开始,尽管我已经阅读了大部分 ELF 规范,但它对我来说仍然很神秘。

【问题讨论】:

  • .so 是通过套接字连接发送的,我正在寻找解决方案伴侣,而不是替代方案。
  • @killercode 您正在为您定义的问题寻找解决方案。您目前缺乏从记忆中编写 .so 的知识,并且想花钱请别人来做。替代方案更有意义,除非您能给我们一些背景信息。
  • .so 是通过套接字发送的,我不想将它写入磁盘,因为我的应用程序可能没有权限将文件写入磁盘,所以我想从内存中运行它以避免任何任何平台上的那些,而不仅仅是 linux。
  • killercode... 你能找到答案吗?你有一些代码要显示吗?

标签: c linux shared-objects


【解决方案1】:

您正在查看错误的源代码:ld 不执行程序和库加载。相反,您应该查看在 libc 中找到的 dlopendlsym 函数的源代码。另外,您应该查看dynamic链接器的来源:ld-linux.so(真实名称因平台而异;执行ldd /bin/ls 以找出动态链接器所在的位置)。

ELF 解析并不难,但需要注意细节并理解特定 CPU 的汇编代码;您还需要针对您的平台的 ABI 规范(32 位和 64 位 linux 不同,CPU 之间也不同。)

如果您只需要在运行时从内存中加载目标文件(即,它不必是 SO),您可以查看 X11 项目:他们已经实现了一个模块该系统基本上是在某个地址加载目标代码并重新定位它。

【讨论】:

    【解决方案2】:

    您需要 dlopen() 系列函数(在 GNU/Linux 上,它们在 /usr/include/dlfcn.h 中定义)。

    例如,看看how PHP does modules

    【讨论】:

    • 我知道如何从磁盘使用.so,我想从内存中使用它们,它们不会存在于磁盘上
    【解决方案3】:

    “从内存中加载.so 文件”对您意味着什么?

    如果你有任何*.so 文件,那么它在某个文件系统中,并且有一个路径。然后就用dlopen就可以了。

    如果不是文件,那是什么?你是怎么进入记忆的?你到底有什么记忆? (内存中有 ELF 标头和 ELF 布局吗?)

    如果您有足够的信息来制作 ELF *.so 文件,请将此类文件转储(即写入)到某个文件系统中(如果您关心磁盘性能,请使用像 tmpfs 这样的临时文件系统)。然后dlopen那个。

    如果您没有足够的信息来制作 ELF .so 文件,那么您可能正在内存中动态构建代码。看看现有的机器代码生成基础设施(如LLVMGCCJITlibjitGNU lightningLuaJit ....)正在做什么。

    如果您在内存中有完整的功能代码,请确保内存可以使用 mmapmprotect 执行并跳转到其中(例如使用函数指针技巧)。

    【讨论】:

    • 我对负面反馈感到非常惊讶。我说错了什么?为什么我的回答不相关?
    • 没有完全回答他似乎试图(固执地)实现他想要的方式,但这些信息通常很有用。 +1
    • 我不明白原始海报“从内存中加载.so文件”的确切含义......(甚至从内存中加载任何类型的文件),因为文件只能从文件系统中读取。我猜想 Windows 有这样的功能,因为 Windows 上的(IIRC)多个进程不能一次对文件进行操作(例如,你不能删除 Windows 上另一个进程打开的文件,但你可以在 Linux 上这样做) .
    • 他设想通过套接字传递一个 .so 文件,因此他将整个文件的内容保存在内存中,并希望从那里有效地dlopen() 它,而不是从磁盘上。
    • 原始发帖人没有提到任何类型的套接字或管道。但是,如果他在这样一个(不可搜索,非mmap-able)文件描述符上获取.so ELF 文件的内容,唯一明智的选择是将其写入文件,然后dlopen 那文件。
    猜你喜欢
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多