【问题标题】:Do method names get compiled into the EXE?方法名称会编译到 EXE 中吗?
【发布时间】:2009-01-05 14:47:12
【问题描述】:

将 Windows 应用项目编译为 EXE 后,类、方法和变量名称是否包含在 MSIL 中?

  • 对于混淆 - 名称越少,逆向工程就越难。
  • 为了性能 - 更短的名称,更快的访问。

例如所以如果方法是通过名称调用的:

  • 保持名称简短,命名查找的性能更好。
  • 保持名称神秘,更难反编译。

【问题讨论】:

    标签: c# methods performance obfuscation cil


    【解决方案1】:

    是的,他们在 IL - 启动 Reflector,你会看到他们。如果它们最终没有出现在 IL 中,那么您就无法将它们作为库来构建。 (是的,您可以像引用类库一样引用 .exe 文件。)

    但是,这一切都在 JIT 中解决了一次。

    保持名称可读,以便您将来能够维护代码。性能问题不太可能造成任何可衡量的差异,如果你想混淆你的代码,不要在源代码级别(你是一个人阅读代码)- 使用专门构建的混淆器。

    编辑:至于包含的内容 - 为什么不启动 Reflector 或 ildasm 并找出答案?从内存中,您会丢失局部变量名称(如果您构建它,则在 pdb 文件中)但仅此而已。私有方法名和私有变量名还在。

    【讨论】:

    • JIT 编译?! JavaScript 不就是这样执行的吗?这不是最坏的情况吗,因为您有所有成员名称可供逆向工程师使用+
    • 如果你真的对 .NET 使用 JIT 编译感到惊讶,我建议你在使用 C# 之前阅读更多关于 .NET 的内容。是的,你可以对代码进行逆向工程——你可以用任何语言(理论上)这样做。您还可以对代码进行混淆处理,因此并非所有 .NET 代码实际上都是开源的。
    • 虚拟方法表最初只填充了指向 JIT 编译器本身的指针,直到运行时首先调用该方法,然后 JIT 编译器确定方法代码在哪里,并将调用替换为JIT 与实际代码的偏移量。这可能因每台机器而异。
    • ...(续)在 Don Box 的“Essential .Net”一书中对所有这些工作原理进行了很好的解释...
    • 或者在 Jeffrey Richter 的“CLR via C#”中也很出色。
    【解决方案2】:

    是的,他们有。我认为使用较短的名称不会有显着的性能提升。收益无法弥补可读性的损失。

    【讨论】:

    • 私人成员名称是否也包含在内?
    【解决方案3】:

    MSIL 中不包含局部变量。字段,方法,类等。 变量是基于索引的。

    【讨论】:

    • 就像 Jon Skeet 所说,“从记忆中,你失去了局部变量名......私有变量名仍然存在。”
    【解决方案4】:

    无论是私有的还是公共的,成员名称都会包含在 IL 中。事实上,您的所有代码也都包含在内,如果您使用 Reflector,您实际上可以阅读应用程序的所有源代码。剩下的就是调试应用了,我认为可能有工具可以解决这个问题。

    如果您正在制作具有大量客户和竞争对手的打包应用程序,您必须绝对(我不能再强调)混淆您的代码。幸运的是,有许多混淆器可用。

    这是我对 .Net 的主要抱怨。既然 MS 在这方面做了很多艰苦的工作,为什么不开发(或获得)一个专业的混淆器并将其作为 VS 的一部分。 Dotfuscator 只是没有削减它,而不是他们为社区提供的版本。

    【讨论】:

    • 首先确定您的威胁模型:您希望人们如何处理您不希望他们使用的未混淆代码?虽然很高兴相信你有一些每个人都想逆向工程的超级棒的代码,但实际上没有人这样做。如果您这样做,则不应将其发送给您的客户。
    【解决方案5】:
    • 保持名称简短,更好 命名查找的性能。

    这有什么不同?我不确定 VM 是如何查找标识符的,但我很确定它没有进行直接的字符串比较查找。这将是最糟糕的方法。

    • 保持名称神秘,更难反编译。

    说实话,我不认为代码混淆有多大帮助。大多数有能力的开发人员已经开发出一种“第六感”来快速解决问题,即使像方法名称这样的标识符完全没有帮助,因为他们需要维护或改进的源代码通常已经存在这些问题(我说的是方法名称像“DoAllStuff()”)。

    无论如何,通过默默无闻来确保安全通常是个坏主意

    【讨论】:

    • 使用 .NET Reflector 任何一年级 CS 学生都可以找出您的代码。不混淆等同于将您的应用程序作为开源发布。开源对于许多商业应用程序来说并不实用。要么混淆,要么多做半步,让你的应用开源。
    • mhenry1384:无论您如何混淆您的可执行文件,任何有能力的程序员都可以轻松搞定。您可以在运行时生成代码,这会提高一点,但不会太多。就像大多数受版权保护的游戏在发布后几天就会被破解一样。
    • 不,我不认为混淆是不值得的。
    • mhenry1384:不,不是,因为它没有许可作为开源。仅仅因为您的用户可以根据需要阅读(反编译的)代码,并不意味着他们可以合法地用它做任何事情。 .NET 和本机代码之间的唯一区别是反编译的难度。
    【解决方案6】:

    如果您担心混淆,请查看 .NET Reactor。我测试了 8 种不同的混淆器,Reactor 不仅是最便宜的商业混淆器,而且是同类产品中第二好的(最好的是最昂贵的,Dotfuscator Gold)。

    [编辑]

    实际上现在我想起来了,如果你关心的只是混淆方法名称,那么 VS.NET 附带的 Dotfuscator 社区版应该可以正常工作。

    【讨论】:

      【解决方案7】:

      我认为它们已添加,但名称的长度不会影响任何事情,因为查找函数名称的方式。至于混淆,我认为有一些工具(Dotfuscator 或类似的东西)基本上可以完全按照您的意思行事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-12
        • 2011-02-20
        • 2015-04-17
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多