(char *) type vars and .rdata section

W

Ws

Ok, so I have a question reguarding compilers and placing strings into
the .rdata section of the PE.

I was working on a program and couldn't figure out why I was getting a
0xc0000005 error message (memory access violation) while trying to
alter a (char *) data type'd variable. Proper size, pointers all
accurate and verified. I finally got frustrated enough and tried
something else, built it as a Release application (using Microsoft
Visual Studio 2005 Professional -- it is a legitimate copy, believe it
or not), and took it into OllyDbg.

My finding in OllyDbg was that it was storing the string in the .rdata
section of the PE, and that this section of the file was Read-Only
access. Ok, that answers why it was erroring.

== But more to the point, why did the compiler place the string in
the .rdata section?! I have prepared a short sample code that
duplicates the same problem. (merged stdafx.h into the source inline
to show the concept.)

Code:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void alter_data( char * data )
{
	// simply sets the first byte to be 'b' instead
	data[0] ^= 'b';
}

int main ( int argc, char ** argv )
{
	char *my_data = "Hello, world!";

	printf( "%s\n", my_data );
	alter_data( my_data );
	printf( "%s\n", my_data );

	// pause
	_getch();

	return 0;
}

Anyone have any pointers as to why VC++ placed the my_data string into
the .rdata section of the file?

Thanks in advance for any pointers on this query :)

-Wes
 
F

Flash Gordon

Ws wrote, On 06/08/07 16:42:

My finding in OllyDbg was that it was storing the string in the .rdata
section of the PE, and that this section of the file was Read-Only
access. Ok, that answers why it was erroring.

== But more to the point, why did the compiler place the string in
the .rdata section?!

Because it is allowed to and it felt like it. Read question 1.32 of the
comp.lang.c FAQ at http://c-faq.com/
> I have prepared a short sample code that
duplicates the same problem. (merged stdafx.h into the source inline
to show the concept.)

Code:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void alter_data( char * data )
{
	// simply sets the first byte to be 'b' instead[/QUOTE]

// style comments were only added to the C standard in C99, a standard 
that MSVC does not support. It might support it as an extension or you 
might be compiling the code as C++ by mistake, in either case you need 
to check your compiler options carefully.
[QUOTE]
data[0] ^= 'b';[/QUOTE]

This line does not attempt to set the first byte to 'b' so either your 
comment is wrong or the above line is wrong.
[QUOTE]
}

int main ( int argc, char ** argv )
{
	char *my_data = "Hello, world!";[/QUOTE]

Although the C standard does not make string literals const qualified it 
explicitly says that modifying them invokes "undefined behaviour", i.e. 
you are not allowed to do it but the compiler is not required to warn 
you about it. One reason for this is so that string literals *can* be 
placed in read only memory.
[QUOTE]
printf( "%s\n", my_data );
	alter_data( my_data );
	printf( "%s\n", my_data );

	// pause
	_getch();[/QUOTE]

I believe you can get MSVC to not close the output window on program 
termination and thus avoid the need to pause the program. Even if you 
did need to you could use the standard getchar function instead of the 
non-standard _getch function. Why make your program non-portable when 
you don't need to?
[QUOTE]
return 0;
}

Anyone have any pointers as to why VC++ placed the my_data string into
the .rdata section of the file?

Because you should not be trying to modify it.
 
B

Bill Waddington

Ok, so I have a question reguarding compilers and placing strings into
the .rdata section of the PE.

I was working on a program and couldn't figure out why I was getting a
0xc0000005 error message (memory access violation) while trying to
alter a (char *) data type'd variable. Proper size, pointers all
accurate and verified. I finally got frustrated enough and tried
something else, built it as a Release application (using Microsoft
Visual Studio 2005 Professional -- it is a legitimate copy, believe it
or not), and took it into OllyDbg.

My finding in OllyDbg was that it was storing the string in the .rdata
section of the PE, and that this section of the file was Read-Only
access. Ok, that answers why it was erroring.

== But more to the point, why did the compiler place the string in
the .rdata section?! I have prepared a short sample code that
duplicates the same problem. (merged stdafx.h into the source inline
to show the concept.)

Code:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void alter_data( char * data )
{
	// simply sets the first byte to be 'b' instead
	data[0] ^= 'b';
}

int main ( int argc, char ** argv )
{
	char *my_data = "Hello, world!";

	printf( "%s\n", my_data );
	alter_data( my_data );
	printf( "%s\n", my_data );

	// pause
	_getch();

	return 0;
}

Anyone have any pointers as to why VC++ placed the my_data string into
the .rdata section of the file?

I'll try to save the regulars the trouble...

C FAQs 8.5 & 1.32 and others.

http://c-faq.com/charstring/strlitinit.html

Bill
 
W

Ws

This line does not attempt to set the first byte to 'b' so either your
comment is wrong or the above line is wrong.

Comment is wrong. Altered it for an XOR to better tinker with it, and
forgot to update the comment since it is just a demo code block.
Although the C standard does not make string literals const qualified it
explicitly says that modifying them invokes "undefined behaviour", i.e.
you are not allowed to do it but the compiler is not required to warn
you about it. One reason for this is so that string literals *can* be
placed in read only memory.

Thank you for a full elaboration as to why a compiler would/could do
that. Much appreciated taking the time :)
I believe you can get MSVC to not close the output window on program
termination and thus avoid the need to pause the program. Even if you
did need to you could use the standard getchar function instead of the
non-standard _getch function. Why make your program non-portable when
you don't need to?

Eh, don't know, just sort of did it, as I'm just trying to learn C++
by hacking, not by any formalized teaching from a book or such, as
every time I pick up some 800 page (exaggeration, but I digress) I get
distracted very easy, and I've always ended up learning faster by
tinkering over time. :)

But again, thanks for your elaboration! Much appreciated.
 
C

CBFalconer

Ws said:
Heh, sorry, it's been a while since I'd been trying to learn C/++
so I had forgotten about that lovely resource. Sorry for wasting
time with a frivolous query.

Just a word of caution - this is comp.lang.c, not c++. C++ is
another language, and discussion here is off-topic. So far you
have been discussing C, so no real problem yet.
 
F

Flash Gordon

Ws wrote, On 07/08/07 06:37:

Eh, don't know, just sort of did it, as I'm just trying to learn C++
by hacking, not by any formalized teaching from a book or such, as
every time I pick up some 800 page (exaggeration, but I digress) I get
distracted very easy, and I've always ended up learning faster by
tinkering over time. :)

Trying to learn C or C++ (they are very different languages) by
tinkering is not, in my opinion, very good. There is lots of stuff which
might happen to work using your current setup but which is nevertheless
still wrong and would fail if you change optimisation level. For C I
recommend K&R 2nd edition which is nice and short, ask in comp.lang.c++
if you want recommendations for C++.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top