解説

インサイド .NET Framework [改訂版]

第5回 アセンブリのロードとセキュリティ

吉松 史彰
2003/07/30
Page1 Page2 Page3 Page4

厳密名の検証

 mscorwks.dllが呼び出されると、CLR環境が動作を開始する。CLRはまずロードされたEXE/DLLのメタデータ(マニフェスト)を読んで、これがアセンブリのプライマリ・モジュール(マニフェストが含まれているモジュール)であることを確認する。プライマリ・モジュールではなかった場合は、そこで例外が発生して、処理は終了する。

 次に、CLRはこのアセンブリに電子署名が施されているかどうかを確認する。厳密名付きアセンブリだった場合は、まず署名の検証を行わなくてはならない。そのために、CLRはmscoree.dllのStrongNameSignatureVerification関数を呼び出す。mscoree.dllはmscorsn.dllのStrongNameSignatureVerification関数を呼び出して、公開キーを使った署名の検証を行う。検証に失敗した場合は、ファイルに改ざんがあったものと見なして、例外を発生させて処理を中止する。ここがCLRのセキュリティ機能の第1チェック・ポイントになる。アセンブリに署名して改ざんを防止することで、ウイルス感染などによる不正なプログラムの実行を防げるようになる。

.NETアプリケーション実行時の流れ

プログラムの開始

 署名の検証が終わると、CLRはロードされているプログラム(この場合はuser.exe)からエントリ・ポイントを探す。同じエントリ・ポイントという名前ではあっても、ここで探されるエントリ・ポイントは「マネージ・コードのエントリ・ポイント」だ。このエントリ・ポイントは、PEファイルの拡張部分に書き込まれているCLRヘッダに設定されている。CLRヘッダは、先ほどのdumpbin.exeを次のように実行すれば見ることができる。なおCLRヘッダの構造は、.NET Framework SDKに付属しているCorHdr.hファイルに定義されている(IMAGE_COR20_HEADER構造体)。

% dumpbin.exe /clrheader user.exe

dumpbin.exe /clrheaderの実行結果画面

 出力されたデータの中ほどに「6000001 entry point token」というエントリがある。これがマネージ・コードのエントリ・ポイントを表している。マネージ・コードには必ずそれに対応するメタデータがある。6000001というのは、マネージ・コードのエントリ・ポイントについての情報が書いてあるメタデータ・テーブルのキーを表すトークンである。頭の60という値をCorHdr.hファイルで検索してみると、CorTokenTypeというenum(列挙)の中に次のような定義があることが確認できる。

typedef enum CorTokenType
{
  ...
  mdtMethodDef            = 0x06000000,       //
  ...
}
CorHdr.hファイル内のCorTokenType列挙体にあるメソッド定義テーブルの定義(抜粋)

 つまり6000001という数値は、「メタデータ中のメソッド定義テーブルの1番目のレコード」を表している。メタデータをたどってこのレコードを探し出せば、C#やVisual Basic .NETにおけるMainメソッドの定義が取り出せるというわけだ。この検索結果は、この連載で最初からお世話になっているildasm.exeで見ることができる。

ildasm.exeで表示したMainメソッドのメソッド定義テーブル部分
表示方法については「第3回 アセンブリのロード」の「アセンブリのロード 1〜2段階」を参照

 メソッド定義テーブルの中には、RVAという名前の付いているエントリがある。RVA(Relative Virtual Address)とは、PE形式においてメモリ上にロードされたときのアドレスを相対的に表したものである。つまり、この場合はuser.exeファイルの中の0x00402050アドレスに当たる部分に、Mainメソッドの実体が格納されていることを意味している。先ほど出てきたdumpbin.exe /headersの結果をもう1度見ると、このアドレスはファイル上では0x00000250バイト目ということになる。ここは次のような内容になっている。

13 30 01 00 12 00 00 00 01 00 00 11 73 02 00 00
0A 0A 06 6F 03 00 00 0A 28 04 00 00 0A 2A 00 00

 最初の12バイトはメソッド・ヘッダと呼ばれる情報である。ildasm.exeでMainメソッドの中身を出力してみると、「.entrypoint」「// Code size 18 (0x12)」「.maxstack 1」「.locals init (class [.module util.netmodule]Util V_0)」という情報が表示されるが、これらの情報がこの12バイトの中に収められている。

 13バイト目からがILコードである。このILコードを少し読みやすくすると次のようになる。

73 0x0A000002
0A
06
6F 0x0A000003
28 0x0A000004
2A

 これをILアセンブラ言語に直すと次のようなコードになる。

newobj 0x0A000002
stloc.0
ldloc.0
callvirt 0x0A000003
call 0x0A000004
ret

 ildasm.exeで表示したMainメソッドの中身(下図)と一致するのが分かるだろう。つまり、ここに入っているデータがILそのものなのである。

ildasm.exeで表示したMainメソッドの中身
 

 INDEX
  解説 インサイド .NET Framework [改訂版]
  第5回 アセンブリのロードとセキュリティ
    1.Windowsローダーの動作
    2.CLRのロード
  3.署名の検証とプログラムの開始
    4.いくつものセキュリティ・チェック
 
インデックス・ページヘ  「解説:インサイド .NET Framework [改訂版]」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間