【问题标题】:Modifying executable upon download (Like Ninite)下载时修改可执行文件(如 Ninite)
【发布时间】:2014-12-03 12:04:25
【问题描述】:

我目前正在开发一个需要在下载时进行内部修改的应用程序 (Windows)。 此外,我使用 Linux 主机交付它,因此无法按建议按需编译。
Ninite如何处理?
在 Ninite.com 中,每次您选择不同的选项时,您都会得到相同的 .exe,但在内部稍作修改。

选项 1
使用预定义数据编译程序(在 Windows 中)。
使用 PHP 查找文件并替换我的自定义字符串。

选项 2
将原始 .EXE 附加到不同的资源文件

其他?

有人开发过这样的东西吗?最好的方法是什么?
谢谢。

【问题讨论】:

  • 你想保留哪些信息?
  • 在主应用程序中?除了客户数据之外的所有内容。
  • 请编辑您的问题以改进它。您将其重点从“修补我的可执行文件”更改为“使我的应用程序持久化”
  • 不,应该是“按需修补” :) 我仍在阅读有关它的更多信息。这就是为什么我给出了 Ninite 的例子,当你点击下载时,他们会修补它。
  • 请通过编辑说明您提出问题的动机。您是想要保留大部分运行数据(然后专注于检查点和持久性),还是想要一些微小但持久的数据(例如密码)在重新启动后仍然存在?请说明您想到的数据类型和应用程序类型。

标签: c++ windows qt


【解决方案1】:

您可以将数据附加到原始可执行文件的后面。 Windows PE 文件格式足够强大,不会使可执行文件本身无效。 (但它会使任何现有的数字签名失效。)

如果事先不知道该数据的大小,则查找该数据的开头可能是一项挑战。在这种情况下,可能需要附加可变长度数据,然后附加数据长度(本身是一个固定长度字段 - 4 个字节应该可以)。要读取额外数据,请读取最后 4 个字节以获取数据长度。获取文件长度,长度字段减去4,然后减去可变长度得到数据的开头。

【讨论】:

  • 在可执行文件末尾追加 4 个字节可以改变其执行吗?
  • @Danilo:基本上,WinMain() 还是在原来的位置上,它只调用其他也在原来位置上的函数。所以这些不受影响。只有知道附加了额外数据的代码才会注意到该数据。
【解决方案2】:

最便携的方式可能是在应用程序中安装一个插件(其路径连接在主程序中)。该插件将被修改(例如在 Linux 上通过生成 C++ 代码 gencod.cc,分叉 g++ -Wall -shared -fPIC -O gencod.cc -o gencod.so 编译,然后 dlopen-ing ./gencod.so)并且您的应用程序可以生成该插件的 C++ 源代码并编译它。

我想这在 Windows 上可能也是可行的(我不知道)。问题可能是编译它(编译命令在 Windows 和 Linux 上会有所不同)。请注意,Windows 上的 AFAIK 进程无法修改其自己的可执行文件(但您应该检查)。

Qt 有一个可移植的插件层。见QPluginLoader & Qt Plugins HowTo

或者,不要修改应用程序,而是使用一些 persistent 文件或数据(在明确定义的位置,-其位置或文件路径已连接到可执行文件中-最好是文本格式,如 JSON,或者可能使用sqlite 或真实数据库)保持不断变化的信息。另请阅读application checkpointing

如果您需要实现特定的应用程序检查点,最好尽早设计您的应用程序以解决这个问题。研究 garbage collection 算法(检查点过程类似于精确复制 GC)并阅读有关 continuations 的更多信息。另请参阅 this answer 以了解非常相似的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2021-06-19
    • 2016-01-26
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多