缓冲区溢出问题 [英] buffer overflow question

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

问题描述

大家好,

我有一个简单的问题.下面的代码是
容易发生缓冲区溢出吗?当我执行它时
大字符串(> 20)时出现分段错误

Hi all,

I have some simple question. The code below is
vulnerable to buffer overflow right? When I execute it
with large string (>20) I get segmentation fault

1. char dest[20];
2. char * p = new char[100];
3. cin>>p;
4. cout<<endl<<p;
5. strcpy(dest,p);
6. return 0;



我的问题是(是否会发生奇怪的事情),如果我将第1行替换为
char * dest =新的char [20];
那么一切似乎都可以正常工作,即使p的内容也可以打印
即使我输入了大字符串(例如50个字符).
只是好奇在这种情况下发生了什么.显然strcpy仍然覆盖了
要删除的大字符串-不会出现分段错误.为什么?



My question is (and strange thing happens) if I replace line 1 with
char *dest = new char [20];
then everything seems to work fine, even content of p gets printed
even if I enter large string (e.g., 50 characters).
Just curious what is happening in this case. Apparently strcpy still overwrote
the large string to dest -- and no segmentation fault heppened.why?

推荐答案

运气.

不要依赖它. new指令将数据从堆栈移动到堆-当您将其声明为char dest [20]时,它是一个本地数组,因此它进入堆栈.使用strcpy时,它将覆盖数组的末尾,然后开始覆盖来自strcpy的返回地址.因此,当strcpy尝试返回已完成复制的地址时,该地址将不再有效,并且会出现错误.

当您用new替换它时,它将在堆上分配新数组,而不是在堆栈上分配新数组,因此,尽管它覆盖了数据,但它不会影响strcpy返回地址,因此不会引起故障.但是.

始终检查尺寸!
Luck.

Don''t rely on it. The new instruction moves the data from the stack to the heap - when you declare it as char dest[20] it is a local array, so it goes on the stack. When you use the strcpy, it overwrites the end of your array, and then starts to write over the return address from strcpy. So when strcpy tries to return having finished copying, the address is no longer valid, and you get an error.

When you replace it with new it allocates the new array on the heap, not the stack, so despite it overwriting data it does not affect the strcpy return address so the fault is not noticed. Yet.

Always check your dimensions!


在第一种情况下,dest分配在堆栈上,在第二种情况下,它分配在堆上.

当两个字符串都在堆上时,您将获得一个如下的内存映像:
In your first case dest is allocated on the stack in in the second case it is allocated on the heap.

When both strings are on the heap, you have a memory image like this:
dest: at some address
p:    at dest + 20 + alignment (4 with 8 byte alignment) + heap info


如果现在将包括NULL字节的20个以上的字符复制到dest,它将溢出到p中(strcpy无法处理重叠内存的复制,但在这种情况下它将起作用).现在打印dest将显示完整的字符串,而打印p将仅显示字符串的结尾. p处的堆已损坏.但是当不再使用p时,您将不会意识到这一点.

堆栈内存的组织与堆内存不同:它以相反的方向使用内存(从初始大小开始减去所需内存的大小).因此,内存映像如下所示(最高地址在前):


If you now copy more than 20 characters including the NULL byte to dest, this will overflow into p (strcpy can''t handle copying of overlapping memory but in this case it will work). Printing now dest will show the full string while printing p will show only the end of the string. The heap at p is corrupted. But you will not recognize this when not using p anymore.

The organization of stack memory is different from the heap memory: It uses memory in a reverse direction (starting at the initial size subtracting the size of the required memory). So the memory image looks like this (highest addresses first):

current stack top at some address
dest: top - 20


现在将超过20个字节复制到dest时,这将覆盖顶部的堆栈内容.堆栈上还有其他局部变量,函数参数和函数的返回地址.在您的情况下,某些函数的返回地址很可能会被覆盖,从而导致访问冲突.

因此,区别在于损坏的堆栈和堆内存之间的区别在于,堆栈损坏要危险得多,因为它会影响程序执行,而堆内存主要包含数据(当内存包含指针时,这也可能导致访问冲突).


When now copying more than 20 bytes to dest, this will overwrite the stack content on top. On the stack are other local variables, function parameters, and the return addresses of functions. In your case the return address of some function is most likely overwritten resulting in the access violation.

So the difference is between corrupted stack and heap memory where the stack corruption is much more dangerous because it effects program execution while heap memory mainly contains data (which may also lead to access violations when the memory contains pointers).


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

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