【问题标题】:Do compilers put data inside .text section of PE or ELF files? if so, why?编译器是否将数据放入 PE 或 ELF 文件的 .text 部分?如果是这样,为什么?
【发布时间】:2019-08-10 06:31:54
【问题描述】:

所以前段时间有人问过这个问题:

Why do Compilers put data inside .text(code) section of the PE and ELF files and how does the CPU distinguish between data and code?

但最重要的答案是文本部分中没有数据,编译器不会这样做!

但我在 ollydbg 中调试时遇到了一些二进制文件,我在 .text 中看到了一些奇怪的字节,我猜这可能是数据,我仍然阅读声称数据可能在 .text 部分内的论文

这实际上是静态反汇编成为一个无法确定的问题的原因(至少学术论文声称它是),因为他们说数据可能在文本部分内,我们永远无法知道

所以我想一劳永逸地解决这个问题,如果您想回答这个问题,请提供来源

  1. 编译器是否将数据放入 .text 部分?如果是这样,您知道哪些编译器和编译器版本可以做到这一点?

  2. 如果他们这样做,那是为什么呢?我阅读了我链接的问题的答案,但我无法理解它,因为我并不是真正的硬件专家,所以你们能提供一个更简单的解释,软件开发人员可以理解吗?

这里有另一个说法是我们无法区分可执行文件中的数据和代码:

https://www.usenix.org/legacy/publications/library/proceedings/usenix03/tech/full_papers/prasad/prasad_html/node5.html

将代码与二进制文件中的数据区分开来是一个根本无法确定的问题

【问题讨论】:

    标签: x86 cpu compiler-optimization decompiler


    【解决方案1】:

    对于 x86,gcc/clang/ICC/MSVC 不会将数据与代码混合,因为它毫无意义,就像我在对链接问题的回答中所说的那样。 (不计算立即数,它显然会作为指令的一部分进行解码)。 .text 部分的结尾和.rodata 部分的开头可能在 TEXT 段内相邻,但这不是您的意思。

    对于非 x86 ELF 二进制文件(例如 ARM),它们确实混合了代码和只读数据,以允许仅使用 12 位或更小的偏移量进行相对于 PC 的加载,以适合固定宽度的加载指令。

    经过混淆的 x86 二进制文件肯定会混入一些数据,或者只是让反汇编变得困难,因此看起来可能存在一些数据。静态反汇编通常在编译器生成的没有被有意混淆的代码上很容易。任何混淆反汇编的东西都可以使它看起来像可能的数据。是的,这是无法确定的。


    我在链接的答案中没有说不存在具有混合代码 + 常量的二进制文件。 我只是说普通优化编译器不会这样做,并且它没有性能优势.只有反逆向工程的优势,假设数据是只读的,性能代价很小。 (如果数据是读/写的,则成本非常高。)

    二进制混淆是人们在商业软件中使用的真实事物。我一点也不惊讶你在野外发现了不能干净地反汇编的二进制文件。但这是在编译后完成的,从编译器输出生成一个新的混淆二进制文件。 (或者也许使用编译器插件?我真的不确定)。但不是编译器 proper 这样做,这是构建工具链中的后续步骤。我认为销售二进制混淆软件的人销售的是二进制->二进制转换器,而不是编译器。

    我从来没有在任何 Linux 发行版(例如 /usr/bin 或 /usr/lib 中的东西)上反汇编 gcc/clang 输出时遇到任何问题。如果没有调试符号,您将获得大量指令块,但反汇编不会与执行方式不同步。函数之间的填充是长 NOP,在函数底部的 retjmp 之后正常解码。或者对于 MSVC,填充是单字节 int3 指令,它再次不会像 00 00 字节 (add [rax], al) 那样对下一个函数的开始进行解码。

    请注意您的声明(存在混淆的二进制文件)与链接的论文中更强有力的声明之间的区别来自另一个问题(优化编译器出于性能原因积极地这样做,包括x86)。

    如果你想实现必须为每个二进制文件工作的二进制重写,那么是的,你有一个大问题。但如果您只需要关心非混淆的编译器输出,那就容易多了。

    【讨论】:

      猜你喜欢
      • 2019-08-31
      • 2017-01-25
      • 1970-01-01
      • 2021-12-17
      • 2012-02-06
      • 2011-05-29
      • 1970-01-01
      • 2017-06-21
      • 2012-12-19
      相关资源
      最近更新 更多