你应该为商业 .Net 应用程序混淆代码吗?

40

我正在考虑对一款商业 .Net 应用程序进行混淆。但是选择、购买和使用这样的工具真的值得吗?混淆后的二进制文件真的能够免受逆向工程吗?


4
Visual Studio 2010在使用托管代码方面比较繁重,并且没有进行混淆。在这种情况下,这是一项救命稻草,因为这是弄清楚某些可扩展API的唯一希望(某些Visual Studio功能只是随主产品安装的扩展程序)。 - Sam Harwell
8
没有什么能够逃避逆向工程。具体来说,您试图防范什么威胁?如果有人对您的代码进行逆向工程,您将损失多少?混淆器会减慢进程并阻止某些人,但它不能完美无缺,并且会有自己的成本。明智地权衡它们。 - David Thornley
3
不行:https://github.com/0xd4d/de4dot/wiki/Changelog - CAD bloke
2
当然,没有什么是可以逃脱一个决心坚定的反向工程师的,但这并不意味着轻易放弃你的代码是最好的选择。无论多么微小,障碍仍然是障碍。话虽如此,你必须考虑混淆你的代码的成本/效益,并确定是否值得承担任何不利后果。 - CatShoes
这就是我讨厌.NET产品的原因。终于可以编写本机x64代码了,但代价是由于MSIL与OpCode的工作方式不同,你的代码完全暴露了。 - Kraang Prime
显示剩余2条评论
16个回答

40

您可能不需要购买工具-Visual Studio.NET带有Dotfuscator社区版。其他免费的混淆工具在此列出,它们可能能够满足您的需求。

尽管混淆后的二进制文件可能不安全,容易被逆向工程,就像您的自行车锁可能容易被破解或者被撬开一样。然而,通常小的不便已经足以阻止潜在的代码/自行车盗贼。

此外,如果将来需要在法庭上维护代码权利,那么曾经努力保护它(通过混淆)的做法可能会给您额外的加分。 :-)

然而,您必须考虑到缺点-使用混淆代码可能更难使用反射,并且如果使用类似log4net之类的工具根据涉及的类名生成日志行的部分,这些消息可能会变得更加困难。


如果它们被正确混淆,那些日志将变得几乎不可能解释,"更加困难"似乎有点轻描淡写了 ;) - Kawa
1
请记住(理论上),您有原始代码和日志消息文本来帮助。唯一应该混淆的是类和成员名称。此外,许多工具(例如Dotfuscator)会创建映射文件,告诉您混淆构造名称映射回哪个原始名称 - 这可能使确定日志消息的确切来源变得麻烦,但远非不可能。 - Blair Conrad
3
同时,为了保留 API,公共和受保护的类型及成员名称不会被混淆,因此在混淆后,堆栈跟踪中的某些部分仍将保持完整。 - Andrew Arnott
DotFuscator的免费版本很差。它只混淆方法名称,而不是字符串等。使用Reflector仍然可以轻松阅读和跟踪代码。 - Kraang Prime
1
Dotfuscator社区版仅限个人免费使用,商业用途需付费。 - Sam

29

记住混淆只是阻止代码被随意查看的屏障。如果有人认真想弄清楚你写的内容,你将很难阻止他们。

如果你的代码中有秘密(比如密码),那么你做错了。

如果你担心有人会使用你的思路制作软件,通过提供客户需要的新版本、技术支持并成为他们的合作伙伴,你将在市场上获得更多成功。好的业务赢得市场。


12

在我们公司,我们评估了几种不同的混淆技术,但它们都存在问题。最大的问题是我们很大程度上依赖反射(例如,根据属性名称动态创建网格)。

所以所有的混淆器都会重命名东西,当然你可以禁用它,但那样你就失去了大部分混淆的好处。

此外,在我们的代码中,有很多NUnit测试依赖于更多的方法和属性是公共的,这使得一些混淆器无法混淆这些类。

最终,我们选择了一个叫做.NET Reactor的产品。

它的工作效果非常好,我们没有遇到其他产品存在的任何问题。

"与混淆器相比,.NET Reactor通过将任何纯.NET程序集(使用C#、VB.NET、Delphi.NET、J#、MSIL等编写)与本机机器码混合来完全阻止任何反编译。详细地说,.NET Reactor在潜在黑客和您的.NET代码之间建立了一个本机墙壁。结果是一个标准的基于Windows而非MSIL兼容的文件。原始的.NET代码保持完好,并受到本机代码的保护,对于窥探的眼睛是不可见的。原始的.NET代码从未在硬盘上复制。没有任何工具能够反编译.NET Reactor受保护的程序集。"


2
根据您的描述,这似乎无法阻止一个有决心的黑客使用x86反编译器。如果计算机可以执行它,那么代码就可以被反编译。 - Ant
@Ant:你尝试逆向工程一个原生代码应用程序。一个简单的for循环会有数十个看似不相关的指令。 - Andrei Rînea
10
从使用 Reactor 加密的 .NET 应用中提取 .NET 代码非常容易,甚至有多个教程可供参考。但需要注意的是,这并不意味着所有加密方式都可以轻松破解。 - mmcdole
10
根据您的描述,自动地破坏了任何可移植性的好处。 - EFraim

7
事实上,你可以进行反向工程并不意味着混淆无用。它确实显著提高了门槛。
未经混淆的 .NET 程序集将通过下载 .NET Reflector 显示所有源代码,高亮显示等。加入混淆后,将大大减少能够修改代码的人数。
这取决于你要保护自己免受什么威胁。如果你会发布未经混淆的版本,那么你可能会开源应用程序并从营销中受益。发布混淆版本只会使人们相对容易地通过补丁生成修改后的二进制文件,而无法窃取你的代码并创建直接竞争对手。根据混淆器的不同,从混淆代码中获取实际源代码非常困难。

4

需要考虑的事情:

  • 混淆并不能保护你的代码或逻辑。它只是让它更难读懂和理解。
  • 混淆并不能阻止反向工程。它只会减缓这个过程。
  • 在大多数国家,你的知识产权都受到法律保护。因此,如果竞争对手使用了你的代码或特定实现,你可以起诉他。

混淆唯一能够解决的问题就是有人创建了一个与你的特定实现相同或接近相同的副本。

在理想的世界里,混淆应用程序的反向工程不经济实惠。

但回到现实:

  • 在这个星球上不存在任何工具可以阻止某人复制任何应用程序提供或产生的用户界面、行为或结果。在这种情况下,混淆是100%无用的。
  • 市场上最好的混淆器也不能阻止某人使用某种反汇编器或十六进制编辑器,对于一些极客来说,这非常方便地窥探应用程序的内部。它只是比未混淆的代码更难。

因此,现实情况是,你可以使窥探你的应用程序变得更加困难和耗时,但你不会真正获得可靠的保护。无论你使用免费还是商业产品。

像控制流混淆或代码虚拟化这样的高级技术可能有助于使逻辑理解变得非常困难,但它们也可能导致许多有趣且难以调试或解决的问题。因此,它们有时更像是一个额外的问题而不是解决方案。

在我看来,混淆不值得一些公司收取的费用。如果你想要纠缠休闲开发者,开源混淆器已经足够好了。如果你想尽可能地防止人们窥探你的应用程序,你需要使用带有虚拟执行环境和虚拟文件系统的加密容器,但它们也提供攻击向量,并可能成为一个充满问题的来源。

在大多数国家,你的知识产权和产品都受到法律保护。因此,如果有竞争对手分析和复制你的代码,你可以起诉他。如果一个坏人、黑客或破解者拿走了你的应用程序,你就受骗了——但混淆器并没有什么区别。

因此,您应该首先考虑您的目标、市场以及您想通过混淆器实现什么。正如您可以在这里(以及其他地方)阅读到的那样,混淆并不能真正解决反向工程的问题。它只会使其更加困难和耗时。但如果这是您想要的,您可以查看开源混淆器,例如sharpObfuscator或obfuscar,它们可能足以卡住休闲的编码人员(列表可在此处找到:维基百科上的.NET混淆器列表)。 如果在您的情况下有可能,您也可能对SaaS概念感兴趣。这意味着您提供对软件的访问权限,而不是软件本身。因此,客户通常无法访问您的程序集。但是,根据服务级别、安全性和用户基础,实现可靠、自信和高效的SaaS服务可能会很昂贵、复杂和困难。

4

我认为这取决于您的产品类型。如果它是面向开发人员使用的,则混淆将对您的客户造成伤害。我们在工作中一直在使用ArcGIS产品,而所有的DLL都被混淆了。这使得我们的工作变得更加困难,因为我们无法使用Reflector来解密奇怪的行为。而且我们正在购买那些为该产品支付数千美元的客户。

所以,除非确实必须,否则请不要进行混淆。


3

对于其他在未来几年阅读此文的人,我要提醒一句话——我几个小时前仅大致浏览了附带VS2008的Dotfuscator社区版许可证,我认为你不能使用该版本发布商业产品或混淆涉及除你之外的任何开发人员参与的项目的代码。因此,对于商业应用程序开发人员来说,这实际上只是一个试用版。


据我所知,根据http://www.preemptive.com/eula,此限制仅适用于评估期(高级版本?),而不适用社区版。 - David L

3

不,混淆已被证明不能防止某人能够解密编译后的代码。它使这样做更加困难,但并非不可能。


3

我曾成功地将一个免费的混淆器的输出放入另一个混淆器中。在 Dotfuscator CE 中,只包含了部分混淆技巧,因此使用另一个具有不同技巧的混淆器可以使它更加混淆。


2
这就像声称在RAR之后应用ZIP可以使存档变小一样。 - EFraim
3
不是这样的。在CE中有一些东西没有混淆,使用Reflector加载混淆的DLL会显示出未混淆的项目,可以清晰地阅读。使用第二个工具混淆后,这些项目被混淆了,在Reflector中没有任何可读性。 - harriyott
当你的应用程序崩溃时,享受调试客户端堆栈跟踪的乐趣。 - Matthew Whited
1
有一个映射文件被生成,因此(虽然繁琐),但仍然可以将它们匹配起来。 - harriyott
您也可以使用第三个和第四个混淆器。但这并不会改变事实。如果目标是保护知识产权或者想要使反向工程变得不可能,混淆几乎是无用的。在我看来,混淆只是毒酒。大多数应用程序都有用户界面。它们需要某种输入,并且可能会创建一些输出。用户可以以某种方式进行交互。在这种情况下,通常不需要进行反向工程。观察和思考很可能足以让熟练的开发人员创建一个“山寨”;-) - Axel

3

我非常擅长阅读x86汇编代码,那么对于从事汇编工作超过20年的人来说呢?

你总能找到一些人只需要一分钟就能看出你的c#或c代码在做什么...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接