|
|||
|
When you place a string between two quote marks in the function’s
parameter, how many characters should be limited? The character length should be 256. For example void Test( char* text ) { …. } Test( “0123456789” ); If character length is to be 512, 1024, or 4096, string is too big to fit into the stack. If anyone plants virus program into memory, it is possible to cause that buffer overruns unless null terminator is overwritten with new character value. The condition is shown *ptr != ‘\0’ is unsafe. More safe condition should be added. If buffer goes past overwritten null terminator, buffer overruns can be avoided with limited character garbages. char A[ 256 ] = "0123456789"; int main() { const int BUFFER_SIZE = 256; char B [ 256 ]; int index = 0; do { B[ index ] = A[ index ]; ++index; } while( index < BUFFER_SIZE - 1 && A[ index ] != '\0' ); // safe // while(A[ index ] != '\0' ); // unsafe B[ index ] = '\0'; return 0; } |
|
|
||||
|
||||
|
|
|
|||
|
Nephi Immortal <immortalnephi@gmail.com> wrote in news:88995416-31ea-
441d-9744-81e43b0afa15@n19g2000yqk.googlegroups.com: > When you place a string between two quote marks in the function’s > parameter, how many characters should be limited? The character > length should be 256. > > For example > > void Test( char* text ) { …. } > > Test( “0123456789” ); > > If character length is to be 512, 1024, or 4096, string is too big to > fit into the stack. > > If anyone plants virus program into memory, it is possible to cause > that buffer overruns unless null terminator is overwritten with new > character value. > > The condition is shown *ptr != ‘\0’ is unsafe. More safe condition > should be added. If buffer goes past overwritten null terminator, > buffer overruns can be avoided with limited character garbages. > > char A[ 256 ] "0123456789"; > > > int main() > { > const int BUFFER_SIZE = 256; > > char B [ 256 ]; > > int index = 0; > > do > { > B[ index ] = A[ index ]; > ++index; > } > while( index < BUFFER_SIZE - 1 && A[ index ] != '\0' ); // safe > // while(A[ index ] != '\0' ); // unsafe > > > B[ index ] = '\0'; > > return 0; > } You are solving an unexisting problem (at least in comp.lang.c++). #include <string> std::string a("0123456789"); int main() { std::string b = a; // safe } Extra bonus: you can have very large strings, no stack overflow with a std::string. nrhth Paavo |
|
|||
|
On Apr 28, 10:35*am, Paavo Helde <myfirstn...@osa.pri.ee> wrote:
> Nephi Immortal <immortalne...@gmail.com> wrote in news:88995416-31ea- > 441d-9744-81e43b0af...@n19g2000yqk.googlegroups.com: > > > > > > > When you place a string between two quote marks in the function’s > > parameter, how many characters should be limited? *The character > > length should be 256. > > > For example > > > void Test( char* text ) { …. } > > > Test( “0123456789” ); > > > If character length is to be 512, 1024, or 4096, string is too big to > > fit into the stack. > > > If anyone plants virus program into memory, it is possible to cause > > that buffer overruns unless null terminator is overwritten with new > > character value. > > > The condition is shown *ptr != ‘\0’ is unsafe. *More safe condition > > should be added. *If buffer goes past overwritten null terminator, > > buffer overruns can be avoided with limited character garbages. > > > char A[ 256 ] * * *"0123456789"; > > > int main() > > { > > * * *const int BUFFER_SIZE = 256; > > > * * *char B [ 256 ]; > > > * * *int index = 0; > > > * * *do > > * * *{ > > * * * * * B[ index ] = A[ index ]; > > * * * * * ++index; > > * * *} > > * * *while( index < BUFFER_SIZE - 1 && A[ index ] != '\0' ); //safe > > // * * while(A[ index ] != '\0' ); // unsafe > > > * * *B[ index ] = '\0'; > > > * * *return 0; > > } > > You are solving an unexisting problem (at least in comp.lang.c++). > > #include <string> > > std::string a("0123456789"); > > int main() { > * * * * std::string b = a; // safe > > } > > Extra bonus: you can have very large strings, no stack overflow with a > std::string. std::string's data members (including base pointer and size) are allocated into stack, but string allocates any number of bytes into heap. String has no big deal, but I talk about traditional C string. You need to take care to limit the number of characters because it does not know the length until reaching null terminator. std::string( "0123456789", 10 ) is both C string and C++ string. "0123456789" including null terminator in string constructor is C string and it is always pushed into stack before main function begins and pop out after main function ends. string constructor ignores null terminator unless length is included in the function parameter. It allocates 10 bytes into heap before each character is copied from stack to heap. If you show std::string( "0123456789" ) instead of std::string( "0123456789", 10 ), how can string constructor copy more than ten characters unless null terminator is overwritten with any character value in memory by virus program and until finding null terminator before garbage characters are copied? |
|
|||
|
Nephi Immortal <immortalnephi@gmail.com> wrote in news:2ce08a82-a893-
4910-869b-a9697d829c82@9g2000yqp.googlegroups.com: > > std::string( "0123456789", 10 ) is both C string and C++ string. > "0123456789" including null terminator in string constructor is C > string and it is always pushed into stack No. The string literal is placed in a data segment in the compiled executable and is not copied anywhere from there without the program's consent. > before main function begins > and pop out after main function ends. You are talking nonsense. > string constructor ignores null > terminator unless length is included in the function parameter. It > allocates 10 bytes into heap before each character is copied from > stack to heap. > > If you show std::string( "0123456789" ) instead of > std::string( "0123456789", 10 ), how can string constructor copy more > than ten characters unless null terminator is overwritten with any > character value in memory by virus program and until finding null > terminator before garbage characters are copied? The evil virus cannot overwrite the null terminator as in a typical implementation the string literal is placed in a read-only memory segment. Also, you have the virus functionality backwards - the buffer overrun exploit first attempts to snigger in a too large string which does not fit into buffer, and gain access via that. In your scenario virus has already gained access and then trying to enlarge the string by deleting a zero terminator - this is backwards. cheers Paavo |
|
|||
|
On Apr 28, 2:31*pm, Paavo Helde <myfirstn...@osa.pri.ee> wrote:
> Nephi Immortal <immortalne...@gmail.com> wrote in news:2ce08a82-a893- > 4910-869b-a9697d829...@9g2000yqp.googlegroups.com: > > > > > std::string( "0123456789", 10 ) is both C string and C++ string. > > "0123456789" including null terminator in string constructor is C > > string and it is always pushed into stack > > No. The string literal is placed in a data segment in the compiled > executable and is not copied anywhere from there without the program's > consent. > > > before main function begins > > and pop out after main function ends. > > You are talking nonsense. > > > string constructor ignores null > > terminator unless length is included in the function parameter. *It > > allocates 10 bytes into heap before each character is copied from > > stack to heap. > > > If you show std::string( "0123456789" ) instead of > > std::string( "0123456789", 10 ), how can string constructor copy more > > than ten characters unless null terminator is overwritten with any > > character value in memory by virus program and until finding null > > terminator before garbage characters are copied? > > The evil virus cannot overwrite the null terminator as in a typical > implementation the string literal is placed in a read-only memory > segment. > > Also, you have the virus functionality backwards - the buffer overrun > exploit first attempts to snigger in a too large string which does not > fit into buffer, and gain access via that. In your scenario virus has > already gained access and then trying to enlarge the string by deleting a > zero terminator - this is backwards. if the code shows below, int main() { const char* A = "0123456789"; // store in stack const char B[ 10 + 1 ] = "0123456789"; // store in stack static const char C[] = "0123456789"; // store in data segment return 0; } then do both A and B store 11 characters into stack and C into data segment? If you say data segment, then it should look like this below void foo( "0123456789" ); // store string in data segment // global scope const char X[] = "0123456789"; // store string in stack? struct bar { static const char N[]; } const char bar::N[] = "0123456789"; // store string in data segment You mentioned that data segment is read only. Can separate data segment be read/write unless string is non-constant? |
|
|||
|
Nephi Immortal <immortalnephi@gmail.com> wrote in
news:44b62e39-e7bd-4b25-b7bf-b0389f365ba6@2g2000yqk.googlegroups.com: > if the code shows below, > > int main() > { > const char* A = "0123456789"; // store in stack > const char B[ 10 + 1 ] = "0123456789"; // store in stack > static const char C[] = "0123456789"; // store in data segment > > return 0; > } > > then do both A and B store 11 characters into stack and C into data > segment? Why don't you check by yourself? Here is an example program: #include <iostream> int main() { int stack_top; const char* A = "0123456789"; // store in stack const char B[ 10 + 1 ] = "0123456789"; // store in stack int before_C; static const char C[] = "0123456789"; // store in data segment int after_C; std::cout << "A takes " << ( (char*) &stack_top - (char*) &A) << " bytes in the stack\n"; std::cout << "B takes " << ( (char*) &A - (char*) &B) << " bytes in the stack\n"; std::cout << "C takes " << ( (char*) &before_C - (char*) &after_C - sizeof(after_C)) << " bytes in the stack\n"; return 0; } In MSVC 32-bit Debug mode (no smart optimizations done by the compiler!) this prints out: A takes 4 bytes in the stack B takes 12 bytes in the stack C takes 0 bytes in the stack A is a 4-byte pointer on the stack, the string literal is by itself in some (read-only) data segment. B is indeed 11 bytes on stack, 1 extra byte for alignment padding. C seems to be indeed in a data segment. > > If you say data segment, then it should look like this below > > void foo( "0123456789" ); // store string in data segment String literal is in a read-only data segment. A pointer to it is passed to foo(). > > // global scope > const char X[] = "0123456789"; // store string in stack? If it is in global scope, then there is no stack involved. Stack is related to the actual execution thread; in a multi-threaded program each thread has its own stack memory, but global variables are visible in all threads. This already shows they are not on stack. The string literal itself is placed in a read-only data segment. A copy may be made for X and placed in a read-write or read-only data segment. I guess an optimizer is allowed to coalesce these things into one, but not 100% sure. > > struct bar > { > static const char N[]; > } > > const char bar::N[] = "0123456789"; // store string in data segment This is the same as X I think. > > You mentioned that data segment is read only. Can separate data > segment be read/write unless string is non-constant? Sure, there are read-write data segments as well. Non-const global variables go there for sure. hth Paavo |
|
|||
|
Nephi Immortal <immortalnephi@gmail.com> wrote:
> When you place a string between two quote marks in the function???s > parameter, how many characters should be limited? The character > length should be 256. > > For example > > void Test( char* text ) { ???. } > > Test( ???0123456789??? ); > > If character length is to be 512, 1024, or 4096, string is too big to > fit into the stack. What a load of BS. When you call 'Test()' above, the only thing that gets put onto the stack is one pointer. |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|