我一直在思考如何保护我的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://www.hex-rays.com/idapro/的副本并分解一些二进制文件。

CPU需要执行代码的事实是你的失败。CPU只执行机器代码…程序员可以阅读机器代码。

话虽如此……你可能有不同的问题,可以用另一种方式解决。你想保护什么?根据您的问题,您可以使用加密来保护您的产品。

其他回答

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

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

安全网哨兵(原阿拉丁)。不过要注意的是——他们的API很烂,文档也很烂,但与他们的SDK工具相比,这两者都很棒。

I've used their hardware protection method (Sentinel HASP HL) for many years. It requires a proprietary USB key fob which acts as the 'license' for the software. Their SDK encrypts and obfuscates your executable & libraries, and allows you to tie different features in your application to features burned into the key. Without a USB key provided and activated by the licensor, the software can not decrypt and hence will not run. The Key even uses a customized USB communication protocol (outside my realm of knowledge, I'm not a device driver guy) to make it difficult to build a virtual key, or tamper with the communication between the runtime wrapper and key. Their SDK is not very developer friendly, and is quite painful to integrate adding protection with an automated build process (but possible).

Before we implemented the HASP HL protection, there were 7 known pirates who had stripped the dotfuscator 'protections' from the product. We added the HASP protection at the same time as a major update to the software, which performs some heavy calculation on video in real time. As best I can tell from profiling and benchmarking, the HASP HL protection only slowed the intensive calculations by about 3%. Since that software was released about 5 years ago, not one new pirate of the product has been found. The software which it protects is in high demand in it's market segment, and the client is aware of several competitors actively trying to reverse engineer (without success so far). We know they have tried to solicit help from a few groups in Russia which advertise a service to break software protection, as numerous posts on various newsgroups and forums have included the newer versions of the protected product.

最近,我们在一个较小的项目上尝试了他们的软件许可解决方案(HASP SL),如果您已经熟悉HL产品,那么这个解决方案就足够简单了。它似乎有效;目前还没有关于盗版事件的报道,但这款产品的需求要低得多。

当然,没有什么保护措施是完美的。如果有人有足够的动机,并且有大量的现金可以烧,我相信HASP提供的保护是可以规避的。

有一件事到目前为止还没有被提及:

您可以在自己的端(服务器端,例如由REST API调用)运行部分代码。这样,逆向工程师就完全无法访问代码。

当然,这只适用于

延迟 交通量 计算和I/O功率 隐私问题

不会阻止服务器端执行(部分)您的代码。

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

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

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

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

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

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

printf("1677741794\n");

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

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

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

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