【问题标题】:Compiler keeps inlining functions and array values编译器保持内联函数和数组值
【发布时间】:2020-06-23 15:42:34
【问题描述】:

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

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

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

【问题讨论】:

  • 您使用的是哪个编译器/工具链?听起来您需要在某些地方禁用优化,而不是使用链接时间代码生成。
  • 这是一个用于研究、娱乐或教育目的的玩具项目,还是您希望它能够承受实际攻击?
  • 我不太确定我是否完全理解这里的行为。您有一些以某种方式加密的功能。要在运行时调用它们,您需要解密函数,此时您将调用解密的例程,然后删除函数的解密版本。如果是这种情况,您是要防止对解密加密函数的例程进行内联,还是要防止对加密函数本身进行内联?如果是前者,我不知道为什么重要,如果是后者,这怎么可能?
  • 另外,您是否使用这些函数加密来启动您的可执行文件?因为如果你是,那么你已经无法防御你正在防御的任何东西。
  • 如果您的问题是“如何阻止编译器内联”,那么这是一个骗子:stackoverflow.com/questions/3329214/…

标签: c++ reverse-engineering visual-studio-2019


【解决方案1】:

数组需要从二进制文件中导出,即它需要是可执行文件符号表中的公共符号。

在 Windows 上,这将是:

using Function = ...;

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

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

#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 将符号添加到导出表(或 LLVM 链接器中的等效项)。即使它是 C 符号,该名称也可能被破坏,因此您需要使用 objdump 检查目标文件以查看该数组的真实符号名称。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2010-10-13
    • 2011-06-19
    • 2015-01-10
    相关资源
    最近更新 更多