27

当我启动 .NET exe 时会发生什么?我知道 C# 被编译为 IL 代码,我认为生成的 exe 文件只是一个启动器,它启动运行时并将 IL 代码传递给它。但是怎么做?它的过程有多复杂?

IL 代码嵌入在 exe 中。我认为它可以从内存中执行而无需将其写入磁盘,而普通的 exe 则不是(好的,是的,但它非常复杂)。

我的最终目标是提取 IL 代码并编写我自己的加密启动器,以防止脚本小子在 Reflector 中打开我的代码并轻松窃取我的所有课程。好吧,我不能完全阻止逆向工程。如果他们能够检查内存并捕捉到我将纯 IL 传递给运行时的时刻,那么它是否是 .net exe 并不重要,是吗?我知道有几个混淆器工具,但我不想弄乱 IL 代码本身。

编辑:所以似乎不值得尝试我想要的东西。他们无论如何都会破解它......所以我会寻找一个混淆工具。是的,我的朋友也说过,将所有符号重命名为无意义的名称就足够了。毕竟逆向工程不会那么容易。

4

7 回答 7

37

如果您绝对坚持加密您的程序集,那么最好的方法可能是将您的程序代码放入类库程序集中并对其进行加密。然后,您将编写一个小的存根可执行文件,它将程序集解密到内存中并执行它们。

这是一个非常糟糕的主意,原因有两个:

  1. 您将不得不在存根中包含加密密钥。如果 1337 黑客可以有意义地使用您反射的程序集,他可以很容易地窃取您的加密密钥并自己解密它们。(这基本上是模拟孔
  2. 没有人关心你的 1337 代码。对不起,那是艰难的爱。没有人认为任何人的代码几乎和作者一样有趣。
于 2010-02-26T00:05:44.780 回答
27

你与成千上万人分享的“秘密”并不是秘密。请记住,您的攻击者只需破坏您的微不足道即可破解,因为密钥就在那里“加密”方案恰好一次。

如果您的代码非常有价值,必须保密,那么请保密。仅将代码保留在您自己的服务器上;将您的软件编写为 Web 服务。然后保护服务器。

于 2010-02-26T05:19:56.007 回答
20

生成的 exe 文件只是一个启动器,它启动运行时并将 IL 代码传递给它。

不完全是。有不同的方法可以设置你的程序,但通常 IL 代码被编译为与运行时一起运行的本机机器代码。

至于孩子们——如果你认为你可以卖给他们或任何使用他们重新分配的东西的人,那你就是在自欺欺人。如果他们无法解锁您的应用程序,他们会继续前进并找到一个他们可以或没有的应用程序。它们正好代表 0 美元的潜在销售额;花太多精力试图阻止它们是没有意义的,因为您的投资不会有任何回报。一个基本的混淆器可能没问题,但不要超出这个范围。

实际上,与盗版相比,大多数开发人员面临的来自默默无闻的挑战要大得多。你所做的任何阻止你宣传你的产品的事情都比海盗对你的伤害更大。这包括让人们花钱来获得它。大多数情况下,更好的方法是拥有一个小孩子甚至不需要解锁的应用程序的免费版本。对他们来说已经足够好的东西,破解你的应用程序只会浪费他们的时间,而不仅仅是时间或功能有限的试用。让他们和尽可能多的其他人把它传播得更远更广。

现在我知道你最终确实需要一些付费客户。关键是现在利用你从免费产品中获得的所有注意力来追加销售或推广其他更有利可图的东西。这里的一种选择是还拥有一个高级版本,其中包含主要针对商业受众的附加功能;诸如使其易于部署到整个网络并以这种方式进行管理之类的事情。企业财力雄厚,更有可能支付您的许可费。然后,您的免费版本将用于推广您的产品并为您的企业客户提供合法性。

当然,还有其他模型,但无论您做什么,都值得记住,默默无闻是更大的挑战,您的软件的盗版副本永远不会转化为销售。最终(当然这取决于你的执行力)你将能够通过利用这些点的商业模式赚更多的钱,而不是你试图与它们作斗争。

于 2010-02-26T00:01:30.373 回答
6

“...防止脚本小子在 Reflector 中打开我的代码并轻松窃取我所有的课程。”

不幸的是,无论您如何掩盖启动,调试器中的六个命令都可以将当前运行的程序集转储到用户选择的文件中。因此,即使您可以按照 Brian 的建议启动应用程序,一旦该应用程序运行,将其组件放入 Reflector 并不难(如果有人觉得有趣,我可以从 WinDbg 发布一个示例)。

混淆工具是根据大量技术经验创建的,通常旨在使调试器难以可靠地附加到进程或从中提取信息。正如布赖恩所说:我不确定你为什么决心保留 IL,如果你想要任何有意义的保护免受脚本小子的影响,那么你可能必须改变主意。

于 2010-02-25T23:47:03.947 回答
6

“他们复制了他们能效仿的一切,但他们无法复制我的想法,所以我让他们流汗和偷窃一年半。” ——R.吉卜林

于 2010-04-19T23:49:37.937 回答
3

我个人认为混淆是要走的路。它很简单而且很有效,特别是如果您的所有代码都在一个 exe 中(我不确定“弄乱 IL”有什么顾虑)。

但是,如果您觉得这对您不起作用,也许您可​​以加密您的 exe 并将其作为资源嵌入到您的启动器中。处理它的最简单方法是解密 exe 资源并将其写入文件并执行它。exe完成执行后,删除该文件。您也可以通过 Emit 函数运行它。我不知道这将如何工作,但这里有一篇文章可以帮助您入门 - Using Reflection Emit to Cache .NET Assemblies

当然,您的解密密钥可能也必须嵌入到 exe 中,因此真正确定的人无论如何都能够解密您的程序集。这就是为什么混淆可能是最好的方法。

于 2010-02-25T23:21:27.227 回答
2

从这个问题中复制我的答案(不完全重复,但可以用相同的答案回答,因此是 CW):

一个 Windows EXE 包含多个“部分”。简而言之,.net 代码 (=MSIL) 只是 EXE 的一部分,并且在 EXE 中还有一个“真正的”本机 Windows 部件,用作 .net 框架的某种启动器,然后执行 MSIL。

Mono 将只获取 MSIL 并执行它,而忽略本机 Windows 启动器的内容。

同样,这是一个简化的概述。

编辑:我担心我对深度 depp 细节的理解不足以提供很多细节(我大致知道 PE Header 是什么,但不是真正的细节),但我发现这些链接很有帮助:

NET 程序集结构——第二部分

.NET Foundations - .NET 程序集结构

附录:如果您真的想更深入,请在Advanced .net Debugging上获取一份副本。第一章准确地解释了在 Windows XP 之前和之后如何加载 .net 程序集(从 XP 开始,Windows 加载器是 .net 感知的,这从根本上改变了 .net 应用程序的启动方式)

于 2010-02-26T07:07:07.117 回答