I am new to C++ and I was playing around with string class. I realized when I run the following code in CodeBlocks with GNU compiler:

#include <iostream>

using namespace std;

int main()
{
    string test ="hi";
    cout<<"char is : "<<test[100];
    return 0;
}

I actually get a value. I play with indexes (I tried from 100 to 10000) and I may get other characters or I may get null. Does that mean this way you are able to read parts of memory that you are not supposed to? can you use it for exploitation? or is it just my mind being illusional?

  • 3
    Undefined behavior is undefined be.havior – πάντα ῥεῖ Sep 2 at 18:35
  • 1
    C++ doesn't have bounds-checking. Going out of bounds leads to undefined behavior and probably is (or at least use to be) the most common reason for most security problems of programs. – Some programmer dude Sep 2 at 18:35
  • 1
    You tell C++ to go to the 100th entry from the initial starting point, it will happily do so, whether it is "your memory" or not. What will happen? You don't know, I don't know, no one really can tell you. That's what undefined behavior is, and C++ is one of the very few languages where such a concept exists. – PaulMcKenzie Sep 2 at 18:36
  • 1
    To elaborate a bit on the comment by @Someprogrammerdude -- C++ doesn't require bounds checking on string's operator[]. There is no requirement on what the program does, which, formally, is referred to as "undefined behavior". The language definition does not prohibit bounds checking; throwing an exception for out of bounds access is allowable, since the behavior is simply undefined. Some implementations do that in debug mode. – Pete Becker Sep 2 at 18:56
  • 1
    @TheEngineer -- Because I think this is unsafe and exploitable! -- Which is why it's your responsibility to use secure / safe coding practices. You don't declare arrays to be of size N, and then willy-nilly take input from a user that goes beyond N and just plug it into your array accesses. You're responsible for any bounds-checking, unless you use function(s) to explicitly check for out-of-bounds access. C++ is designed to not hamper programming performance by doing access checks -- that falls on your shoulders. – PaulMcKenzie Sep 2 at 20:36
up vote 0 down vote accepted

This is undefined behavior, so anything can happen. The compiler can optimize away the line, insert abort(), or do anything else.

If the compiler does not make big changes to the code, and std::string implements short-string-optimization, then test[100] will access the stack frame of one of the functions that call main().

These functions are responsible for loading shared libraries, arranging the environment variables, constructing global objects such as std::cout, and creating and passing argc, argv, to main(). This code peeks into the stack of these functions. On a system with memory protection, such as Linux or Windows, with far enough out-of-bounds access, the application will crash.

Don't rely on it, since the compiler can do something totally unexpected with it.

And yes, it can lead to exploitation. If out-of-bounds depends on user input, then that user may be able to read or write data they were not supposed to. This is one of the way a worm or a virus might spread: they read passwords, or write code that will execute upon a return from a function.

The answer is simple- Undefined Behavior. No, you can't trust this info and it is highly not recommended. Don't do it..

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.