缓冲区溢出示例与gcc

时间:2016-11-24 15:53:13

标签: c gcc memory

我试图在C中的strcmp函数中演示缓冲区溢出。 我有strcpyV.c个文件:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{

    char a[8];
    char b[8];

    // function causes buffer overflow
    strcpy(b, "01234567");

    // buffer overflow again
    strcpy(a, "89abcdef");

    printf("\nb = %s\n", b);

    return 0;
}

我使用gcc编译器编译这个程序。

gcc -o strcpyV strcpyV.c

当我在树莓派B +(Raspbian wheezy)中这样做并运行时:

./strcpyV

我得到了预期的结果:

b = 0123456789abcdef

但是当我在Ubuntu 16.04中完成整个过程时,结果是:

b = 01234567

有没有办法在没有这种内存保护的情况下编译代码?

2 个答案:

答案 0 :(得分:2)

您可以将数组打包在结构中。然后适用结构打包的规则。结构打包规则不是由标准定义的,但如果我们使用gcc,则在这种情况下char数组将是连续的(注意b现在放在a之前):

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
    struct ab {
        char b[8];   
        char a[8];
    } s;

    // function causes buffer overflow
    strcpy(s.b, "01234567");

    // I removed this buffer overflow by making the string fit.
    // A second overflow doesn't add anything - quite the opposite.
    // The first overflow is sufficient to get the
    // behaviour you want.
    strcpy(s.a, "89abcde");

    printf("\nb = %s\n", s.b);

    return 0;
}

答案 1 :(得分:2)

您可以禁用安全检查:

从手册:

-fstack-protector
      Emit extra code to check for buffer overflows, such as stack smashing attacks.  >This is done by adding a guard variable to functions with
      vulnerable objects.  This includes functions that call alloca, and functions with >buffers larger than 8 bytes.  The guards are initialized when
      a function is entered and then checked when the function exits.  If a guard check >fails, an error message is printed and the program exits.

-fstack-protector-all
      Like -fstack-protector except that all functions are protected.

如果你想禁用它,请不要选择名称

-fno-stack-protector -fno-stack-protector-all

缓冲区溢出示例:

int main(){
    int valid = 0;
    char str1 = ["START"];
    char str2 = [8];

    gets(str2);
    if(strncmp(str1, str2, 8) == 0){
        valid = 1;
        cout << "buffer: " << str1 << ", " << str2 << ", " << valid << endl;
    }

}