编译器保持内联函数和数组值

Compiler keeps inlining functions and array values

我正在尝试实施一种反分析技术,其中一些关键功能被加密并且仅在使用前解密然后再次加密。 因此,我的实现涉及到拥有一个数组,该数组将保存外部加密器将用于识别和加密所述函数的函数地址和长度。

我的问题是编译器一直使用数组中的值作为常量而不是访问,这使得加密器无法定位函数等等,我已经尝试了几个编译器选项,但 none我在找什么。我正在寻找使函数数组具有单个副本而不是内联的方法,因为当前。

编辑:编译器是VS2019 编辑 2:澄清问题

数组需要从二进制文件中导出,即它需要是executable的符号table中的public符号。

在 Windows,那将是:

using Function = ...;

__declspec(dllexport) const Function encrypted_functions[] = { f1, f2, ... };

在非 Windows 平台上,您需要使用 gold 链接器并确保符号可见:

#ifdef __cplusplus
extern "C" {
#endif
__attribute__((visibility ("default")) const Functions encrypted_functions[] = ...;
#ifdef __cplusplus
}
#endif

然后 use the gold linker's --export-dynamic-symbol=encrypted_functions option 将符号添加到导出 table(或 LLVM 链接器中的等效项)。即使它是 C 符号,该名称也可能被破坏,因此您需要使用 objdump 检查目标文件以查看该数组的真实符号名称是什么。

但这有点傻,因为加密程序应该是构建过程的一部分,并且应该直接与目标文件交互。最好的方法是使用与 LLVM 项目捆绑在一起的 libObject。见 source files, the headers, and some documentation.