2011-06-24 8 views
8

私はCLRの管理コードとアンマネージコードについて学んでいます。 は、だから私はC#でCスタイルのポインタで、この例を書いた:このコードでは安全でないものは何ですか?

unsafe static void Main(string[] args) 
{ 
    int x; 
    int* y; 
    y = &x; 
    *y = 50; 
    Console.WriteLine(*y); 
    Console.WriteLine(((int)y).ToString()); 
} 

は、だから私は本当に私は上記のコードから得たILコードに安全ではないかと思っていますか?

.assembly extern mscorlib 
{} 
.assembly UnsafePointers 
{} 
.module UnsafePointers.exe 
.class private auto ansi beforefieldinit UnsafePointers.Program 
extends [mscorlib]System.Object 
{ 
    .method private hidebysig static void Main(string[] args) cil managed 
    { 
     .entrypoint 
     // Code size  34 (0x22) 
     .locals init (int32 x, 
     int32* y) 
     IL_0001: ldloca  x 
     IL_0003: conv.u 
     IL_0004: stloc  y 
     IL_0005: ldloc y 
     IL_0006: ldc.i4 50 
     IL_0008: stind.i4 
     IL_0009: ldloc  y 
     IL_000a: ldind.i4 
     IL_000b: call  void [mscorlib]System.Console::WriteLine(int32) 
     IL_0010: nop 
     IL_0011: ldloca  y 
     IL_0012: conv.i4 
     IL_0016: call  instance string [mscorlib]System.Int32::ToString() 
     IL_001b: call  void [mscorlib]System.Console::WriteLine(string) 
     IL_0021: ret 
    } 
}  

CLRはこのコードを管理しますか?上記のコードで何が問題になることがありますか?

+0

他の人の話に加えて、これはまだ100%マネージドコードです。確かに、メモリが正しいとは限りません.preverifyが教えてくれるツールです。 – John

答えて

6

このコードを安全にしないのは、 'ldind.i4'ステートメントの使用です。これにより、メモリアドレスから符号付き4バイト整数がロードされます。任意のメモリアドレスを与えることができ、現在のプロセス内の任意のメモリアドレスから読み取ることができます。これは安全ではなく、確認不能とみなされます。たとえば、これを使用して他のappdomainを見ることができますが、これは許可されていません。

+0

あなたの答えをありがとう!私はこの説明が私が探していたものだと思う。今は私にはとても分かりやすいようですが、今までそれを見ていませんでした。 – vldmrrdjcc

+1

Peverifyはすでに 'conv.u'に失敗しています。つまり、ロードされたアドレスを整数として再intrepretすることを安全に呼び出すことを拒否します。 – John

6

これは管理されていないため、部分的に安全ではないと呼ばれています。

あなたは簡単にC++スタイルのメモリリークを作成することができ、何の境界チェック、およびその他の問題がない...

危険なコードについての素晴らしい記事、また、いくつかのリスクを示しています

Using Unsafe Code in C#

+0

これはまだ管理されているコードですが、確認できません。 – John

3

一般に、unsafeキーワードを使用すると、メモリに直接アクセスできるため、CLRによるすべての検証と安全性チェックをバイパスできます。

はここで良いの使用上の記事やunsafeコードの影響です: http://blogs.msdn.com/b/sebby1234/archive/2006/04/05/565090.aspx

+0

これは非常にいい記事です、私はこれが私が探していたものだと思います。ありがとう! CLRが安全でないILコードを知っていること宣言された型を見ていますか?たとえば、ポインタ型の場合はコードが安全でないと判断しますか? – vldmrrdjcc

4

危険は危険を意味しないかもしれませんが、危険なコードで重要であることが一つあります。それは、検証不可能です。これは、配列の境界をチェックしないなど、いくつかのことを意味する可能性があります。あなたの簡単な例で。それについてそれほど危険でも怖いものでもありません。かなり簡単です。

Inは、.NET Frameworkのセキュリティメカニズムの大部分を占めるため、安全ではない可能性があります。とにかく安全でないコードにはフルトラストが必要な理由です。

Unsafe!= Unmanaged。安全でないことは単にポインタを操作できることを意味します。

0

デフォルトでは、MicrosoftのC#およびVisual Basic.NETコンパイラは「安全な」コードを生成します。安全なコードは、検証可能な安全なコードです。ただし、C#の安全でないキーワードを使用するか、Managed ExtensionsまたはIL Assembly言語でC++などの他の言語を使用すると、検証可能な安全ではないコードを生成することができます。つまり、コードは実際には安全ですが、検証では証明できません。

管理者は、「.NET管理」Microsoft 管理コンソールスナップインを使用して、検証を無効にすることができます。検証をオフにすると、JITコンパイラは検証不能なILをネイティブCPU命令にコンパイルします。ただし、管理者はコードの動作を完全に掌握しています。

関連する問題