代码之家  ›  专栏  ›  技术社区  ›  caesay

Salamander.net链接器-它是如何工作的?

  •  1
  • caesay  · 技术社区  · 14 年前

    我想了解一下蝾螈是怎么做的? 我将包括一些我特别感兴趣的要点

    -

    按需链接

    链接器从入口方法(您可以配置)开始,递归地遍历调用图以仅链接所需的MSIL代码位。未使用的代码将不会链接到最终程序集中。因此,您的代码会变得更高效,文件大小也会变小。

    -

    链接到框架API

    链接器非常强大,甚至Microsoft.NET框架程序集(如System.Windows.Forms.dll)也可以链接到您自己的.NET程序集。因为它按需链接,所以只链接所需的部分。这对于通过调试框架代码本身来保护代码、简单的应用程序部署和解决问题非常有用。

    -

    土生土长

    本机编译器将所有托管程序集(包括系统程序集)转换为x86本机代码。不会发出msil指令,也不会在运行时编译jit。这提供了最好的防止反汇编和反编译的保护,还提高了性能和启动时间。

    -

    无需完全安装Microsoft.NET Framework,即可实现简单快速的部署

    迷你部署工具将最小的一组clr运行时文件和依赖程序集放在一起,这些文件和依赖程序集可以简单地复制到目标计算机上的一个文件夹中,并且您的应用程序就像安装了整个框架一样运行。由于安装被隔离到单个文件夹中,因此不会与将来的.NET安装发生冲突。当链接用于依赖程序集时,它将进一步减小文件大小。

    -

    代码保护 有一个问题:当前的模糊处理程序地址都没有,即,无论模糊处理有多好,代码中都有分散的系统库调用和其他外部引用(请参见下面的红色部分)。由于这些调用是外部引用,因此模糊处理程序必须保持不变。然而,这些引用有助于理解反编译代码,因为它们是文档化的和公共的API。链接器通过将框架API链接到您自己的代码中来删除或减少此类公共API,从而使您的代码在模糊后更难反编译。下面显示了使用链接器前后的示例MSIL代码。

    before:(由于以下代码是外部公共API,因此没有模糊器能够重命名它们)

    IL_0000:  ldarg.0
    IL_0001:  call       instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
    IL_0006:  ldarg.0
    IL_0007:  newobj     instance void  [System.Windows.Forms]System.Windows.Forms.TextBox::.ctor()
    IL_000c:  stfld      class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::A
    IL_0011:  ldarg.0
    IL_0012:  ldfld      class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::A
    IL_0017:  call       valuetype  [System.Drawing]System.Drawing.Color [System.Drawing]System.Drawing.Color::get_Cyan()
    IL_001c:  callvirt   instance void  [System.Windows.Forms]System.Windows.Forms.TextBoxBase::set_BackColor(valuetype [System.Drawing]System.Drawing.Color)
    IL_0021:  ldarg.0
    

    之后:(绝对没有线索窗口。使用表单API,这是黑客理解这一点的一大障碍 垃圾)

    IL_0000:  ldarg.0
    IL_0001:  call       instance void a.A::.ctor()
    IL_0006:  ldarg.0
    IL_0007:  newobj     instance void  D.c::.ctor()
    IL_000c:  stfld      class D.c A.A::A
    IL_0011:  ldarg.0
    IL_0012:  ldfld      class f.aA.A::A 
    IL_0017:  call  valuetype        a.B()
    IL_001c:  callvirt  instance   void  D.c(valuetype g.e)
    IL_0021:  ldarg.0  
    

    有些事情让我困惑,我想知道是否还有其他人知道这一切是如何运作的?

    1 回复  |  直到 11 年前
        1
  •  1
  •   jyoung    14 年前

    土生土长, 没有完整的Microsoft.NET Framework安装,部署简单快速, 代码保护:

    他们正在将“yourapp”+“.netframework”编译为本机dll。它没有IL,也没有符号,所以逆向工程要困难得多。

    按需链接, 链接到框架API:

    为了使.dll保持合理的大小,它们必须从dll中去掉死代码(永远不会调用的代码)。为了做到这一点,他们从根目录(通常是main())遍历调用树,并且只包含这些方法。通过反射调用代码可能有问题,所以我猜它们允许超过1个根。