内存中函数的校验和

时间:2010-12-01 20:59:28

标签: c++ function memory checksum

我正在为程序制作一种反黑客的东西,我希望能够创建一个函数字节的校验和,看看它是否已被修改。我知道如何进行校验和,但是如何得到校验和的字节数?有没有办法获得我的功能的大小?

4 个答案:

答案 0 :(得分:4)

甚至不要尝试。您不能假设函数在内存中是连续的:它可能具有起始地址低于其入口点的基本块;它可以与其他功能共享尾随基本块;它可能包含散布数据或对齐字节,也可能完全消失,具体取决于调用站点(由于编译器决定内联函数)。

您的代码无法知道生成的函数的大小。试想一下:大小完全取决于编译器发出的内容,并且取决于所有类型的编译器设置和标志(想想优化的,大量内联的发布版本与调试版本或使用增强的指令集如SSE与不使用它们)。

另外,正如已经指出的那样,这样的校验和检查对于作为黑客来说是微不足道的 - 只是你必须反转的另一个分支。

最后,作为一个好奇的练习,因为潜在的恶意黑客也会使用它,我建议通过IDA Pro反汇编程序锁定你的二进制文件。这将使您的预期反黑客攻击的许多问题变得明显......

如果您真的想继续沿着这条路走下去,我建议您使用反reversing resources或在您的代码上运行后处理步骤 a)通过插入连接它们的跳转将所有函数链接在一起,这些跳跃将永远不会被捕获。隐藏不透明谓词后面的分支。这将使拆卸难以阅读/理解,甚至会破坏一些进行静态流量分析的反汇编器,因为这会产生巨大的功能。
b)通过单个大分支函数重定向所有函数调用。这将对您的代码产生性能影响,但它也会使调用图完全无法使用/不可读。

答案 1 :(得分:2)

理论上你可以使用指向你的可执行文件中的函数的符号的长度(假设你可以得到它),但它实际上并不需要是正确的 - 系统不关心,它只是转到函数的开头并运行直到函数返回。您可以尝试查找下一个函数的开始并假设函数是顺序的(除了填充,但没有理由不仅仅是校验和),但这需要您知道哪个函数在您想要校验和之后。无论哪种方式,您都必须让可执行文件在内存中进行分析才能找到标题的那一部分

答案 2 :(得分:0)

代码通常位于只读内存中,因此无法更改。

但是您可以为DLL嵌入校验和,以便在加载后立即验证自己的映像,并在DLL磁盘映像被修改后中止。但是操作系统还没有做过吗?

答案 3 :(得分:0)

Standard不允许将函数用作sizeof运算符的参数。所以没有可移植的方法来获得函数体的大小。此外,函数不一定要放在连续的存储块中。几个函数的一部分可以在一个地方混洗(这就是VS在Release版本中所做的)。