简体   繁体   English

缓冲区溢出是否发生在C ++字符串中?

[英]Does buffer overflow happen in C++ strings?

This is concerning strings in C++. 这与C ++中的字符串有关。 I have not touched C/C++ for a very long time; 我很长时间没有接触过C / C ++; infact I did programming in those languages only for the first year in my college, about 7 years ago. 事实上,大约7年前,我只在大学的第一年用这些语言编程。

In C to hold strings I had to create character arrays(whether static or dynamic, it is not of concern). 在C中保存字符串我必须创建字符数组(无论是静态的还是动态的,都不需要考虑)。 So that would mean that I need to guess well in advance the size of the string that an array would contain. 这意味着我需要提前猜出数组将包含的字符串的大小。 Well I applied the same approach in C++. 我在C ++中应用了相同的方法。 I was aware that there was a std::string class but I never got around to use it. 我知道有一个std :: string类但我从来没有使用它。

My question is that since we never declare the size of an array/string in std::string class, does a buffer overflow occur when writing to it. 我的问题是,因为我们从未在std :: string类中声明数组/字符串的大小,所以在写入时会发生缓冲区溢出。 I mean, in C, if the array's size was 10 and I typed more than 10 characters on the console then that extra data would be writtein into some other object's memory place, which is adjacent to the array. 我的意思是,在C中,如果数组的大小是10并且我在控制台上键入了超过10个字符,那么额外的数据将被写入到与数组相邻的其他对象的内存位置。 Can a similar thing happen in std::string when using the cin object. 使用cin对象时,std :: string中是否会发生类似的事情。

Do I have to guess the size of the string before hand in C++ when using std::string? 使用std :: string时,我是否必须在C ++之前猜测字符串的大小?

Well! 好! Thanks to you all. 谢谢大家。 There is no one right answer on this page (a lot of different explanations provided), so I am not selecting any single one as such. 这个页面上没有一个正确的答案(提供了很多不同的解释),所以我没有选择任何一个这样的答案。 I am satisfied with the first 5. Take Care! 我很满意第一个5.小心!

Depending on the member(s) you are using to access the string object, yes. 根据您用来访问string对象的成员,是的。 So, for example, if you use reference operator[](size_type pos) where pos > size() , yes, you would. 所以,例如,如果你使用reference operator[](size_type pos) ,其中pos > size() ,是的,你会的。

Assuming no bugs in the standard library implementation, no. 假设标准库实现中没有错误,没有。 A std::string always manages its own memory. std::string总是管理自己的内存。

Unless, of course, you subvert the accessor methods that std::string provides, and do something like: 当然,除非你破坏std::string提供的访问器方法,否则执行以下操作:

std::string str = "foo";
char *p = (char *)str.c_str();
strcpy(p, "blah");

You have no protection here, and are invoking undefined behaviour . 这里没有保护,并且正在调用未定义的行为

The std::string generally protects against buffer overflow, but there are still situations in which programming errors can lead to buffer overflows. std :: string通常可以防止缓冲区溢出,但仍然存在编程错误可能导致缓冲区溢出的情况。 While C++ generally throws an out_of_range exception when an operation references memory outside the bounds of the string , the subscript operator [] (which does not perform bounds checking) does not . 虽然C ++通常在操作引用字符串边界之外的内存时抛出out_of_range异常但是下标operator [](不执行边界检查)不会

Another problem occurs when converting std::string objects to C-style strings. 将std :: string对象转换为C样式字符串时会出现另一个问题 If you use string::c_str() to do the conversion, you get a properly null-terminated C-style string. 如果使用string :: c_str()进行转换,则会得到一个正确的以null结尾的C风格字符串。 However, if you use string::data(), which writes the string directly into an array (returning a pointer to the array), you get a buffer that is not null terminated. 但是,如果使用string :: data(),它将字符串直接写入数组(返回指向数组的指针),则会得到一个非空终止的缓冲区。 The only difference between c_str() and data() is that c_str() adds a trailing null byte.

Finally, many existing C++ programs and libraries have their own string classes. 最后,许多现有的C ++程序和库都有自己的字符串类。 To use these libraries, you may have to use these string types or constantly convert back and forth. 要使用这些库,您可能必须使用这些字符串类型或不断地来回转换。 Such libraries are of varying quality when it comes to security. 在安全性方面,这些库的质量各不相同。 It is generally best to use the standard library (when possible) or to understand the semantics of the selected library. 通常最好使用标准库(如果可能)或理解所选库的语义。 Generally speaking, libraries should be evaluated based on how easy or complex they are to use, the type of errors that can be made, how easy these errors are to make, and what the potential consequences may be. 一般而言,应根据使用它们的容易程度或复杂程度,可能产生的错误类型,这些错误的容易程度以及潜在的后果可能来评估库。 refer https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/295-BSI.html 参考https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/295-BSI.html

In c the cause is explained as follow: 在c中,原因解释如下:

void function (char *str) {
       char buffer[16];
       strcpy (buffer, str);
    }
    int main () {
      char *str = "I am greater than 16 bytes"; // length of str = 27 bytes
      function (str);
    }

This program is guaranteed to cause unexpected behavior, because a string (str) of 27 bytes has been copied to a location (buffer) that has been allocated for only 16 bytes. 此程序保证会导致意外行为,因为已将27个字节的字符串(str)复制到仅分配了16个字节的位置(缓冲区)。 The extra bytes run past the buffer and overwrites the space allocated for the FP, return address and so on. 额外的字节经过缓冲区并覆盖为FP分配的空间,返回地址等。 This, in turn, corrupts the process stack. 反过来,这会破坏进程堆栈。 The function used to copy the string is strcpy, which completes no checking of bounds. 用于复制字符串的函数是strcpy,它不会检查边界。 Using strncpy would have prevented this corruption of the stack. 使用strncpy可以防止堆栈的这种损坏。 However, this classic example shows that a buffer overflow can overwrite a function's return address, which in turn can alter the program's execution path. 但是,这个经典的例子表明缓冲区溢出可以覆盖函数的返回地址,这反过来可以改变程序的执行路径。 Recall that a function's return address is the address of the next instruction in memory, which is executed immediately after the function returns. 回想一下,函数的返回地址是内存中下一条指令的地址,该函数在函数返回后立即执行。

here is a good tutorial that can give your answer satisfactory. 这是一个很好的教程 ,可以让你的答案令人满意。

In C++, the std::string class starts out with a minimum size (or you can specify a starting size). 在C ++中, std::string类以最小大小开始(或者您可以指定起始大小)。 If that size is exceeded, std::string allocates more dynamic memory. 如果超出该大小, std::string将分配更多动态内存。

Assuming the library providing std::string is correctly written, you cannot cause a buffer overflow by adding characters to a std::string object. 假设正确写入了提供std::string的库,则不能通过向std::string对象添加字符来导致缓冲区溢出。

Of course, bugs in the library are not impossible. 当然,库中的错误并非不可能。

"Do buffer overflows occur in C++ code?" “C ++代码中是否会发生缓冲区溢出?”

To the extent that C programs are legal C++ code (they almost all are), and C programs have buffer overflows, C++ programs can have buffer overflows. 如果C程序是合法的C ++代码(它们几乎都是),并且C程序有缓冲区溢出,C ++程序可能会有缓冲区溢出。

Being richer than C, I'm sure C++ can have buffer overflows in ways that C cannot :-} 比C更丰富,我确信C ++可以以C不能的方式进行缓冲区溢出: - }

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

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