我一直在思考如何保护我的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)
我的意思是,这些是我想过的一些事情,但它们都可以在适当的时间框架内由代码分析师解决。我还有别的选择吗?
自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的共识是对未来相当乐观。
我这么说很随意,但对于那些习惯于本能地忽视混淆技术的人来说——这是不同的。如果它被证明是真正的工作和实际,这确实是重要的,而不仅仅是为了混淆视听。
Take, for example, the AES algorithm. It's a very, very public algorithm, and it is VERY secure. Why? Two reasons: It's been reviewed by lots of smart people, and the "secret" part is not the algorithm itself - the secret part is the key which is one of the inputs to the algorithm. It's a much better approach to design your protocol with a generated "secret" that is outside your code, rather than to make the code itself secret. The code can always be interpreted no matter what you do, and (ideally) the generated secret can only be jeopardized by a massive brute force approach or through theft.
我认为一个有趣的问题是“为什么你想让你的代码变得模糊?”你想让攻击者难以破解你的算法?让他们更难在你的代码中发现可利用的漏洞?如果代码一开始就不可破解,那么您就不需要混淆代码。问题的根源在于易破解的软件。解决问题的根源,不要只是混淆它。
而且,你的代码越混乱,你就越难找到安全漏洞。是的,这对黑客来说很难,但你也需要找到漏洞。从现在开始,代码应该很容易维护,即使是编写良好的清晰代码也很难维护。不要让事情变得更糟。