views:

72

answers:

3

Dears,

I've got this DLL I made. It's injected to another process. Inside the other process, I do a search from it's memory space with the following function:


void MyDump(const void *m, unsigned int n)
{
        const char *p = reinterpret_cast(m);

        for (unsigned int i = 0; i < n; ++i) {
                // Do something with p[i]...
        }
}

Now my question. If the target process uses a data structure, let's say

struct S
{
        unsigned char a;
        unsigned char b;
        unsigned char c;
};

Is it always presented the same way in the process' memory? I mean, if S.a = 2 (which always follows b = 3, c = 4), is the structure presented in a continuous row in the process' memory space, like

Offset
---------------------
0x0000 | 0x02 0x03 0x04

Or can those variables be in a different places there, like

Offset
---------------------
0x0000 | 0x00 0x02 0x00
0x03fc | 0x00 0x03 0x04

If the latter one, how to reconstruct the data-structure from various points from the memory?

Many thanks in advance,
nhaa123

A: 

The order of member will always be the same and the structure will occupy a contiguous memory block.

Depending on a compiler padding might be added between members but it still will be the same if the program is recompiled with the same compiler and the same settings. If padding is added and you are unaware of it you can't detect it reliably at runtime - all the information the compiler had is lost to that moment and you are left to just analyze the patterns and guess.

sharptooth
+1  A: 

If your victim is written in C or C++, and the datatypes used are truly that simple, then you'll always find them as a single block of bytes in memory.

But as soon as you have C++ types like std::string that observation no longer holds. For starters, the exact layout will differ between C++ compilers, and even different versions of the same compiler. The bytes of a std::string will likely not be in a contiguous array, but sometimes they are. If they're split in two, finding the second half probably will not help you in finding the first half.

Not throw in more complicated environments like a JIT'ting JVM running a Java app. The types you encounter in memory are very very complex; one could write a book about decoding them.

MSalters
Well, how the application itself finds a splitted std::string? I mean, the information must be held somewhere, right?
nhaa123
The application itself will have loaded the appropriate C++ runtime. That runtime doesn't need to find the first half (the program logic will take care of that, e.g. by putting that part on the stack). That first half was created by the C++ runtime, so the same runtime can use it to find back the other part(s). The main problem for you would be that it's this second part of a std::string which often holds the characters themselves, and thus the only part you'd find when searching for a specific string.
MSalters
A: 

It depends on the alignment of the structure.

If you have something like this:

struct A
{
  int16_t a;
  char    b;
  int32_t c;
  char    d;
}

then by default on 32bit platform( I dont know if that is true for 64bit ), the offset of c is 4 as there is one byte padded after b, and after d there are 3 more bytess padded at the end (if I remember correctly).

It will be different if the structure has a specified alignment.

leiz