如何在C ++函数中生成一致的字节签名?

时间:2014-04-12 01:25:11

标签: visual-studio visual-c++ assembly 64-bit obfuscation

我想在C ++函数中嵌入一致的字节签名。这种签名的目的是充当信标并且提供空间用于插入/移动用于二进制混淆的指令。例如。一个工具可能会在结果二进制文件中搜索签名,然后用随机生成的代码块替换它,这些代码块实际上什么都不做,从而产生一些多态的代码。这要求签名必须与代码直接一致,编译器必须将其视为函数的一部分。

在32位Visual C ++中,可以使用内联汇编轻松完成:

int main()
{
    cout << "Hello";
    Sleep(1);

    _asm
    {
        _EMIT 0x04
        _EMIT 0x05
        _EMIT 0x06
        _EMIT 0x07
        _EMIT 0x08
        _EMIT 0x09
    }

    cout << " world" << endl;

    return 0;
}

但是我正在寻找一种方法,它也适用于由Visual C ++构建的64位二进制文​​件。

我考虑或尝试过的事情

解决方案:只使用Visual Studio的内联汇编功能

  • 问题:不支持x64

解决方案:将签名写为MASM函数(在.asm文件中)

  • 问题:无法内联这些功能

解决方案:使用内联C ++函数作为签名

  • 问题:即使__forceinline也不保证函数将被内联
  • 在测试时,编译器甚至没有实际内联函数
  • 即使它是内联的,也可以编译为每次扩展使用不同的寄存器

解决方案:宏扩展为一堆语句

  • 问题:编译器优化会破坏这些宏中捆绑的指令
  • 问题:编译器仍然为宏的每个实例使用不同的寄存器

请注意,签名扫描算法可以根据需要进行复杂化(它可以使用掩码,只扫描代码部分等,只要签名始终遵循某些模式)。此外,我正在寻找可以与生产代码一起使用的解决方案,即。禁用整个项目的优化是不行的。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

为什么不使用函数调用作为&#34;签名&#34;?而不是尝试内联代码。如果函数调用需要修复,链接器将在修正表中公布指令的位置,以便您可以根据需要从那里读取它而不是搜索。