在 gcc 汇编中重新排序函数

Psy*_*rio 2 assembly gcc

我正在编写一个程序,该程序在内存中加密/解密自身,然后将 .text 内存区域写入可执行文件的副本,以便我每次都可以更改加密密钥。

这主要是为了挑战,因为我不太擅长 C,而且我也在组装中合并零件。

我的系统是 x86_64 Linux 但我使用 -m32 进行编译

我还使用 -nostartfiles (与 gcc 一起),以便我可以编写自己的 _start 函数。该函数是用汇编语言编写的,它会解密/加密 .text 部分的其余部分。我的问题是外部函数是以错误的顺序编译的,这样当我尝试在加密后转储内存时,它会调用一个加密函数,因此该函数不起作用。

这是函数的当前顺序:

  • 一些来自-static
  • 我的函数顺序正确(汇编函数,然后是主 C 文件中的函数)
  • 更多来自-static

这不起作用,因为程序集从主 C 文件“向下”加密,还加密了程序集函数所需的一些静态函数。

这是我希望函数的顺序:

  • 所有 -static 函数和 #include <> 中的任何内容
  • .S 汇编文件中的函数(整个 .S 按顺序)
  • .c 主文件中的函数(整个 .c 按顺序)
  • .c 主文件的任何非标准包含(即不是 stdio.h 等,来自 #include "" 的内容)

除了手动修改 ELF 文件之外,有什么方法可以重新排序这些函数,以便我需要的函数不被加密,而我想要加密的函数可以轻松加密?

使用 musl(替代 libc)编译后进行编辑,我可以在开始时获得所有函数,以及后面的其余静态函数。然而,这仍然是错误的方法。

exa*_*ple 6

二进制文件中函数的“错误”顺序来自编译器的优化工作。经常使用(或经常一起使用)的函数彼此靠近,因此调用它们不会产生页面错误。

您可以使用 flag 关闭部分优化-fno-toplevel-reorder。您还可以使用该属性section仅将函数的子集排序在一起(例如对它们进行加密),或者您可以编写自己的链接描述文件

另请参阅这个问题