我一直在思考如何保护我的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)

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


当前回答

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

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

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

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

其他回答

安布尔说的完全正确。你可以让逆向工程变得更难,但你永远无法阻止它。永远不要相信依赖于防止逆向工程的“安全性”。

That said, the best anti-reverse-engineering techniques that I've seen focused not on obfuscating the code, but instead on breaking the tools that people usually use to understand how code works. Finding creative ways to break disassemblers, debuggers, etc is both likely to be more effective and also more intellectually satisfying than just generating reams of horrible spaghetti code. This does nothing to block a determined attacker, but it does increase the likelihood that J Random Cracker will wander off and work on something easier instead.

自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的共识是对未来相当乐观。

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

但只要有合适的时间框架,代码分析人员都可以解决这些问题。

如果你给人们一个他们能够运行的程序,那么只要有足够的时间,他们也能够对它进行逆向工程。这就是程序的本质。一旦二进制文件可供想要破译它的人使用,您就无法阻止最终的逆向工程。毕竟,计算机必须能够破译它才能运行它,而人类只是一台较慢的计算机。

不行,你不能保护你的代码不被反汇编。你所能做的就是为业务逻辑设置服务器,并使用webservice为你的应用程序提供它。当然,这种情况并不总是可行的。

传统的逆向工程技术依赖于智能代理使用反汇编程序回答关于代码的问题的能力。如果你想要更强的安全性,你必须做一些事情,可以证明阻止代理得到这样的答案。

您可以通过依赖停止程序(“程序X停止吗?”)来做到这一点,这通常是无法解决的。向程序中添加难以推理的程序,会使程序难以推理。构建这样的程序要比拆解它们容易。你也可以在程序中添加推理难度不同的代码;一个很好的候选程序是关于别名(“指针”)的推理程序。

Collberg等人有一篇论文(“制造廉价、弹性和隐形的不透明结构”)讨论了这些主题,并定义了各种“不透明”谓词,这些谓词会使对代码的推理变得非常困难:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1946&rep=rep1&type=pdf

我还没有看到Collberg的具体方法应用于产品代码,尤其是C或c++源代码。

DashO Java混淆器似乎使用了类似的想法。 http://www.cs.arizona.edu/~collberg/Teaching/620/2008/Assignments/tools/DashO/