【问题标题】:LoadLibrary from offset in a file从文件中的偏移量加载库
【发布时间】:2011-05-29 15:47:44
【问题描述】:

我正在编写一个可编写脚本的游戏引擎,为此我有大量执行各种任务的类。引擎的大小正在迅速增长,因此我想将大型可执行文件拆分为 dll 模块,以便仅包含游戏编写者实际使用的组件。当用户编译他们的游戏(也就是说他们的脚本)时,我希望正确的 dll 成为最终可执行文件的一部分。我已经有相当多的覆盖数据,所以我想我也许可以将 dll 存储为这个块的一部分。我的问题归结为:

是否可以欺骗 LoadLibrary 以某个偏移量开始读取文件?这将使我不必将 dll 提取到一个不干净的临时文件中,或者完全取消自动包含 dll 并简单地指示我的用户将 dll 与他们的游戏一起打包。

最初我想采用“从内存中加载 dll”的方法,但以可移植性为由拒绝了它,只是因为它看起来像一个可怕的 hack。

有什么想法吗?

亲切的问候,

菲利普·班纳法尔

【问题讨论】:

  • 您似乎在描述一个非常复杂的静态链接改造。这就是静态链接的全部意义——包括可执行文件中库代码的必要部分。
  • 嗯,这几乎是我想做的,但必须根据脚本内容来完成。因此,我无法预编译它,因为这会导致我回到现在的位置。当用户“编译”他们的游戏时,发生的并不是真正的 C++ 编译。它只是编译自己的相当高级字节码的脚本引擎。然后将此字节码加密并附加到引擎可执行文件的副本中,该可执行文件在开始执行时检查它是否附加了适当的覆盖数据。
  • 听起来您需要一个工具来确定引擎的哪些部分已使用和未使用,然后使用实际的链接器或您自己的工具适当地重新链接引擎可执行文件重新处理文件。
  • 你能推荐任何这样的工具吗?
  • 对不起,这不是我最近需要为windows平台研究的东西。您的第一个决定可能是让开发人员重新链接引擎,或者想办法从您提供的已链接的可执行文件中删除不需要的部分。

标签: windows dll loadlibrary


【解决方案1】:

您正在尝试解决一个不存在的问题。加载 DLL 实际上不需要任何物理内存。 Windows 为 DLL 内容创建内存映射文件。只有当您的程序调用该代码时,DLL 中的代码才会被加载。除了保留的内存页面,未使用的代码不需要任何系统资源。在 32 位操作系统上,你有 20 亿字节的价值。您必须编写 很多 代码才能全部使用它们,50 兆字节的机器代码已经是一个非常大的程序了。

内存映射也是你不能让 LoadLibrary() 做你想做的事情的原因。没有你需要的现实场景。

查看链接器的 /DELAYLOAD 选项以提高启动性能。

【讨论】:

    【解决方案2】:

    我认为该任务的每个解决方案都是“可怕的 hack”,仅此而已。

    我看到的最简单的方法是创建您自己的虚拟驱动器,该驱动器提供自定义文件系统并将系统访问路径从一个真实文件(您的库的编译)破解到多个单独的 DLL-s。例如像TrueCrypt 一样(它是开源的)。并且您可以使用LoadLibrary 函数而无需更改。

    但我认为唯一正确的方法是改变你的任务并且不要使用这种方法。我认为您需要使用结构、指针等创建自己的脚本解释器和编译器。

    主要是我不明白您从使用库中获得的好处。我认为当前任何已编译的代码都没有那么重,并且可能包装得很好。任何其他资源都可以在第一次调用时动态加载。您需要做的就是以正确的方式组织脚本引擎所有组件的工作周期。

    【讨论】:

      猜你喜欢
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      相关资源
      最近更新 更多