我一直在思考如何保护我的C/ c++代码不被反汇编和逆向工程破坏。通常情况下,在我的代码中,我绝不会宽恕这种行为;然而,为了各种人的安全,我目前正在研究的协议决不能被检查或理解。

现在这对我来说是一个新的主题,互联网并没有真正的资源来防止逆向工程,而是描述了大量关于如何逆向工程的信息

到目前为止我想到的一些事情是:

Code injection (calling dummy functions before and after actual function calls) Code obfustication (mangles the disassembly of the binary) Write my own startup routines (harder for debuggers to bind to) void startup(); int _start() { startup( ); exit (0) } void startup() { /* code here */ } Runtime check for debuggers (and force exit if detected) Function trampolines void trampoline(void (*fnptr)(), bool ping = false) { if(ping) fnptr(); else trampoline(fnptr, true); } Pointless allocations and deallocations (stack changes a lot) Pointless dummy calls and trampolines (tons of jumping in disassembly output) Tons of casting (for obfuscated disassembly)

我的意思是,这些是我想过的一些事情,但它们都可以在适当的时间框架内由代码分析师解决。我还有别的选择吗?


当前回答

很多时候,担心你的产品被逆向工程是多余的。是的,它可以被逆向工程;但它是否会在短时间内变得如此出名,以至于黑客们会发现它值得逆转。它吗?(对于大量的代码行来说,这项工作不是一个小时间活动)。

如果它真的能赚钱,那么你就应该筹集足够的资金,通过专利或版权等合法途径来保护它。

恕我直言,采取你将要采取的基本预防措施,然后释放它。如果它成为逆向工程的一个点,这意味着你已经做得非常好,你自己会找到更好的方法来克服它。祝你好运。

其他回答

看看http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_against。我相信其他人可能也能给出一个更好的来源,说明为什么通过隐匿性实现安全是一件坏事。

它应该是完全可能的,使用现代加密技术,让您的系统是开放的(我不是说它应该是开放的,只是它可以是),并且仍然具有完全的安全性,只要加密算法没有漏洞(如果您选择了一个好的算法,就不太可能),您的私钥/密码保持私有,并且您的代码中没有安全漏洞(这是您应该担心的)。

自2013年7月以来,人们对密码学上健壮的混淆(以不可区分混淆的形式)重新产生了兴趣,这似乎是由Amit Sahai的原始研究激发的。

Sahai, Garg, Gentry, Halevi, Raykova, Waters,候选人 以及所有电路的功能加密(2013年7月21日)。 Sahai, Waters,《如何使用无区别模糊处理》 可否认加密,以及更多。 Sahai, Barak, Garg, Kalai, Paneth,保护混淆不受代数攻击(2014年2月4日)。

您可以在这篇Quanta Magazine文章和IEEE Spectrum文章中找到一些提炼的信息。

目前,利用这项技术所需的资源数量使其不切实际,但AFAICT的共识是对未来相当乐观。

我这么说很随意,但对于那些习惯于本能地忽视混淆技术的人来说——这是不同的。如果它被证明是真正的工作和实际,这确实是重要的,而不仅仅是为了混淆视听。

最近有一篇论文叫做“程序混淆和一次性程序”。如果你真的想保护你的应用程序。本文主要围绕使用简单通用硬件的理论不可能结果。

如果你负担不起额外的硬件,那么还有另一篇论文,在所有具有相同功能和相同大小的程序中,给出了理论上的最佳可能混淆“On最佳可能混淆”。然而,本文表明,信息理论的最佳可能意味着多项式层次结构的崩溃。

如果这些结果不能满足你的需要,这些论文至少应该给你足够的参考书目引导去查阅相关文献。

更新:一种新的混淆概念,称为不可区分混淆,可以减轻不可能性结果(论文)

与大多数人所说的相反,基于他们的直觉和个人经验,我不认为密码安全的程序混淆通常被证明是不可能的。

这是一个完美混淆的程序语句的例子,以证明我的观点:

printf("1677741794\n");

人们永远猜不到它真正的作用是什么

printf("%d\n", 0xBAADF00D ^ 0xDEADBEEF);

关于这个问题有一篇有趣的论文,它证明了一些不可能的结果。它叫做“关于混淆程序的(Im)可能性”。

尽管这篇论文确实证明了使程序与它实现的函数不可区分的混淆是不可能的,但以某种较弱的方式定义的混淆仍然是可能的!

有人试过codemoth: http://www.sourceformat.com/code-obfuscator.htm吗? 或者Themida: http://www.oreans.com/themida_features.php ?

晚一点看起来更有希望。