Buffer overflow protection for stackalloc in .Net

前端 未结 1 562
予麋鹿
予麋鹿 2021-01-01 00:13

From C# reference for stackalloc:

the use of stackalloc automatically enables buffer overrun detection features in the common language runtime (CLR).

相关标签:
1条回答
  • 2021-01-01 00:52

    Yes, the .NET jitter generates the kind of stack canary checking that also exists in native code generated by the Microsoft C/C++ compiler with the /GS compiler option. The basic scheme is to store a random 32-bit value at the top of the stack, written at method entry. At method exit it checks if the value is still there. A change in the value is a very high predictor for a stack buffer overflow, the kind that malware uses to take control of a program.

    Some code to play with:

    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;
        }
    }
    

    Running this code triggers the Windows Error Reporting dialog, even with the debugger attached. You can see the crash reason in the Output window:

    The program '[3636] ConsoleApplication33.exe: Native' has exited with code -1073740791 (0xc0000409).

    The exception code is defined in the ntstatus.h SDK header file:

    //
    // 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
    

    You can see the code that does this with Debug + Windows + Disassembly. The essential parts of 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 
    

    The actual canary value changes every time the code is jitted.

    0 讨论(0)
提交回复
热议问题