我一直在思考如何保护我的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的共识是对未来相当乐观。
我这么说很随意,但对于那些习惯于本能地忽视混淆技术的人来说——这是不同的。如果它被证明是真正的工作和实际,这确实是重要的,而不仅仅是为了混淆视听。
传统的逆向工程技术依赖于智能代理使用反汇编程序回答关于代码的问题的能力。如果你想要更强的安全性,你必须做一些事情,可以证明阻止代理得到这样的答案。
您可以通过依赖停止程序(“程序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/
关于隐藏代码要记住的第一件事:不是所有的代码都需要隐藏。
最终目标:我对大多数软件程序的最终目标是能够出售不同的许可证,这些许可证将打开和关闭我的程序中的特定功能。
最佳技术:我发现构建一个像WordPress提供的钩子和过滤器系统,绝对是迷惑对手的最佳方法。这允许您加密某些触发器关联,而无需实际加密代码。
这样做的原因是,您希望加密尽可能少的代码。
了解你的破解者:了解这一点:破解代码的主要原因不是因为恶意分发许可,实际上是因为需要更改你的代码,而他们真的不需要分发免费副本。
入门:撇开少量要加密的代码,其余的代码应该尝试塞到一个文件中,以增加复杂性和可理解性。
准备加密:你将在我的系统中分层加密,这也将是一个非常复杂的过程,所以构建另一个程序来负责加密过程。
第一步:使用base64名称来混淆所有内容。完成之后,将混淆的代码base64,并将其保存到一个临时文件中,该文件稍后将用于解密和运行此代码。有意义吗?
我重复一遍,因为你会一次又一次地这样做。您将创建一个base64字符串,并将其保存到另一个文件中,作为将被解密和呈现的变量。
第二步:您将把这个临时文件作为一个字符串读入并混淆它,然后将它作为base64并将其保存到第二个临时文件中,该文件将用于解密并为最终用户呈现它。
第三步:重复第二步,你想重复多少次都行。一旦你让它正常工作,没有解密错误,然后你就会想要开始为你的对手埋地雷。
雷区一:你一定要把你收到通知这件事绝对保密。因此,在第2层构建一个破解尝试安全警告邮件系统。这将让你知道你的对手的细节,如果有任何事情是错误的。
地雷二:依赖。你不希望你的对手能够运行第1层,而没有第3层、第4层或第5层,甚至没有实际设计的程序。因此,请确保在第一层中包含某种终止脚本,如果程序不存在,该脚本将被激活,或在其他层中。
我相信你能想出你自己的地雷,玩得开心。
需要记住的事情:你可以加密你的代码,而不是base64。这样,简单的base64就不会解密程序。
奖励:记住,这实际上是你和对手之间的一种共生关系。我总是在第一层里面放一条评论,评论祝贺破解者,并给他们一个促销码,以便从你那里获得现金奖励。
让现金奖励意义重大,但不涉及偏见。我通常会说500美元左右。如果你的男朋友是第一个破解密码的人,那就付钱给他,成为他的朋友。如果他是你的朋友,他就不会分发你的软件。问问他是怎么做到的,你可以如何改进!
好运!
通过不公开来保证安全并不像比他聪明得多的人所证明的那样有效
我们两个。如果你必须保护你的客户的通信协议,那么你是
道德上有义务使用最好的代码,这些代码是公开的,并由专家全面审查。
这适用于人们可以检查代码的情况。如果您的应用程序是在嵌入式微处理器上运行的,那么您可以选择一个具有密封功能的微处理器,这使得在运行时不可能检查代码或观察更多的琐碎参数,例如当前使用情况。(是的,除了硬件入侵技术,你要小心地拆卸芯片,使用先进的设备来检查单个晶体管上的电流。)
我是x86逆向工程汇编程序的作者。如果你准备感冒的话
惊喜,寄给我你竭尽全力的结果。(通过我的网站联系我。)
在我所看到的答案中,很少有人会给我带来实质性的障碍。如果你想看的话
如何复杂的逆向工程代码工作,你真的应该研究网站
逆向工程挑战。
你的问题需要澄清一下。你怎么能保守协议的秘密,如果
计算机代码可以进行逆向工程吗?如果我的协议是发送一个RSA加密消息(甚至是公钥),通过保持协议的秘密,你能得到什么?
出于所有实际目的,检查器将面对一系列随机比特。
问候阿尔伯特