c - 如何将二进制数据添加(和使用)到已编译的可执行文件中?

标签 c exe elf portable-executable

有几个问题涉及这个问题的某些方面,但似乎都没有完全回答。整个问题可以总结如下:

  • 您有一个已经编译好的可执行文件(显然希望使用这种技术)。
  • 您想向其中添加任意大小的二进制数据(不一定是它本身,这将是另一个需要处理的棘手问题)。
  • 您希望已编译的可执行文件能够访问此添加的二进制数据。

我的特定用例是解释器,我想让用户能够从解释器二进制文件和他提供的代码中生成单个可执行文件(解释器二进制文件是可执行文件,必须是用用户提供的代码作为二进制数据进行修补)。

类似的情况是自解压存档,其中一个程序(存档实用程序,例如 zip)能够构建这样一个包含预构建解压缩程序的可执行文件(已编译的可执行文件)和用户提供的数据(存档的内容)。显然,此过程中没有编译器或链接器参与(感谢 Mathias 的注释并指出 7-zip)。

使用现有问题,解决方案的特定路径显示在以下示例中:

appending data to an exe - 这涉及将任意数据添加到任意 exe 的方面,没有涵盖如何实际访问它(基本上简单的附加通常有效,对于 Unix 的 ELF 格式也是如此)。

Finding current executable's path without /proc/self/exe - 与上述相伴,这将允许获取用于打开 exe 的文件名,以访问添加的数据。这类问题还有很多,但是都没有特别关注获得适合实际将二进制文件作为文件打开的路径的问题(单独的目标可能(?)更容易实现 - 真的你不知道甚至需要路径,只需要打开二进制文件进行阅读即可)。

可能还有其他比填充二进制文件并打开文件以读取它更优雅的方法来解决这个问题。例如,是否可以制作可执行文件,以便以后用任意大小的数据,因此它出现在某些适当的数据段中的“内部”? (我真的找不到任何东西,对于固定大小的数据,它应该是微不足道的,除非可执行文件有一些散列)

这是否可以在与标准 C 的偏差尽可能小的情况下合理地完成?甚至或多或少跨平台? (至少从维护的角度来看)请注意,如果执行添加二进制数据的程序不依赖编译器工具来完成它(用户可能没有),那将是首选,但需要这些的解决方案也可能有用.

请注意已编译的可执行文件标准(上面列表中的第一点),这需要一种与 C/C++ with GCC: Statically add resource files to executable/library 等问题中描述的解决方案完全不同的方法。或 SDL embed image inside program executable ,它要求嵌入数据编译时。

补充说明:

上面概述并在一些评论中建议的明显方法的问题,即仅附加到二进制文件并使用它,如下所示:

  • 打开当前正在运行的程序的二进制文件似乎不是一件小事(打开可执行文件进行阅读是,但找不到提供给文件打开调用的路径,至少不是以合理的跨平台方式)。<
  • 获取路径的方法可能会提供一个攻击面,否则可能不会存在。这意味着潜在的攻击者可能会欺骗程序以查看可执行文件实际具有的不同二进制数据(由他提供),从而暴露数据解析器中可能存在的任何漏洞。

最佳答案

这取决于您希望其他系统如何查看您的二进制文件。

Windows 中的数字签名

exe 格式允许验证文件自发布后未被修改。这将使您能够:-

  1. 编译你的文件
  2. 添加你的数据包
  3. 签署您的文件并发布它。

遵循这个系统的好处是,“每个人”都同意您的文件自签名后没有被修改。

实现此方案的最简单方法是使用资源。可以在链接后添加 Windows 资源。它们受到authenticde数字签名的保护,您的程序可以从自身中提取资源数据。

过去可以增加签名以包含二进制数据。不幸的是,这已被禁止。有些二进制文件使用签名部分中的数据。不幸的是,这被恶意使用。这里有一些细节 msdn blog

破坏签名

如果重新签名不是一个选项,那么结果将被视为不安全。此处值得注意的是,附加数据是不安全的,可以在人们无法察觉的情况下进行修改,但二进制文件中的代码也是如此。

将数据附加到二进制文件确实会破坏数字签名,也意味着最终用户无法判断代码是否已被修改。

这意味着您添加到代码中以确保数据 blob 仍然安全的任何 self 保护都不会阻止您的代码被修改以删除检查。

运行模块

Windows GetModuleFileName 允许找到运行路径。

Linux 提供/proc/self/proc/pid

Unix 好像没有可靠的方法。

数据读取

zip格式的做法,是在文件末尾写一个目录。这意味着可以在位置的末尾找到数据,然后向后查找数据的开始。这里的优势是,数据 blob 是从数据末尾开始标记的,而不是自然开始的。

关于c - 如何将二进制数据添加(和使用)到已编译的可执行文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32437714/

相关文章:

python - 使用 Python 运行带参数的可执行文件

windows - 如何知道 80000003 断点后面是否隐藏了不同的异常(WER 对话框)

java - 从 eclipse 包中提取后损坏的 ELF header /部分

Python 选项解析器覆盖 '-h'

c - 在内核和用户端保持 Netlink Socket 打开

c++ - 如何使用 MSVC 在 C++ 中定义外部 C 结构返回函数?

c - 为什么这个数组中的第一个元素不存储任何值?

c - 将文件的值存储到数组中会导致奇怪的行为

installation - 安装程序与 zip 或可执行 exe?

elf - ELF规范中,BA_OS和KE_OS是什么意思?