Home > Programming, Reverse Engineering, Windows > Object Creation. How and where.

Object Creation. How and where.

February 21st, 2009

This seems to be something that confuses a lot of newbies so I’m going to take the time to explain it properly here.

‘Inspiration’: Example

First off. PE Files. Although we can ignore most of the details of the PE file format for the purposes of this there are still some basics that are important. A PE file has ’sections’. One of those sections is ‘.text’, this is typically where code is stored. Another we need to know about is ‘.data’, this is typically where global variables are stored. The last we need to know about is ‘.rdata’, this is typically where global constants, hardcoded strings, floating point constants, etc are stored.

Nitpicker’s Corner: I said “typically” because packers often abuse intricacies of the PE file format which are irrelevant for this discussion in order to avoid the use of these standard sections and confuses disassemblers and debuggers. I am dealing ONLY with regular PE files created by regular compilers such as MSVC++, Intel, etc.

Second. The stack and the heap. The stack is a LIFO (Last In First Out) data structure typically used for things like passing parameters to functions, temporarily saving or “pushing” values stored in registers to be restored or “popped” back later, storing local variables, saving function return addresses, etc. All threads typically have their own ’stack’ to manage. The heap is a ‘pool’ of dynamically allocated memory typically used to store objects which are dynamically allocated at runtime because there size or other details cannot be known at run time. For more info on either of these subjects please consult any book on computer science, or wikipedia.

Nitpicker’s Corner: I am referring only to the stack/heap structures/concepts in terms of their relevance to this discussion and only the implementations which I have outlined. I am aware that the “stack” is also a common data type.

The following is a “typical” C++ application.

Nitpicker’s Corner: Typical in the sense in which objects are created  in multiple fashions ane the application uses fairly standard C++ concepts.

Nitpicker’s Corner: Application is obviously not thread-safe due to lack of serialization on global objects.

#include <iostream>
#include <string>

std::string MyGlobalString(”Foobar”);
std::string* pMyOtherGlobalString = new std::string(”Foobar2″);

std::string& GetStaticString()
{
static std::string MyStaticString(”Foobar3″);
return MyStaticString;
}

void MyStringSub()
{
std::string MyStackString(”Foobar4″):
std::string* pMyHeapString(”Foobar5″);
// Do something here
}

int main()
{
std::cout << MyGlobalString << *pMyOtherGlobalString
<< GetStaticString() << std::endl;
return 0;
}

Now the question is, which objects are stored where?

MyGlobalString will typically be stored in the ‘.data’ section becaues it is a global object.

pMyGlobalString will typically be stored in the heap, but a pointer to it will be kept in the ‘.data’ section, again because it is a global object.

MyStaticString will typically be stored in the ‘.data’ section because it is also a ‘global’ object. Whats that you say? Its not a global? Well by defining it ’static’ we technically are defining it as ‘global’. Static objects are created when the program first runs and not destroyed until the program quits, they are effectively globals as far as the compiler is concerned, the only differences are at the higher language level. The differences at the lower level are negligible.

MyStackString will be stored on the stack because it is local to a function.

pMyHeapString will be stored in the heap but the pointer to it will be stored in the stack because it is local to a function.

What is interesting though is where all the strings like “Foobar1″, “Foobar2″ etc are stored. They are NOT stored in the ‘.data’ section with our string objects. Hardcoded C-style strings will typically be stored and referenced through the ‘.rdata’ section. This is because std::string objects are created at runtime but the underlying c-style string needs to be stored somewhere. This “somewhere” is usually ‘.rdata’ because the section is designed for constants and will typically be paged as read-only when in memory. Our hard-coded strings never need to be changed so this is the perfect spot to put them.

Cypher Programming, Reverse Engineering, Windows , , ,

  1. No comments yet.
  1. No trackbacks yet.