How to recreate data memory space from loaded space?
I have this DLL that I created. It is introduced into another process. Inside another process, I search from this 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 is using a data structure, say
struct S
{
unsigned char a;
unsigned char b;
unsigned char c;
};
Does it always show up in process memory the same way? I mean, if Sa = 2 (which always follows b = 3, c = 4), it is a structure represented on a continuous string in the process memory space, like
Offset
---------------------
0x0000 | 0x02 0x03 0x04
Or these variables can be in different places, for example
Offset
---------------------
0x0000 | 0x00 0x02 0x00
0x03fc | 0x00 0x03 0x04
If the latter, how to recover the data structure from different points from memory?
Thanks a
lot in advance, nhaa123
source to share
If your victim is written in C or C ++ and the data types used are really simple, then you will always find them as one block of bytes in memory.
But once you have C ++ types like std::string
this, this observation no longer holds. First, the exact layout will differ between C ++ compilers and even different versions of the same compiler. The bytes of a std :: string will most likely not be in the contiguous array, but sometimes they are. If they are split in two, finding the second half will probably not help you find the first half.
Don't run more complex environments like JIT-JVM running Java application. The types you encounter in memory are very complex; you can write a book about decoding them.
source to share
The order of the members will always be the same, and the structure will occupy a contiguous block of memory.
Depending on the compiler, the addition may be added between the contributors, but it will still be the same if the program is recompiled with the same compiler and the same settings. If the addition is completed and you do not know about it, you cannot reliably determine it at runtime - all the information that the compiler has lost up to this point, and you just have to parse the templates and guess.
source to share
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 a 32-bit platform (I don't know if this is true for 64-bit), the offset c is 4 since there is one byte padded after b and there are 3 more bytes after d at the end (if I am correct remember).
This will be different if the structure is aligned.
source to share
Now my question. If the target process uses a data structure [...], is it always represented in the same way in the process memory? I mean if Sa = 2 (which always follows b = 3, c = 4), is it a structure represented on a continuous line in the process memory space?
Yes, however this will often be augmented to align members in ways you might not expect. So by simply recreating the data structure to interact with it through code injection.
I would highly recommend using ReClassEx or ReClass.NET , two open source programs built specifically for recovering data structures from memory and generating useful C ++ code! Check out the screenshot:
source to share