Что небезопасно в этом коде? - PullRequest
8 голосов
/ 24 июня 2011

Я изучаю управляемый и неуправляемый код в 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 этим кодом? А что может пойти не так с кодом выше?

Ответы [ 5 ]

6 голосов
/ 27 июля 2011

Что делает этот код небезопасным, так это использование оператора 'ldind.i4'.Это загружает 4-байтовое целое число со знаком из адреса памяти.Можно указать любой адрес памяти, что позволяет вам читать с любого адреса памяти в текущем процессе.Это считается небезопасным и не поддается проверке.Например, вы можете использовать это для просмотра других доменов приложений, что недопустимо.

6 голосов
/ 24 июня 2011

Он называется небезопасным, отчасти потому, что им не управляют.

Вы можете легко создавать утечки памяти в стиле c ++, нет граничных проверок и других проблем ...

Хорошая статьяо небезопасном коде также перечислены некоторые риски:

Использование небезопасного кода в C #

4 голосов
/ 24 июня 2011

Небезопасный может не означать опасного, но есть одна вещь, которая важна в небезопасном коде: это не поддается проверке . Это может означать несколько вещей, например, не проверять границы массива. В вашем простом примере. в этом не так уж много опасного или страшного. Это довольно просто.

In может быть небезопасным, поскольку он также обходит большинство механизмов безопасности в .NET Framework; вот почему небезопасный код в любом случае требует полного доверия.

Небезопасно! = Неуправляемый. Небезопасный просто означает, что он может манипулировать указателями.

3 голосов
/ 24 июня 2011

Как правило, ключевое слово unsafe обеспечивает прямой доступ к памяти и, следовательно, обходит все проверки и проверки безопасности CLR.

Вот хорошая статья об использовании и воздействии кода unsafe: http://blogs.msdn.com/b/sebby1234/archive/2006/04/05/565090.aspx

0 голосов
/ 23 февраля 2012

По умолчанию компиляторы Microsoft C # и Visual Basic.NET создают «безопасный» код.Безопасный код - это код, который надежно проверен.Однако, используя небезопасное ключевое слово C # или другие языки (такие как C ++ с Managed Extensions или язык ассемблера IL), вы можете создать код, который не может быть надежно проверен.То есть код может быть на самом деле безопасным, но проверка не может его доказать.

администратор может отключить проверку (с помощью оснастки «.NET Management» консоли управления Microsoft.).При выключенной проверке JIT-компилятор скомпилирует непроверяемый IL в собственные инструкции процессора;однако администратор берет на себя полную ответственность за поведение кода.

...