保护可执行文件免受逆向工程?


210

我一直在考虑如何保护我的C / C ++代码免于反汇编和逆向工程。通常,我永远不会在自己的代码中宽恕这种行为。但是,为了所有人的安全,我目前正在研究的当前协议绝不能被检查或理解。

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

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

  • 代码注入(在实际函数调用之前和之后调用伪函数)
  • 代码混淆(破坏二进制文件的反汇编)
  • 编写我自己的启动例程(调试器很难绑定到)

    void startup();  
    int _start()   
    {  
        startup( );  
        exit   (0)   
    }  
    void startup()  
    {  
        /* code here */  
    }
  • 运行时检查调试器(如果检测到,则强制退出)

  • 功能蹦床

     void trampoline(void (*fnptr)(), bool ping = false)  
     {  
       if(ping)  
         fnptr();  
       else  
         trampoline(fnptr, true);  
     }
  • 没有意义的分配和释放(堆栈变化很多)

  • 无意义的虚拟呼叫和蹦床(拆卸输出中的大量跳跃)
  • 吨铸件(用于模糊拆卸)

我的意思是,这是我想到的一些事情,但是在适当的时间范围内,代码分析人员可以解决所有这些问题,或者可以由代码分析人员弄清楚这些问题。我还有别的选择吗?


172
“但是,为了所有人的安全,我目前正在研究的当前协议绝不能被检查或理解。” -祝你好运。
琥珀

62
您可以使您的应用程序难以逆向工程。只要其他人手中有相当一部分碎屑,就不可能做到这一点。谨慎保证全面的安全性,尤其是在生命受到威胁的情况下-您无法交付。
2011年

127
如果您的计算机可以理解该代码,那么一个人也可以。
Lightness竞赛,

78
将代码设为“开源”,没有人会对其进行反向工程。
用户未知

28
“默默无闻的安全从来没有奏效。”
bot47 2011年

Answers:


151

琥珀所说的完全正确。您可以使逆向工程更加困难,但是您永远无法避免。您永远不应信任依赖于防止逆向工程的“安全性”

也就是说,我所见过的最好的反逆向工程技术不是集中在混淆代码上,而是集中在破坏人们通常用来理解代码工作原理的工具上。与仅产生大量可怕的意大利面条式代码相比,寻找创造性的方法来破坏反汇编程序,调试器等可能不仅更有效,而且在智力上更令人满意。这无济于事,无法阻止坚定的攻击者,但确实增加了J Random Cracker徘徊而从事更轻松工作的可能性。


14
我了解这一点,并且阅读了一些有关Skype安全性的文章,并且我一直在考虑Skype已经尝试使用的相同想法,但并不是阻止而是保护我的协议。考虑到Skype的明显情况,已经证明足够有价值。
石墨

8
Skype实际上是想到的第一个示例,因此,很高兴您已经在模拟它们的方法。
莉吉特

175

但是只要有适当的时间范围,代码分析人员就可以解决所有这些问题,也可以通过代码分析找出它们。

如果您给人们提供了他们可以运行的程序,那么他们也将在足够的时间对其进行反向工程。这就是程序的本质。一旦二进制文件可供想要解密的人使用,您就无法阻止最终的反向工程。毕竟,计算机必须能够解密才能运行它,而人类只是速度较慢的计算机。


113
+1。阅读有关Apple II上复制保护的辉煌时光,混淆器和饼干之间不断升级的战争,软盘步进电机的疯狂技巧以及未记录的6502指令等信息,然后哭着说。睡眠,因为您不会执行任何如此复杂的事情,并且最终都被破解了。
Nemo

2
与尝试通过视觉或反汇编程序进行反向工程相比,更容易使用模拟器并获得更好的可见性。如果您所使用的硬件中没有内置安全性,那么我认为世界平均需要大约两天到两周的时间来进行反向工程并击败几乎所有出现的问题。如果花超过两天的时间来创建和实现此功能,则您花费了太多时间。
old_timer 2011年

5
如今,唯一可正常运行的DRM是密钥和Internet服务器的组合,该服务器可在一次timem上验证密钥的仅一个实例处于活动状态。
托尔比约恩Ravn的安德森

2
@Rotsor:计算机无法理解它,因为我们还无法将这种智能化为一种算法(尚未),不是因为存在某种物理或技术障碍。人们之所以能够理解它,是因为他可以做计算机可以做的任何事情(尽管速度较慢)以及推理
亚当·罗宾逊

3
此时,除非计算机只能在您控制的环境中可用,否则有人会尝试对计算机进行反向工程。
2012年

41

安全网络哨兵(以前称为阿拉丁)。需要注意的是-他们的API很糟糕,文档也很糟糕,与它们的SDK工具相比,两者都很不错。

我已经使用了他们的硬件保护方法(Sentinel HASP HL)多年了。它需要一个专有的USB密钥卡,它可以作为软件的“许可证”。他们的SDK会对您的可执行文件和库进行加密和混淆,并允许您将应用程序中的不同功能绑定到密钥中烧录的功能。没有许可方提供并激活的USB密钥,该软件将无法解密,因此将无法运行。密钥甚至使用自定义的USB通信协议(在我的知识范围之外,我不是设备驱动者)使构建虚拟密钥或篡改运行时包装程序和密钥之间的通信变得困难。他们的SDK对开发人员不是很友好,并且很难将添加保护与自动构建过程集成在一起(但可能)。

在我们实施HASP HL保护之前,有7位已知的海盗从产品中剥夺了dotfuscator的“保护”。我们在软件的主要更新的同时添加了HASP保护,它可以对视频进行实时的大量计算。从性能分析和基准测试中可以最好地看出,HASP HL保护仅将密集计算的速度降低了约3%。自大约5年前发布该软件以来,尚未发现该产品的新盗版者。它所保护的软件在其市场领域中需求很高,并且客户知道一些竞争者正在积极地尝试逆向工程(到目前为止没有成功)。我们知道他们已经尝试从俄罗斯几个团体中寻求帮助,这些团体宣传一项旨在破坏软件保护的服务,

最近,我们在一个较小的项目上尝试了他们的软件许可证解决方案(HASP SL),如果您已经熟悉HL产品,那么它就很容易上手。它似乎有效;没有盗版事件的报道,但该产品的需求量低得多。

当然,没有任何保护措施是完美的。如果有人有足够的动力,并且有足够的现金可以燃烧,我相信HASP提供的保护措施可以被规避。


19
主持人注意: 由于进入对立噪声,此答案下的注释已被删除。
蒂姆·波斯特

2
+1是经验,但我想回应一下这并不完美。Maya(3D套件)使用了硬件加密狗(不确定是否是HASP),这种加密狗在很长一段时间内并未阻止海盗。只要有意志,就有办法。
罗伯特·弗雷泽

1
AutoCAD使用了类似的系统,该系统已被破解多次。HASP和其他类似程序将使诚实的人保持诚实,并防止偶然的盗版。如果您要开发下一个价值数十亿美元的设计产品,那么您总会遇到麻烦。这一切都是关于收益递减的问题-值得花几个小时的时间来破解软件保护,而不仅仅是付出代价。
RyanR 2011年

6
我也想从使用过HASP安全软件的人的角度来了解一下。对于最终用户而言, HASP简直就是一团糟。我已经处理了Dallas iButton和Aladdin HASP,但它们确实有错误,导致该软件随机停止工作,需要断开并重新连接HASP。
假名称

4
另外,值得注意的是,与代码混淆相比,HASP安全措施并不一定要更加安全-确保它们需要不同的方法来进行反向工程,但是很有可能将它们进行反向-请参阅:flylogic.net/blog/?p=14 flylogic.net/blog/?p=16 flylogic.net/blog/?p=11
虚假名称

22

最好的反反汇编技巧,特别是在可变字长的指令集上,是在汇编/机器代码中,而不是在C中。例如

CLC
BCC over
.byte 0x09
over:

反汇编程序必须解决分支目标是多字节指令中的第二个字节的问题。指令集模拟器虽然没有问题。分支到您可能会从C引起的计算地址,这也使反汇编变得困难甚至不可能。指令集模拟器将没有问题。使用模拟器为您整理分支目的地可以帮助拆卸过程。编译后的代码相对来说比较干净,反汇编起来也很容易。因此,我认为需要一些组装。

我认为这是迈克尔·阿布拉什(Michael Abrash)的《汇编语言禅》(Zen of Assembly Language)的开篇之作,在那里他展示了一个简单的反反汇编和反调试技巧。8088/6有一个预取队列,您所做的就是拥有一条指令,该指令可以修改下一条指令或几条指令。如果单步执行,则执行修改后的指令;如果指令集模拟器未完全仿真硬件,则执行修改后的指令。在正常运行的实际硬件上,只要您没有再次执行该指令串,实际指令就已经在队列中,并且修改后的内存位置不会造成任何损坏。当流水线处理器获取下一条指令时,您今天可能仍会使用这样的技巧。或者,如果您知道硬件具有单独的指令和数据高速缓存,那么如果您在高速缓存行中正确对齐此代码,则可以在前面修改多个字节,修改后的字节将不会通过指令高速缓存写入,而是通过数据高速缓存写入,并且没有适当的缓存模拟器的指令集模拟器将无法正确执行。我认为只有软件的解决方案不会使您走得太远。

以上是古老且众所周知的,我对当前的工具了解不足,无法知道它们是否已经解决了这些问题。自修改代码可以/将使调试器崩溃,但是人类可以/将缩小问题范围,然后查看自修改代码并解决。

过去,黑客需要大约18个月的时间才能完成某些工作,例如DVD。现在,他们平均需要2天到2周的时间(如果有动力)(蓝光,iphone等)。对我来说,这意味着如果我在安全方面花费了几天以上,那很可能浪费我的时间。您将获得的唯一真正的安全性是通过硬件实现的(例如,您的指令已加密,并且只有芯片内部的处理器内核才在执行之前进行解密,从而无法公开解密的指令)。那可能会花上几个月而不是几天。

另外,请阅读凯文·米特尼克(Kevin Mitnick)的《欺骗的艺术》。像这样的人可以拿起电话,让您或同事将系统的秘密透露给系统,以为它是公司另一部分的经理或另一位同事或硬件工程师。这样您的安全性就大打折扣了。安全并不只是管理技术,还必须管理人员。


1
同样,您不必访问源代码(甚至是反汇编的源代码)即可发现安全漏洞。这可能是偶然的,也可能是因为大多数漏洞来自代码中的相同问题(例如缓冲区溢出)。
asmeurer 2011年

2
自修改代码存在很大的问题。如果没有非常高的特权,大多数现代的OS /硬件将不允许您这样做,可能会出现缓存问题,并且代码不是线程安全的。
马丁·詹姆斯

1
对于现代x86处理器,此类技巧通常对性能不利。将同一存储器位置用作一个以上指令的一部分可能会产生与错误预测分支相似的效果。自修改代码使处理器丢弃缓存行,以保持指令缓存和数据缓存之间的一致性(如果您执行修改后的代码的次数多于修改后的代码,则可能仍然是一个胜利)。
jilles 2011年

2
我在20年前遇到了这个问题。我们花了将近半个小时才弄清楚发生了什么。如果需要更长的保护时间,效果不是很好。
Bo Persson

1
“真正的指令将已经在队列中,并且修改后的内存位置不会造成任何损坏”,直到在两者之间发生中断,刷新指令管道,并使新代码可见。现在,您的困惑给合法用户带来了一个错误。
Ben Voigt 2015年

21

AES算法为例。这是一个非常非常公开的算法,非常安全。为什么?原因有两个:许多专家对此进行了审查,“秘密”部分不是算法本身-秘密部分是密钥,它是算法的输入之一。用代码之外的生成的“秘密”设计协议的方法要好得多,而不是使代码本身成为秘密。无论您做什么,都始终可以解释该代码,并且(理想情况下)生成的秘密只能通过大规模的暴力手段或盗窃来破坏。

我认为一个有趣的问题是“ 为什么要混淆代码?” 您想使攻击者难以破解您的算法吗?使他们更难在代码中找到可利用的bug?如果代码首先不可破解,则无需混淆代码。问题的根源是可破解软件。解决问题的根源,不要仅仅混淆它。

另外,使代码混乱的程度越大,发现安全漏洞的难度就越大。是的,这对黑客来说很难,但是您也需要查找错误。从现在起,代码应该易于维护,甚至编写良好的清晰代码也可能难以维护。不要让它变得更糟。


3
+1是常识:当您只想设计一个更好的系统时,为什么要增加对自己的难度。
Necrolis 2011年

1
就像我经常说的那样,如果您保留服务器端的所有内容,则它会更安全
liamzebedee 2011年

20

使代码难以逆向工程称为代码混淆。

您提到的大多数技术都相当容易解决。他们以添加一些无用的代码为中心。但是,无用的代码易于检测和删除,从而为您提供了干净的程序。

为了进行有效的混淆,您需要使程序的行为取决于正在执行的无用位。例如,而不是这样做:

a = useless_computation();
a = 42;

做这个:

a = complicated_computation_that_uses_many_inputs_but_always_returns_42();

或代替这样做:

if (running_under_a_debugger()) abort();
a = 42;

做到这一点(在哪里running_under_a_debugger应该不容易被识别为测试代码是否在调试器下运行的功能,它应该将有用的计算与调试器检测混合在一起):

a = 42 - running_under_a_debugger();

有效的混淆并不是纯粹在编译阶段就可以做的。无论编译器可以做什么,反编译器都可以做到。当然,您可以增加反编译器的负担,但是步伐不会太快。尽管存在有效的混淆技术,但从第一天开始就需要编写混淆的源代码。使您的代码能够自我修改。利用从大量输入中得出的经过计算的跳转来乱码。例如,代替简单的调用

some_function();

执行此操作,您碰巧知道以下位的确切预期布局some_data_structure

goto (md5sum(&some_data_structure, 42) & 0xffffffff) + MAGIC_CONSTANT;

如果您对混淆感到认真,请在计划中增加几个月的时间。混淆并不便宜。并且要考虑到到目前为止,避免人们对您的代码进行反向工程的最佳方法是使它无用,以免他们打扰。这是一个简单的经济考虑:如果对他们的价值大于成本,它们将进行反向工程;但是提高成本也会增加您的成本,因此请尝试降低其价值。

既然我已经告诉过您,混淆既困难又昂贵,我将告诉您无论如何都不适合您。你写

出于各种人的安全考虑,我一直在研究的当前协议绝不能被检查或理解。

这引起了危险。默默无闻安全的,它的记录很差。如果该协议的安全性取决于不了解该协议的人员,那么您已经迷路了

推荐阅读:

  • 安全圣经:罗斯·安德森的安全工程
  • 迷惑的圣经:克里斯蒂安·柯伯格和贾斯维尔·纳格拉的秘密软件

1
@Gilles,这是您的声明,非常有力,因此举证责任就在于您。但是,我将提供一个简单的示例:2+2可以通过编译器简化为4,但反编译器无法将其恢复为2+2(如果实际上是1+3?)。
Rotsor 2011年

7
@Rotsor 42+2在观察上是等效的,因此在此目的上它们是相同的,即弄清楚程序在做什么。是的,当然,反编译器无法重建源代码,但这无关紧要。此次问答是关于重构行为(即算法,更确切地说是协议)的问题。
吉尔(Gilles)“所以,别再邪恶了”,

1
您无需执行任何操作即可重建行为。您已经有了该程序!通常,您需要了解协议并对其进行更改(例如,将2 in替换为2+23或将其替换+*)。
Rotsor 2011年

1
如果您认为所有行为等效的程序都相同,那么可以,编译器无法执行任何操作,因为它仅执行身份转换。反编译器也就没有用了,因为它又是身份转换。但是,如果不这样做,则2+2-> 4是编译器执行的不可逆转换的有效示例。它使理解变得更容易或更困难是一个单独的论点。
Rotsor 2011年

2
@吉尔斯,我无法与苹果进行类比,因为我无法想象一个结构上不同但行为等同的苹果。:)
Rotsor 2011年

13

很多时候,担心您的产品被反向工程错了。是的,可以进行反向工程;但是它会在短时间内变得如此著名,以至于黑客会发现值得逆转。呢?(对于大量的代码行,这项工作不是一项小时间活动)。

如果它确实成为一个赚钱的人,那么您应该已经收集了足够的钱来使用专利和/或版权之类的法律方法来保护它。

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


1
我的意思是,这是一个可行且适用的答案,但是您在保护和获得数百万美元的收入(让其他人为您保护产品)之间划界的界限确实很长。
石墨

12

阅读http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_against。我确信其他人也可能会提供更好的信息,说明为什么默默无闻的安全性是一件坏事。

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


2
我会同意这一点。我认为您可能有一个概念或设计问题。是否有带有公钥-私钥对解决方案的模拟产品?您永远不会泄露私钥,它由安全客户端处理它的所有者拥有。您能否将安全代码保留在他们的计算机之外,而仅将结果传递回用户?
Dizzley 2011年

8

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

您可以在此《Quanta杂志》文章和该IEEE Spectrum文章中找到一些摘要信息。

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

我非常随便地说这句话,但对于习惯于本能地消除混淆技术的每个人来说,这是不同的。如果事实证明它确实可行并且切实可行,那么这确实很重要,而不仅仅是混淆。


7

为了使自己了解信息,请阅读有关代码混淆的学术文献。亚利桑那大学的克里斯蒂安·柯尔伯格(Christian Collberg)是该领域的著名学者。哈佛大学的Salil Vadhan也做了一些出色的工作。

我在这本书上是落后的,但是我知道的基本思想是,您不能阻止攻击者看到您将要执行的代码,但是您可以将其围绕执行的代码,这会花费很多攻击者的指数时间(使用最著名的技术)来发现代码的哪些片段被执行而哪些未被执行。


7

最近有一篇论文叫做“ 程序混淆和一次性程序 ”。如果您真的很认真地保护您的应用程序。通常,本文使用简单通用的硬件来解决理论上不可能的结果。

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

如果这些结果不能满足您的需要,那么这些论文至少应为您提供足够的书目线索,以便您查阅相关文献。

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


6

如果有人想花费时间来反转二进制文件,那么您绝对无能为力。您可以使难度稍大一些,但是仅此而已。如果您真的想了解这一点,请获取http://www.hex-rays.com/idapro/的副本并分解一些二进制文件。

CPU需要执行代码的事实是您要撤消的事情。CPU仅执行机器代码...,程序员可以读取机器代码。

话虽这么说...您可能有另一个可以解决的问题。您要保护什么?根据您的问题,您可能会使用加密来保护您的产品。


6

为了能够选择正确的选项,您应该考虑以下方面:

  1. “新用户”是否有可能不想付费但要使用您的软件?
  2. 现有客户是否可能需要比他们更多的许可证?
  3. 潜在用户愿意支付多少?
  4. 是否要按用户/并发用户/工作站/公司授予许可证?
  5. 您的软件是否需要培训/定制才能有用?

如果对问题5的回答为“是”,则不必担心非法副本。无论如何它们都不会有用。

如果问题1的答案为“是”,则首先考虑定价(请参阅问题3)。

如果您对问题2回答“是”,则“按使用付费”模式可能适合您。

根据我的经验,按使用付费+定制和培训是对您的软件的最佳保护,因为:

  • 定价模式吸引了新用户(少用->少付)
  • 几乎没有“匿名用户”,因为他们需要培训和定制。
  • 没有软件限制会吓跑潜在客户。
  • 现有客户不断产生资金。
  • 由于长期的业务关系,您将从客户那里获得宝贵的发展反馈。

在考虑引入DRM或混淆之前,您可能会想到这些要点以及它们是否适用于您的软件。


很好的建议(我赞成),但是它并没有真正解决这个特定问题
Mawg说,请恢复莫妮卡(Monica)2016年

5

首先,虚拟机中受保护的代码似乎不可能进行反向工程。塞米达·帕克(Themida Packer)

但这不再那么安全了。无论您如何打包代码,您都可以始终对任何已加载的可执行文件进行内存转储,并使用诸如IDA Pro之类的反汇编程序对其进行反汇编。

尽管生成的代码看起来更像是指针/地址的数学混乱,但IDA Pro还附带了一个漂亮的汇编代码,可以转换为C源代码。


5

没有骰子,您不能保护代码免于反汇编。您可以做的是为业务逻辑设置服务器,并使用Web服务为您的应用程序提供服务器。当然,这种情况并非总是可能的。


8
可以说,避免人们拆卸您的代码的唯一方法是永远不要让他们完全物理上访问它,这意味着将您的应用程序专门作为SAAS提供,接受远程客户端的请求并移交处理后的数据。将服务器放在密闭的地下室中,该地下室中有鳄鱼沟和5m高的剃须刀金属丝,在将其全部用10m钢筋混凝土覆盖之前,您将钥匙扔掉了,然后希望您不要忘记安装吨软件系统,以防止通过网络入侵。
jwenting 2011年

6
我希望我永远不会获得维护服务器的合同
Colin Pickard

5

为避免进行反向工程,不得将代码提供给用户。就是说,我建议您使用在线应用程序……但是(因为您未提供任何上下文)对您来说可能毫无意义。


这是真正的解决方案...即将您的皇冠上的宝石放在您自己的VPS机器上的您自己的服务器中,并且仅将来自客户端(浏览器或api客户端)的API调用公开到该服务器中
Scott Stensland

5

可能您最好的选择仍然是使用虚拟化,它会引入旁路需要的另一种间接/混淆级别,但是正如SSpoke在回答中所说,该技术也不是100%安全的。


关键是您将不会获得最终保护,因为没有这样的东西,而且即使有,它也不会持续很长时间,这意味着它最初并不是最终保护。

任何人组装,都可以拆卸。

通常,(适当)拆卸通常是(有点或更多)艰巨的任务,因此您的对手必须更熟练,但是您可以假设总会有这样的人,这是一个安全的选择。

如果要保护某些产品免受RE影响,则必须至少了解RE使用的常用技术。

因此话

互联网对于预防逆向工程并不是真正有用的资源,而是描述了大量有关如何进行逆向工程的信息

对你的态度不好。我并不是说要使用或嵌入保护,您必须知道如何打破它,但要明智地使用它,您应该知道其弱点和陷阱。您应该了解它。

(有一些软件使用保护方式错误的示例,使得这种保护几乎不存在。为避免含糊其辞,我将在Internet:CD-ROM v4上的牛津英语词典第二版中为您简要介绍一个示例。您可以阅读有关在以下页面中无法成功使用SecuROM:在16位,32位或64位Windows环境中的CD-ROM上的牛津英语词典(OED):硬盘安装,错误,文字处理宏,网络,字体和等等

一切都需要时间。

如果您是这个主题的新手,并且没有几个月甚至几年的时间来完全熟悉可再生能源,那么请使用其他人提供的可用解决方案。这里的问题很明显,因为它们已经存在,所以您已经知道它们不是100%安全的,但是进行自己的新保护只会给您一种虚假的被保护感,除非您真正了解最新技术。逆向工程和保护(但至少现在还没有)。

软件保护的重点是吓跑新手,停滞常见的RE,并在经验丰富的RE(非常有趣)到达您的应用程序中心之后对经验丰富的RE露出笑容。

在商务谈话中,您可能会说这一切都是在尽可能延迟竞争。

(看看Philippe Biondi和Fabrice Desclaux 在Skype上发表的精彩演讲“ 银针”在 Black Hat 2006上的表现)。


您知道那里有很多关于RE的东西,所以开始阅读它。:)

我说过关于虚拟化的问题,所以我将给您链接到EXETOOLS FORUM的一个示例线程:最佳软件保护程序:Themida还是Enigma Protector?。它可能会帮助您进一步搜索。


4

我认为任何代码都不是不可破解的,但是对于想要尝试它的人来说,回报必须是巨大的。

话虽如此,您应该做一些事情,例如:

  • 尽可能使用最高的优化级别(逆向工程不仅涉及获取汇编序列,还涉及理解代码并将其移植到诸如C之类的高级语言中)。高度优化的代码可以遵循b --- h。
  • 通过不具有不必要的更大数据类型来使结构密集。在正式代码发布之间重新排列结构成员。您也可以使用结构中重新排列的位字段。
  • 您可以检查是否存在某些不应更改的值(例如版权消息)。如果一个字节向量包含“ vwxyz”,则可以有另一个字节向量包含“ abcde”,并比较差异。执行此功能的函数不应传递给矢量的指针,而应使用其他模块中定义的外部指针,如(伪C代码)“ char * p1 =&string1 [539];” 和“ char p2 =&string2 [-11731];”。这样就不会有任何指针精确地指向两个字符串。然后在比较代码中比较“(p1-539 + i)-*(p2 + 11731 + i)==某个值”。破解者会认为更改string1是安全的,因为似乎没有人引用它。将测试埋在一些意想不到的地方。

尝试自己修改汇编代码,以了解容易和难之处。应该弹出您可以尝试的想法,以使代码更难以逆向工程,并使调试更加困难。


2
您的第一点没有意义,优化的代码消除了麻烦,这使得逆转变得更加容易(我从经验上讲)。您的高峰也浪费时间,值得他精打细算的逆向工程师知道如何进行内存访问断点。这就是为什么最好不要自己设计系统,而最好还是不要“破解”我们的第三方图书馆,原因是它的持续时间可能比“菜鸟”创建的任何东西都要长...
Necrolis

既然看来我对此事一无所知,也许我应该寻求像您这样的专业人员来满足我的软件开发需求,而不是自己编写任何代码。
Olof Forshell

4

正如许多人已经说过的那样:在常规CPU上,您不能阻止它们运行,您可以延迟它们。正如我的老密码老师告诉我的那样:您不需要完美的加密,破解代码肯定比获得的价格昂贵。混淆同样适用。

但是还有3个附加说明:

  1. 可能使逆向工程成为不可能,但是(这是非常大的,但是),您不能在常规cpu上做到这一点。我也做了很多硬件开发,经常使用FPGA。例如,Virtex 5 FX上装有PowerPC CPU,您可以使用APU在硬件中实现自己的CPU操作码。您可以使用此功能真正解密PowerPC的指令,而外部或其他软件无法访问该指令,甚至可以在硬件中执行命令。由于FPGA为其配置位流内置了AES加密,因此您无法对其进行反向工程(除非有人设法破坏AES,但我想我们还有其他问题...)。这样,硬件IP供应商也可以保护他们的工作。

  2. 您是从协议说的。您没有说它是哪种协议,但是当它是网络协议时,您至少应该保护它免受网络嗅探。您确实可以通过加密来做到这一点。但是,如果您想保护加密/解密免受软件所有者的侵害,那您就回到了混乱的状态。

  3. 确保您的程序不可篡改/不可运行。尝试使用某种类型的调试检测并将其应用,例如,在某些公式中,将调试寄存器的内容添加到魔术常数中。如果程序在正常运行的情况下看起来处于调试模式,但是却进行了完全错误的计算,运算或其他操作,要困难得多。例如,我知道一些生态游戏具有非常讨厌的版权保护(我知道您不想要版权保护,但与此类似):被盗的版本在玩了30分钟后就改变了开采的资源,突然间您只得到了一个资源。海盗刚刚破解了它(即对其进行了逆向工程)-检查它是否可以运行,然后volia释放了它。这种细微的行为变化很难检测,尤其是。如果它们没有立即显示出来,而是延迟了。

所以最后我建议:估算人们对软件进行逆向工程的收益,将其转化为一定的时间(例如,通过使用最便宜的印度人的薪水),然后进行逆向工程,这样会花费更多的时间。


3

与大多数人所说的相反,基于他们的直觉和个人经验,我认为通常不会对加密安全的程序进行混淆。

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

printf("1677741794\n");

谁也猜不到它真正的作用是

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

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

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


7
1.您的示例与此处不相关;您显示的两个程序在行为上是等效的,这个问题是关于弄清楚程序的行为,而不是重构其源代码(显然这是不可能的)。2.本文为理论论文;写完美的混淆器是不可能的,但是写完美的反编译器也是不可能的(出于与无法编写完美的程序分析器相同的原因)。实际上,这是一场军备竞赛:谁可以写出更好的(反)混淆论者。
吉尔(Gilles)“所以,别再邪恶了”,

1
@Gilles,(正确的)反混淆的结果在行为上总是等同于混淆后的代码。我不认为这会破坏问题的重要性。
Rotsor 2011年

另外,关于军备竞赛:这不是关于谁在研究上投入更多,而是关于谁是对的。正确的数学证明不会出错,只是因为有人希望它们真的很糟糕。
Rotsor 2011年

1
好吧,也许您在实践中对军备竞赛是正确的。我想我误会了这一点。:)我希望可以进行某种加密安全的混淆。
Rotsor 2011年

对于混淆的有趣情况,请尝试使用智能卡,问题在于攻击者具有物理访问权限(白盒混淆)。响应的一部分是通过物理方式限制访问(攻击者无法直接读取密钥);但是软件混淆也发挥了作用,主要是使DPA之类的攻击无法产生有用的结果。抱歉,我没有很好的报价。我的答案中的示例是从该领域中使用的技术模糊地启发而来的。
吉尔(Gilles)“所以,别再邪恶了”,

3

比我们俩都聪明的人所证明的,通过默默无闻的安全性是行不通的。如果您必须保护客户的通信协议,那么从道德上讲,您有义务使用公开开放的最佳代码,并由专家进行全面审查。

这是针对人们可以检查代码的情况。如果您的应用程序要在嵌入式微处理器上运行,则可以选择具有密封功能的设备,这样就无法检查代码或观察运行时当前用法等琐碎的参数。(除了硬件入侵技术外,您还需要仔细拆卸芯片并使用先进的设备检查各个晶体管上的电流。)

我是x86逆向工程汇编程序的作者。如果您已准备好应对突如其来的意外,请把最好的努力寄给我。(通过我的网站与我联系。)在答复中我几乎看不到会对我构成重大障碍。如果您想了解复杂的逆向工程代码是如何工作的,那么您应该真正研究具有逆向工程挑战的网站。

您的问题可能需要澄清。如果计算机代码可以进行逆向工程,您如何期望对协议保密?如果我的协议是发送RSA加密消息(甚至是公共密钥),那么将协议保密会得到什么呢?出于所有实际目的,检查员将面临一系列随机位。

Groetjes Albert


3

传统的逆向工程技术取决于使用反汇编程序的智能代理程序回答有关代码问题的能力。如果您需要强大的安全性,则必须采取措施以防止代理人获得此类答案。

您可以通过通常无法解决的停止程序(“程序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/


2

关于隐藏代码的第一件事隐藏代码的:并非所有代码都需要隐藏。

最终目标:我的大多数软件程序的最终目标是销售,这将开启和关闭我的程序中的特定功能不同的许可。

最佳技巧:我发现,在试图混淆对手的过程中,建立像WordPress提供的钩子和筛选器系统是绝对最佳的方法。这使您可以加密某些触发器关联,而无需实际加密代码。

这样做的原因是,您将需要加密最少的代码。

了解您的黑客:知道这一点:破解代码的主要原因不是由于许可的恶意分发,实际上是因为需要更改您的代码,而他们实际上并不需要分发免费副本。

入门:保留少量要加密的代码,其余代码应尝试并塞入一个文件中,以增加复杂性和理解力。

准备加密:您将要使用我的系统进行分层加密,这也将是一个非常复杂的过程,因此请构建另一个负责加密过程的程序。

步骤1:对所有内容都使用base64名称进行混淆。完成后,对经过混淆的代码进行base64并将其保存到一个临时文件中,该文件随后将用于解密和运行此代码。合理?

我会重复一次,因为您会一次又一次地这样做。您将创建一个base64字符串,并将其作为变量保存到另一个文件中,该变量将被解密和呈现。

第二步:您将以字符串形式读取此临时文件并对其进行模糊处理,然后对其进行base64并将其保存到另一个临时文件中,该文件将用于最终用户解密和呈现。

第三步:根据需要重复第二步。一旦可以正常工作而没有解密错误,那么您将要开始为对手建造地雷。

地雷一号:您将要保留一个事实,即您被告知绝对是一个秘密。因此,为第2层构建一个“破解尝试”安全警告邮件系统。如果发生任何错误,将触发此通知,让您知道有关对手的详细信息。

地雷二:依赖关系。您不希望对手能够运行第1层,而没有第3层,第4层或第5层,甚至是其设计的实际程序。因此,请确保在第一层中包含某种kill脚本,如果该程序不存在,则该脚本将激活,或者在其他层中包含。

我敢肯定,您可以提出自己的地雷,并乐在其中。

要记住:实际上,你可以代替加密base64'ing它的代码。这样,简单的base64便不会解密程序。

奖励:请记住,这实际上可能是您与对手之间的共生关系。我总是在第一层中放置一个注释,该注释祝贺饼干并为他们提供了促销代码,以便从您那里获得现金奖励。

在不影响任何偏见的情况下,使现金奖励变得可观。我通常说500美元左右。如果您的家伙是第一个破解密码的人,那么请付钱给他并成为他的朋友。如果他是您的朋友,则不会分发您的软件。问他如何做到这一点,以及如何改进!

祝好运!


4
你甚至读过这个问题吗?我从未问过如何防止盗版的方法。该应用程序将是免费的,由于安全性的缘故,所使用的底层协议需要受到保护。
石墨

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.