繁体   English   中英

3台计算机上的C ++缓冲区溢出有所不同

[英]C++ buffer overflow different on 3 machines

我正在用C ++测试一个简单的缓冲区溢出。 该示例是一个测试,假设没有进行检查,恶意用户可能会使用缓冲区溢出来覆盖变量。

该示例定义了一个缓冲区,然后定义了一个变量,这意味着应该为该缓冲区分配空间,然后为该变量分配空间。 该示例从cin读取长度为5的缓冲区,然后检查admin变量是否设置为非0的值(如果是),则用户在概念上获得了admin访问权限。

#include <iostream>
using namespace std;

int main()
{
    char buffer[5];
    int admin = 0;

    cin>>buffer;
    if(strcmp(buffer,"in") == 0)
    {
        admin = 1;
        cout<<"Correct"<<endl;
    }
    if(admin != 0)
        cout << "Access" << endl;
    return 0;
}

我有3台计算机,1台Windows和2台Linux系统。

当我在Windows(CodeBlocks)上对其进行测试时,它在逻辑上输入了5个以上的字符,并且溢出并重写了admin变量的字节

现在我的第一个linux系统也可以工作,但是只有当我输入13个字符时,这与不同的编译器以及它们如何为程序分配内存有关?

我的第二台linux机器根本不会溢出。 仅在第13个字符之后才会给出转储错误。

为什么它们有那么大的差异?

正如您所发现的,未定义的行为是未定义的。 试图解释它通常不是很有效。

在这种情况下,几乎可以肯定是由于堆栈的安排和由在编译器/系统之间变化的局部变量之间插入的填充字节。

您应该检查反汇编。 从那里您将看到确切发生了什么。

一般来说,有两件事要考虑:

  1. 由编译器填充以对齐堆栈变量。

  2. 编译器对堆栈变量的相对放置。

第一点:您的数组char buffer[5]; 将被填充,以便int admin; 将在堆栈上正确对齐。 希望它通常在x86x64上都填充为8个字节,因此要覆盖9个符号。 但是编译器可能会根据自己认为合适的方式进行不同的处理。 尽管如此, 看来 Windows和Linux计算机是x86 (32位)。

第二点:不需要编译器按声明顺序将堆栈变量放在堆栈上。 在Windows和第一个Linux机器上,编译器的确确实放置了char buffer[5]; 以下为int admin; ,因此您可以溢出其中。 在第二台Linux机器上,编译器选择以相反的顺序放置它,这样就不会溢出到int admin; ,在超出为char buffer[5];分配的空间char buffer[5];写入之后,您正在破坏main()调用方的堆栈框架char buffer[5];

这是我对类似问题自己答案的无耻链接- 研究这种溢出的一个例子

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM