Page 1 of 1
Visual C++ .BSS section
Posted: Tue Sep 13, 2011 5:23 am
by mutex
Hi,
I have three questions.
First; How can i find the address of the .bss section and size/end pointer using symbols in Visual c++ (like with LD)? I dont want to parse PE headers since i want the data in NASM constants/data for multiboot header, and other places before i can/want to do PE handling.
Second; Data in .bss is assumed to be zeroed, but not guaranteed. Right? What are the impacts of filling .bss with for example 0xcc or 0x90 pattern? Does the compiler at any time assume .bss to be zero or require it to be? Reason of question i want to fill .bss data with special data to catch bad pointers, halt "rouge" eip, etc and im not sure about the impacts it might have on code generated. Of course im using 0x00000000 today to trap bad pointers.
Third; How do i define (if possible) what fill pattern different compilers use to fill .bss and uninitialized data / code fillspace?
regards
Thomas
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 5:42 am
by gerryg400
All compilers assume that the BSS is entirely zeroed before main is entered. Therefore the loader or the startup code must set the BSS to zero. The impact of not setting the BSS to zero is that your software will not work correctly.
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 5:48 am
by mutex
Thank for your reply.
Ok, so for global variables they are
required to be zeroed. Is this stated in the C/C++ standard somewhere? Only stack allocated symbols actually have a undefined state when first accessed then...
But that leaves me with a question. What about pointers. Is it a way to define a pointer (globaly) and have the compiler fill it with 0xcccccc instead of 0x00000000 (trough the bss clearing) ? Pointers on the stack will always contain garbage...
I find no reference to; "bss" or "uninitialized" in the C99 standard document.
http://www.open-std.org/jtc1/sc22/WG14/ ... /n1256.pdf
But i find;
1 Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 5:55 am
by Combuster
mutex wrote:Is this stated in the C/C++ standard somewhere?
Actually, try the ELF specification. An application loader must fill sections for which no content is provided with zeroes.
But that leaves me with a question. What about pointers. Is it a way to define a pointer (globaly) and have the compiler fill it with 0xcccccc instead of 0x00000000
char * pointer = (char*)0xcccccccc;
You can't clear the stack: the compiler would have to explicitly overwrite the reserved stackspace after every function to make sure it actually contains garbage. Otherwise the first use will set a value, and the next use might inappropriately read that same value.
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 5:57 am
by mutex
Sure,, explicit initialization. Im more interrested in what happens when things are not explicit
Implicit and assumptions.. Together a very bad mix
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 6:41 am
by Solar
I am not sure where you are going with your questions.
mutex wrote:"All objects with static storage duration shall be initialized (set to their initial values) before program startup."
That's what happens with .data and .bss: The former is used to initialize static storage where the values are non-zero, the latter is used to initialize static storage where values
are zero (as it would be stupid to store all those zeroes in the binary).
Note that .bss != heap, and .bss != stack.
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 8:11 am
by mutex
Im pretty sure i put my questions clear, but i might have not. I'm sorry.
First if all i was not sure if my understanding of the BSS section was 100% right since its mostly based on old memory, assumptions and the way i always have thought of it. When i was looking to find some explicit definition that the BSS should really be zeroed i could not find it where i looked. Of course the PE and ELF formats have initialize, zero and not present flags for sections but i was not sure how the compiler actually handled memory from those sections in terms of what do they REALLY expect.
The reason behind this is really that im looking for ways for my os to trap bad pointers, bad eip etc, both for kernel and user programs. I have solutions for this today by using 0x0 as a pagefault (not present) page, checking if eip/esp etc is in bad places when getting pagefault and take action based on this, but then it crossed my mind that in Windows (atleast from my memory), null pointers are usually 0xcccccccc if im not mistaken? Then i was thinking about why..?
Then again i was thinking about code filling (not data in that case but CODE section) when functions are padded.. Usually i have seen 0x90 or 0x00, but i think i might have seen int3 somewhere aswell.. not sure if i remembered correctly. Then i was thinking (was 0x90 also the opcode for both NOP and int3) depending on the DBG flag was set, or was it that int3 had its special 0xcc code.. You know, one question usually leads to another.. Atleast one.. or an answer.
Then... I put my questions up there and was hopeful that someone might give me some short, brieft oneliners that could give all my questions an answer. Because this is'n really rocket science..
Sorry for bothering you. I like this forum alot, but some guys in here have a very low personal level for beeing irritated at other peoples post. Personaly i try to not get irritated at all and everything that i find stupid or dumb in this world,,,, That makes atlast my day less stressfull than it could potentionally be.
regards
Thomas
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 9:14 am
by Solar
Hmm... from my POV it looks like you're tossing lots of losely related questions up into the air and hope for someone else to paint a clean picture for you.
EIP, pointers, stuff pointed to, in stack, heap, bss, padding of code (i.e. .text section), pointers to bss (i.e. pointers to zero), null pointers (i.e. pointers being zero), ...
I think we answered your initial questions (if not, here's my take: 1) I don't know, 2) .bss is zero-initialized by definition, but I was under the impression you had a faulty idea what .bss actually is, as it covers only a very tiny part of your problem, and 3) completely up to the compiler, and I don't think you'll find much documentation on the issue (i.e., don't expect it to be a command-line switch).
Now we're trying to help with the underlying problem (how to enable your OS detecting bad pointers). For that, we have to untangle the mess of related questions (see beginning of my post).
As a tidbit, while the C standard allows NULL to be something different than 0x0, but insists that initializing a pointer to NULL and to 0x0 be identical, you'll need the cooperation of the OS and the toolchain to have "null" pointers be something other than 0x0. I don't know of any halfway-modern system (i.e., from the last twenty years or so) that has "null" pointers different from 0x0.
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 9:25 am
by mutex
Thanks,
No i just try to explain why i think what i do about a problem, and why im asking it.
So basically every compiler if its gcc, vc++ or intel would make any global/static variable 0x0 on initalization. This also go for pointers then. So basically if i try to access a pointer that its not initialized i will always end up with 0x0 if someone havent overwritten og set it before i use it. Thats very good to know. Because i was actually under the impression that it might not be like this in every case (dependent on compiler was my impression).
I actually found out that the 0xcccccccc thing from MS is a debug-crt related thing that actually fills the stack before its use (dont know if its before every called method or only initial. But that anyway sheds a little light over that thing.
Then the last digression was actually what padding (between aligned code or data) thats used. If its also 0x0 or something else.. I could se good reasons for using int3 opcode, but also 0x00. Depending on how you want to catch it (opcodef, or debug).
Last, but not least.. Anyone know how to get symbols/references to .bss in VC++? Does not seem to work like with LD.. Atleast from what i have found out..
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 11:14 am
by Solar
mutex wrote:So basically every compiler if its gcc, vc++ or intel would make any global/static variable 0x0 on initalization.
And this is where you lack precision of expression.
The compiler does what the program and the language tells it to do.
Every compiler will make this global array hold 0 on initialization.
Here, it won't.
So basically if i try to access a pointer that its not initialized i will always end up with 0x0 if someone havent overwritten or set it before i use it. Thats very good to know.
Only for objects of
static duration.
I actually found out that the 0xcccccccc thing from MS is a debug-crt related thing that actually fills the stack before its use...
That's a
completely different ballgame - stack is where objects of
automatic duration reside. They are
not zero-initialized by default.
Re: Visual C++ .BSS section
Posted: Tue Sep 13, 2011 2:34 pm
by mutex
Example (all are outside functions);
Code: Select all
int *x = 0; // Compiler will put data into .data with value 0? or bss and implicit set it to 0?
Code: Select all
int *y; // Compiler will put data into .bss and implicit set it to 0 ?
Code: Select all
int *z=12345678: // This is obvious. Compiler will put into .data and put data there.
So what will happen in both first cases is that it will point to 0x0 and if i use it without initializing it further i will read from 0x0.
Basically sums up what i thought, but i was not sure if .bss was actually guaranteed to be 0 or not.