我正在阅读有关缓冲区溢出的信息。我发现有关堆栈上局部变量的内存分配的一件奇怪的事
int f1 ()
{
char string1[12];
char string2[4];
}
这里分配发生在堆栈上。
现在,在GCC中string2被分配了4个字节,但是如果我声明2的幂(最多16),那么编译器将为它分配16个字节。这意味着如果我在3、5、6、7,....,15字节中分配string2,那么编译器会为它分配16字节,但是如果我以1,2,4,8的2幂进行分配,则...然后分配给它完全相同的大小。如果我分配超过16个字节(不是2的幂),则它将分配32个字节(我猜最多为32个字节)。
而在Visual Studio中,如果我分配1个字节,则分配9个字节,如果从2-4个字节,则分配12个字节,如果从5-8个字节,则由编译器分配16个字节。
谁知道为什么这样的任务???
Atleast在Visual Studio中,如果缓冲区溢出,我会收到调试错误,但在gcc中什么也没有发生。GCC仅在发生太大溢出时才提供分段错误。
堆栈帧大小受内存对齐选择的影响,对于32位代码,通常为4的倍数,对于64位代码为8的倍数。
两种编译器都可以使用canary进行堆栈框架损坏检查,canary是堆栈顶部的32位额外值,该值在函数入口处初始化并在函数出口处进行检查。如果Canary值更改,则由于堆栈帧很可能被恶意代码破坏而导致程序中止,这可能会更改函数返回地址并使它返回任意位置。一个非常流行的恶意软件注入媒介。
MSVC具有/ RTC选项,默认情况下在Debug配置中启用。这将这些金丝雀添加到每个局部变量之间。因此,它可以检测每个变量上的缓冲区溢出问题。
这些金丝雀当然会占用额外的空间,从而影响堆栈的框架大小。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句