.NET中stackalloc的缓冲区溢出保护 [英] Buffer overflow protection for stackalloc in .Net

查看:89
本文介绍了.NET中stackalloc的缓冲区溢出保护的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从C#参考中获取stackalloc:

From C# reference for stackalloc:

使用stackalloc会自动在公共语言运行时(CLR)中启用缓冲区溢出检测功能.如果检测到缓冲区溢出,则将尽快终止进程,以最大程度地减少执行恶意代码的可能性.

the use of stackalloc automatically enables buffer overrun detection features in the common language runtime (CLR). If a buffer overrun is detected, the process is terminated as quickly as possible to minimize the chance that malicious code is executed.

具体来说,.NET实现了哪种保护机制?
它还会检测缓冲区不足吗?针对哪种已知的攻击,防护能力较弱?

Specifically, what kind of protection mechanism is implemented for .NET?
And will it also detect buffer underruns? Against which known attacks is the protection weaker?


对于上下文,例如对于MS C ++编译器,可在此处获取信息:
Windows ISV软件安全防护:

堆栈缓冲区溢出检测功能是在Visual Studio .NET 2002中引入到C/C ++编译器的,并在后续版本中进行了更新./GS是一个编译器开关,它指示编译器添加启动代码以及函数Epilog和Prolog代码,以生成并检查放置在函数堆栈中的随机数.

The Stack Buffer Overrun Detection capability was introduced to the C/C++ compiler in Visual Studio .NET 2002 and has been updated in subsequent versions. /GS is a compiler switch that instructs the compiler to add startup code, and function epilog and prolog code, to generate and check a random number that is placed in a function's stack.

请注意,Visual C ++ 2005(及更高版本)还会对堆栈上的数据进行重新排序,以使其更难以预测地破坏该数据.示例包括:
•将缓冲区移动到比非缓冲区更高的内存中.此步骤可以帮助保护驻留在堆栈上的函数指针.
•在运行时将指针和缓冲区参数移至较低的内存,以减轻各种缓冲区溢出攻击.

Note that Visual C++ 2005 (and later) also reorders data on the stack to make it harder to predictably corrupt that data. Examples include:
• Moving buffers to higher memory than non-buffers. This step can help protect function pointers that reside on the stack.
• Moving pointer and buffer arguments to lower memory at run time to mitigate various buffer overrun attacks.

推荐答案

是的,.NET抖动生成了一种堆栈金丝雀检查,这种检查也存在于由Microsoft C/C ++编译器使用/GS编译器选项生成的本机代码中.基本方案是将一个随机的32位值存储在堆栈的顶部,并写在方法入口处.在方法退出处,它检查该值是否仍然存在.值的变化是堆栈缓冲区溢出(恶意软件用来控制程序的一种)的极高预测指标.

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.

要使用的一些代码:

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错误报告对话框,即使已连接调试器也是如此.您可以在输出"窗口中查看崩溃原因:

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

程序"[3636] ConsoleApplication33.exe:本机"已退出,代码为-1073740791(0xc0000409).

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

异常代码在ntstatus.h SDK头文件中定义:

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

您可以看到使用Debug + Windows + Disassembly执行此操作的代码.Kaboom的基本组成部分:

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.

这篇关于.NET中stackalloc的缓冲区溢出保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆