zoukankan      html  css  js  c++  java
  • MSIL探索IL介绍

    MSIL探索-IL介绍

    by  zguosir/gshzheng

     

    1.

    我们用C#,Vb.Net,Asp.Net或其它的与.Net兼容的语言写的代码最终都会编译成IL。如,我们用Cobol写的程序,可以在C#中修改,然后在Asp.Net中使用。因此,理解IL是我们理解.Net相关技术的最好的方式。

     

    假设您已经至少熟悉一种.Net语言,让我们一步一步揭开IL的面纱,

    a1.il

    .assembly zzz{}

    .method static void mymethod()

    {

    .entrypoint

    ldstr “Hello”

    call void [mscorlib]System.Console::WriteLine(string)

    ret

    }

     

    Output

    hello

    这是比较简单的IL程序,必须指定伪指令.assembly .entrypoint,以及ret函数结束指令。(注,译者还很老土,用的环境Net1.1Net2.0会很不一样,但我们没必要在版本上做更多的计较)

     

    .开始的语句,我们称之伪指令(derective,如创建一类或方法的指令;

    不以.开始的语句,是真正的汇编指令。

     

    IL中,首先被执行的第一个函数为入口函数(entrypoint function,一个程序只能有一个入口函数,.entrypoint是伪指令,它的位置可以放在函数开始处,也可以放在函数的结束处。

     

    ret指令表示函数代码的结束,不能省略。

     

    call语句是函数调用指令,指令的调用有如下的细节

    l           返回值(void

    l           引用的外部装配件([mscorlib]

    l           命名空间(System

    l           类(Console

    l           方法名称(WriteLine

    l           方法参数类型(string

     

    2.

    下面是一个稍微复杂一点IL程序,其中引入了类的定义

    a2.il

    .assembly zzz{}

    .class private auto ansi zzz extends [mscorlib]System.Object

    {

    .method public hidebysig static void mymethod() il managed

    {

    .entrypoint

    ldstr "Hello"

    call void [mscorlib]System.Console::WriteLine(string)

    ret

    }

    }

     

     

    OutPut

    Hello

     

    伪指令.class定义了一个类,并且有三个修饰词

    l           private: 表示对类的程序的访问只能限制在当前类内部。

    l           auto: 表示类在内存中的存储只有在运行时才能决定。

    l           ansi: 原代码可以被分割为两部分,受控的和非受控的。

    l           il managed: 暂不说明。

     

    伪指令.method的修饰词

    l           public: 方法的访问级别。

    l           hidebysig: 此属性让父类的这个方法对派生类来说是隐藏的。

    l           static: 静态的方法是属于类而不是属于对象的。标记为entrypoint的方法首先是static的。

     

    3.

    下面一个再复杂一点的程序,填加了更多的伪指令,还有类的构造函数的写法

    a3.il

    .module a3.exe

    .subsystem 3

    .corflags 1

    .assembly extern mscorlib

    {

      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..

      .ver 1:0:5000:0

    }

    .assembly a3

    {

        .hash algorithm 0x00008004

        .ver 0:0:0:0

    }

    .class private auto ansi zzz extends [mscorlib]System.Object

    {

    .method public hidebysig static void mymethod() il managed

    {

    .entrypoint

    ldstr "Hello"

    call void [mscorlib]System.Console::WriteLine(class [mscorlib]System.String)

    ret

    }

     

    .method public hidebysig specialname rtspecialname instance void .ctor() il managed

    {

    .maxstack 8

    ldstr "Hello1"

    call void [mscorlib]System.Console::WriteLine(class [mscorlib]System.String)

    ldarg.0

    call instance void [mscorlib]System.Object::.ctor()

    ret

    }

    }

     

    Output

    Hello

     

    .ctor: ctor就是constructor

     

    rtspecialname: 这个属性告诉运行时(runtime)当前函数有个特殊的名字,应该进行某些特殊的对待。

     

    Specialname: 这是通知编译器,当前函数是特殊的,RT可能忽略这个属性。

     

    Instance: 指明函数调用是一个相对于实例的调用。

     

    ldarg.0 一般是取的在执行堆栈上的this指针或第0个参数的地址(对于静态方法)。

     

    .maxstack:指定当方法被执行时,在stack上的最大元素数

     

    .module:所有的IL文件必须是某个module的一部分,这里module的名字未必与exe的名字相同。

     

    .subsystem: 这个伪指令用来指定程序将要在哪个OS上运行,它也是指定运行程序类型的一种方式。下面是值的含义:

           2- Windows 控制台程序

           3- WinForm程序

           5- OS/2

     

    .corflags: 1表示可执行程序,4表示类库

     

    .assembly 我们创建的所有东西都是manifest的一部分,assembly伪指令是manifest的开始指令,manifest包括module,一个module只能包含一个assembly伪指令。如果exe程序,assembly只必须有的,而对于dll类库来说,它是可以缺省的。在assembly伪指令中,包含着其它的伪指令。

    .hash: 指明assemblyhash代码。

    .ver:  指明assembly的版本表示,它有4部分组成,有冒号分割,依次分别表示主版本号、次版本号、内建build号,修正号。

     

    extern:如果需要引用其它的assemblies,就需要用到extern伪指令。

    originator:这个伪指令揭示了dll创建着的唯一标识,它是创建者公钥(public key)的8位数字,显然是个hash code

     

    4.

    现在,我们把一个最简单的c#程序,反编译成il后,再来看程序,就貌似不怎么陌生了。

     

    a4.cs

    public class a4

    {

        public static void Main()

        {

            System.Console.WriteLine("Hello"); 

        }  

    }

     

    >csc a4.cs

    >ildasm a4.exe /out=a4.il

     

     

    a4.il

    //  Microsoft (R) .NET Framework IL Disassembler.  Version 1.1.4322.573

    //  Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

     

    .assembly extern mscorlib

    {

      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..

      .ver 1:0:5000:0

    }

    .assembly a4

    {

      // --- 下列自定义属性会自动添加,不要取消注释 -------

      //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(bool,

      //                                                                                bool) = ( 01 00 00 01 00 00 )

      .hash algorithm 0x00008004

      .ver 0:0:0:0

    }

    .module a4.exe

    // MVID: {6E8E5294-3C87-4895-BA7E-F4BDF4FEAC50}

    .imagebase 0x00400000

    .subsystem 0x00000003

    .file alignment 512

    .corflags 0x00000001

    // Image base: 0x00da0000

    //

    // ============== CLASS STRUCTURE DECLARATION ==================

    //

    .class public auto ansi beforefieldinit a4

           extends [mscorlib]System.Object

    {

    } // end of class a4

     

     

    // =============================================================

     

     

    // =============== GLOBAL FIELDS AND METHODS ===================

     

     

    // =============================================================

     

     

    // =============== CLASS MEMBERS DECLARATION ===================

    //   note that class flags, 'extends' and 'implements' clauses

    //          are provided here for information only

     

    .class public auto ansi beforefieldinit a4

           extends [mscorlib]System.Object

    {

      .method public hidebysig static void  Main() cil managed

      {

        .entrypoint

        // 代码大小       11 (0xb)

        .maxstack  1

        IL_0000:  ldstr      "Hello"

        IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)

        IL_000a:  ret

      } // end of method a4::Main

     

      .method public hidebysig specialname rtspecialname

              instance void  .ctor() cil managed

      {

        // 代码大小       7 (0x7)

        .maxstack  1

        IL_0000:  ldarg.0

        IL_0001:  call       instance void [mscorlib]System.Object::.ctor()

        IL_0006:  ret

      } // end of method a4::.ctor

     

    } // end of class a4

     

     

    // =============================================================

     

    //*********** 反汇编完成 ***********************

    // WARNING: Created Win32 resource file a4.res

     

     

  • 相关阅读:
    Vue实战笔记
    项目随笔
    Vuex数据可视化
    Vue项目中,要保证某个部分的高度,应该怎么设置
    (转)http authorization 基本认证
    多页应用和单页应用
    Vue项目中使用webpack配置了别名,引入的时候报错
    [转载]解决在win10中webstrom无法使用命令行(Terminal)
    (转)巧用可视区域
    前端管理后台集成解决方案---vue-element-admin
  • 原文地址:https://www.cnblogs.com/zguosir/p/904427.html
Copyright © 2011-2022 走看看