7

正如在此处此处的类似问题中所讨论的,我想保护我的代码免受逆向工程的影响。

我的情况就像Simucal在他的(优秀)回答中所描述的那样

基本上,归根结底,您成为源盗窃目标的唯一机会是,如果您有一些与您的域相关的非常具体、难以设计的算法,可以让您在竞争中占得先机。这几乎是唯一一次尝试对应用程序的一小部分进行逆向工程具有成本效益。

我正好有这种情况。一种难以设计的算法,它对我们的特定领域来说既优雅又有价值。

经过几个月的微调和开发,最终结果非常紧凑(大约 100 行代码)且优雅。我想保护代码的这个特定部分免受逆向工程的影响,或者至少让它变得合理困难。

该场景是一个用 C# 编写的富客户端应用程序,我必须部署这部分代码 - 我无法从 Web 服务执行它。

我认为由于性能原因(和跨界问题),提取代码并将其重写为非托管本机二进制文件不是一种选择。

最初我想做简单的混淆,但考虑到代码的体积很小,我认为这不会提供太多保护。

理想情况下,我想保护我的整个应用程序,但有两个主要问题似乎使普通混淆器和 3rd 方打包器难以使用:

  1. 应用程序提供了一个插件接口,因此一些程序集(和接口/类)不应该被混淆和打包

  2. 我们仍然希望在收到错误报告时能够获得真正的堆栈跟踪——这可能是通过我将混淆映射到真实代码来完成的。

撇开这些问题不谈(尽管我也希望对此有任何意见),什么是保护我的一小部分代码免受逆向工程的好方法?我不关心任何人更改或破解代码,但希望使其难以理解和逆向工程。

4

8 回答 8

4

这是不可能的。如果你的代码可以运行,那么它就可以被阅读和逆向工程。你所能做的就是让它变得更难一点,相信我,它只会更难一点。你可能不喜欢这个事实,但大多数饼干在破解方面比其他任何人都更擅长让事情变得难以破解。保护您的代码所付出的努力通常是不值得的,特别是如果它不利于您的付费客户。见证 DRM 的惊人失败。

我的建议是不要担心。如果您的算法真的很新颖,请寻求专利(尽管 Bilski 的决定会变得有点困难,除非您将其与特定的硬件实现联系起来)。依靠商业秘密也是没有用的,除非您只将您的软件分发给那些签署合同以确保他们不会允许不受限制的访问的人。然后,你必须有办法对此进行监管。一旦您将二进制文件放到互联网上或在没有合同的情况下分发它们,我相信您将被视为失去商业机密状态。

依赖许可也充满危险——您可能认为您可以在您的许可中插入禁止逆向工程的条款,但世界各地的许多司法管辖区都明确禁止这些条款。无论如何,负责大部分破解的俄罗斯暴徒不太可能遵守上述规定。

您为什么不专注于让您的产品做到最好呢?目标是保持领先于人群,而不是完全将他们拒之门外。在竞争激烈的群体中率先交付并始终拥有最好的产品将确保您的繁荣远胜于将大量精力浪费在无用的保护 (IMNSHO) 上。

这只是我的看法。我可能错了。我以前错了,你只需要问我妻子:-)

于 2009-02-25T07:02:15.790 回答
3

除了混淆之外,它几乎毫无价值,甚至微软(ScottGu等)基本上都说具有适当意图和能力的人会对应用程序进行逆向工程,而在 .NET 中,基本防御是许可和 IP,而不是试图通过保护您的代码默默无闻或其他一些防止逆向工程的方法。

这就是为什么他们发布 BCL 源而不是保密的部分原因。

于 2009-02-25T05:43:21.750 回答
3

你应该混淆完整的代码,因为它更难到达那个有价值的小部分。代码越小,就越容易理解。大多数混淆器不应该与公共接口混淆,因为那里有许多混淆库。

但是我认为你应该让用户相信那里没有特殊的技巧,而不是试图隐藏它。引用 Kaiser Soze 的话,“魔鬼曾经使用过的最大伎俩就是让世界相信他不存在”。

当然,您可以随时为您的发明申请专利并合法保护自己。

于 2009-02-25T05:47:12.520 回答
2

一种选择是使用许可证密钥和/或硬件指纹在运行时解密敏感代码并将其作为 IL 发出;这将使其对静态逆向工程工具(例如反射器)不可见

还检测调试器的存在并拒绝在调试模式下运行,除非在非常有限的情况下(即在您的机器上)

请注意,这将使您的调试变得非常困难,而对其他人来说几乎是不可能的(如果这是一个最终用户应用程序,这不是问题,但如果它是一个库或框架供其他开发人员构建,那就是一个问题)

另请注意,将物理内存复制到磁盘并在内存转储上使用脱机工具将揭示您的解密算法,因此它很容易被击败 - 但比大多数人会烦恼的麻烦要多得多

整个事情是在您的困难与对少数坏苹果的威慑与因盗窃/抄袭造成的潜在损失之间进行权衡

祝你好运,让我们知道你的决定!

于 2009-02-25T05:53:55.437 回答
2

如果你的代码那么敏感,就把它放在没人能拿到的地方。

EG 提供客户端或网页供人们访问某些公开您的功能的服务。

该服务可以位于外部防火墙后面,并与运行敏感代码的内部防火墙后面的后端服务器通信。

为了采取额外措施,请混淆该代码。

这将需要在访问您的代码之前损害几层安全性。

于 2009-02-25T06:32:46.373 回答
1

您可以在 C# 或 CIL 级别对其进行混淆,但真正无法做到的是 IL 编译器旨在创建可以实际执行的最有效的机器代码。

因此,要对您的算法进行逆向工程,请获取机器代码并在其上运行标准反汇编工具。通过从标准输入 API 调用到标准输出 API 调用,跟踪系统中的数据。

面对它,如果有人想要它,他们可以拥有它。

可以让它很难随便弄清楚。例如,我想查看某个由 Java 应用程序管理的数据库中的内容。事实证明,Java 反编译真的很混乱,充满了奇怪的函数、类和名称空间,它们都同名,故意试图隐藏真正发生的事情。

我本可以修复我正在使用的反编译器,以便将所有内容重命名为 A_namespace 而不仅仅是 A,然后函数流将直接弹出到 Eclipse 调用跟踪图中。

相反,我只是举起双手继续实际工作,而不是重写反编译器。

所以,你当然可以把它隐藏起来,不让那些随便感兴趣的人看到。

于 2009-02-25T06:03:16.100 回答
0

大多数混淆器允许您指定要防止混淆的方法/类。例如, SmartAssembly允许您使用属性标记方法或类,而其他允许您选择 UI 中的方法以从流程中排除。你应该能够对过程进行非常精细的控制,这样你就可以吃蛋糕了。

但是,如果您使用反射,您会遇到问题。

于 2009-02-25T06:48:25.493 回答
-2

我听说过关于Spices.Net Obfuscator的好评。它应该能够大大增加获得算法所需的时间。

于 2009-02-25T05:52:41.837 回答