Home > Blockchain >  How do you determine the size of a class when reverse engineering?
How do you determine the size of a class when reverse engineering?

Time:01-11

I've been trying to learn a bit about reverse engineering and how to essentially wrap an existing class (that we do not have the source for, we'll call it PrivateClass) with our own class (we'll call it WrapperClass).

Right now I'm basically calling the constructor of PrivateClass while feeding a pointer to WrapperClass as the this argument...

Doing this populates m_string_address, m_somevalue1, m_somevalue2, and missingBytes with the PrivateClass object data. The dilemma now is that I am noticing issues with the original program (first a crash that was resolved by adding m_u1 and m_u2) and then text not rendering that was fixed by adding mData[2900].

I'm able to deduce that m_u1 and m_u2 hold the size of the string in m_string_address, but I wasn't expecting there to be any other member variables after them (which is why I was surprised with mData[2900] resolving the text rendering problem). 2900 is also just a random large value I threw in.

So my question is how can we determine the real size of a class that we do not have the source for? Is there a tool that will tell you what variables exist in a class and their order (or atleast the correct datatypes or datatype sizes of each variable). I'm assuming this might be possible by processing assembly in an address range into a semi-decompiled state.

class WrapperClass
{
public:
    WrapperClass(const wchar_t* original);

private:
    uintptr_t m_string_address;
    int m_somevalue1;
    int m_somevalue2;
    char missingBytes[2900];
};

WrapperClass::WrapperClass(const wchar_t* original)
{
    typedef void(__thiscall* PrivateClassCtor)(void* pThis, const wchar_t* original);
    PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase   0x1c00);
    PrivateClassCtorFunc(this, original);
}

CodePudding user response:

So my question is how can we determine the real size of a class that we do not have the source for?

You have to guess or logically deduce it for yourself. Or just guess. If guessing doesn't work out for you, you'll have to guess again.

Is there a tool that will tell you what variables exist in a class and their order (or atleast the correct datatypes or datatype sizes of each variable) I'm assuming by decompiling and processing assembly in an address range.

No, there is not. The type of meta information that describes a class, it's members, etc. simply isn't written out as the program does not need it nor are there currently no facilities defined in the C Standard that would require a compiler to generate that information.

CodePudding user response:

There are exactly zero guarantees that you can reliably 'guess' the size of a class. You can however probably make a reasonable estimate in most cases.

The one thing you can be sure of though: the only problem is when you have too little memory for a class instance. Having too much memory isn't really a problem at all (Which is what adding 2900 extra bytes works).

On the assumption that the code was originally well written (e.g. the developer decided to initialise all the variables nicely), then you may be able to guess the size using something like this:

#define MAGIC 0xCD

// allocate a big buffer
char temp_buffer[8092];
memset(temp_buffer, MAGIC, 8092);

// call ctor
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase   0x1c00);
PrivateClassCtorFunc(this, original);

// step backwards until we find a byte that isn't 0xCD. 
// Might want to change the magic value and run again
// just to be sure (e.g. the original ctor sets the last 
// few bytes of the class to 0xCD by coincidence. 
// 
// Obviously fails if the developer never initialises member vars though!
for(int i = 8091; i >= 0; --i) {
   if(temp_buffer[i] != MAGIC) {
      printf("class size might be: %d\n", i   1);
      break;
   }
}

That's probably a decent guess, however the only way to be 100% sure would be to stick a breakpoint where you call the ctor, switch to assembly view in your debugger of choice, and then step through the assembly line by line to see what the max address being written to is.

  • Related