Archive for 5月 22nd, 2012

  1. Hello, COM(MSIL) World!

    Posted on 5月 22nd, 2012 by cx20

    MSIL

    COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
    COM を用いて開発された部品であれば言語を問わず利用することができる。
    以下は MSIL による COM クライアントの例となっている。

    ソースコード

     
    //  Microsoft (R) .NET Framework IL Disassembler.  Version 4.0.30319.1
    //  Copyright (c) Microsoft Corporation. All rights reserved.
     
     
    // Metadata version: v2.0.50727
    .assembly extern mscorlib
    {
      .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .zV.4..
      .ver 2:0:0:0
    }
    .assembly extern Shell32
    {
      .ver 1:0:0:0
    }
    .assembly Hello
    {
      .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
      .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                                 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
      .hash algorithm 0x00008004
      .ver 0:0:0:0
    }
    .module Hello.exe
    // MVID: {558CDDD7-4AF4-48D6-A830-0DA2C5C15D19}
    .imagebase 0x00400000
    .file alignment 0x00000200
    .stackreserve 0x00100000
    .subsystem 0x0003       // WINDOWS_CUI
    .corflags 0x00000001    //  ILONLY
    // Image base: 0x01D10000
     
     
    // =============== CLASS MEMBERS DECLARATION ===================
     
    .class private auto ansi beforefieldinit Hello
           extends [mscorlib]System.Object
    {
      .method private hidebysig static void  Main(string[] args) cil managed
      {
        .entrypoint
        // コード サイズ       56 (0x38)
        .maxstack  5
        .locals init (class [Shell32]Shell32.Shell V_0,
                 class [Shell32]Shell32.Folder V_1,
                 object V_2,
                 bool V_3)
        IL_0000:  nop
        IL_0001:  newobj     instance void [Shell32]Shell32.ShellClass::.ctor()
        IL_0006:  stloc.0
        IL_0007:  ldc.i4.s   36
        IL_0009:  conv.i8
        IL_000a:  box        [mscorlib]System.Int64
        IL_000f:  stloc.2
        IL_0010:  ldloc.0
        IL_0011:  ldc.i4.0
        IL_0012:  ldstr      "Hello, COM(MSIL) World!"
        IL_0017:  ldc.i4.0
        IL_0018:  ldloc.2
        IL_0019:  callvirt   instance class [Shell32]Shell32.Folder [Shell32]Shell32.IShellDispatch5::BrowseForFolder(int32,
                                                                                                                      string,
                                                                                                                      int32,
                                                                                                                      object)
        IL_001e:  stloc.1
        IL_001f:  ldloc.1
        IL_0020:  ldnull
        IL_0021:  ceq
        IL_0023:  stloc.3
        IL_0024:  ldloc.3
        IL_0025:  brtrue.s   IL_0030
     
        IL_0027:  nop
        IL_0028:  ldloc.1
        IL_0029:  call       int32 [mscorlib]System.Runtime.InteropServices.Marshal::ReleaseComObject(object)
        IL_002e:  pop
        IL_002f:  nop
        IL_0030:  ldloc.0
        IL_0031:  call       int32 [mscorlib]System.Runtime.InteropServices.Marshal::ReleaseComObject(object)
        IL_0036:  pop
        IL_0037:  ret
      } // end of method Hello::Main
     
      .method public hidebysig specialname rtspecialname 
              instance void  .ctor() cil managed
      {
        // コード サイズ       7 (0x7)
        .maxstack  8
        IL_0000:  ldarg.0
        IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
        IL_0006:  ret
      } // end of method Hello::.ctor
     
    } // end of class Hello
     
     
    // =============================================================
     
    // *********** 逆アセンブルが完了しました ***********************
    // 警告: Win32 リソース ファイル Hello.res を作成しました。

    上記コードは、以下の C# の実行ファイルを ildadm.exe で逆アセンブルしたものである。

    ソースコード

    using System;
    using System.Runtime.InteropServices;
    using Shell32;
     
    class Hello
    {
        static void Main(string[] args)
        {
            Shell shell = new Shell();
            Folder folder;
            object vRootFolder = (long)ShellSpecialFolderConstants.ssfWINDOWS;
            folder = shell.BrowseForFolder(0, "Hello, COM(MSIL) World!", 0, vRootFolder);
            if (folder != null)
            {
                Marshal.ReleaseComObject(folder);
            }
            Marshal.ReleaseComObject(shell);
        }
    }

    コンパイル&実行方法(.NET Framework)

    C:¥> ilasm Hello.il
    C:¥> Hello

    実行結果

    +----------------------------------------+
    |Browse For Folder                    [X]|
    +----------------------------------------+
    | Hello, COM(MSIL) Wolrd!                |
    |                                        |
    | +------------------------------------+ |
    | |[Windows]                           | |
    | | +[addins]                          | |
    | | +[AppCompat]                       | |
    | | +[AppPatch]                        | |
    | | +[assembly]                        | |
    | |     :                              | |
    | |     :                              | |
    | |     :                              | |
    | +------------------------------------+ |
    | [Make New Folder]    [  OK  ] [Cancel] |
    +----------------------------------------+