2013-02-17 6 views
3

Из ссылки C# для stackalloc:защита от переполнения буфера для stackalloc в .NET

использование stackalloc автоматически включает переполнение буфера функцию обнаружения в общеязыковой среде выполнения (CLR). Если обнаружено переполнение буфера, процесс прекращается как можно быстрее, чтобы свести к минимуму вероятность того, что вредоносный код будет выполнен.

В частности, какой механизм защиты реализован для .NET?
И будет ли это также обнаружение переполнения буфера? Против каких известных атак защита слабее?


Для контекста, например, для компилятора MS C++ информация доступна здесь:
Windows ISV Software Security Defenses:

способность

Стек буфера обнаружения перерасход был введен в/C++ компилятор C в Visual Studio .NET 2002 и был обновлен в последующих версиях./GS - это компилятор, который инструктирует компилятор добавить код запуска и функцию epilog и пролог, чтобы генерировать и проверять случайное число, которое помещается в стек функции.

Обратите внимание, что Visual C++ 2005 (и более поздняя версия) также переупорядочивает данные в стеке, чтобы усложнить предсказуемое повреждение этих данных. Примеры включают:
• Перемещение буферов в более высокую память, чем небуферы. Этот шаг может помочь защитить указатели функций, которые находятся в стеке.
• Перемещение указателей и аргументов буфера для уменьшения объема памяти во время выполнения, чтобы уменьшить различные атаки переполнения буфера.

ответ

10

Да, .NET-дрожит генерирует проверку стека каналов, которая также существует в собственном коде, сгенерированном компилятором Microsoft C/C++ с опцией компилятора/GS. Основная схема состоит в том, чтобы хранить случайное 32-битное значение в верхней части стека, написанное при вводе метода. При выходе метода он проверяет, осталось ли значение. Изменение значения - очень высокий предиктор для переполнения буфера стека, вид, который вредоносная программа использует для управления программой.

Некоторые код, чтобы играть с:

class Program { 
    static void Main(string[] args) { 
     Kaboom(); 
    } 
    static unsafe void Kaboom() { 
     byte* ptr = stackalloc byte[1]; 
     for (int ix = 0; ix < 42; ++ix) ptr[ix] = 0; 
    } 
} 

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

Программа '[3636] ConsoleApplication33.exe: Native' завершился с кодом -1073740791 (0xc0000409).

Код исключения определяется в Ntstatus.h файле заголовка SDK:

// 
// MessageId: STATUS_STACK_BUFFER_OVERRUN 
// 
// MessageText: 
// 
// The system detected an overrun of a stack-based buffer in this application. This overrun could 
// potentially allow a malicious user to gain control of this application. 
// 
#define STATUS_STACK_BUFFER_OVERRUN  ((NTSTATUS)0xC0000409L) // winnt 

Вы можете увидеть код, который делает это с Debug + Windows + разборке. Важные части Kaboom:

00000000 push  ebp        ; setup stack frame 
00000001 mov   ebp,esp 
00000003 sub   esp,8        ; stack space for local variables 
00000006 xor   eax,eax 
00000008 mov   dword ptr [ebp-8],eax    ; zero-initialize local variables 
0000000b mov   dword ptr [ebp-4],eax 
0000000e mov   dword ptr [ebp-4],esp 
00000011 mov   dword ptr [ebp-8],0EDDB7EDFh  ; canary stored here 

// For loop code omitted 

0000002d cmp   dword ptr [ebp-8],0EDDB7EDFh  ; check canary value 
00000034 je   0000003B 
00000036 call  727767A8       ; crash program 
0000003b lea   esp,[ebp]       ; normal exit, pop stack frame 
0000003e pop   ebp 
0000003f ret 

Фактическое значение канарейки изменяется каждый раз при кодировании кода.