This is a question related to another question I asked a few days ago; I recommend you to give a quick read to it here because it can contain useful information.
Anyway, I have two static classes inside my target executable (ECX
register always spotted inside classes' methods), and it clearly looks like the first one contains the second one:
.data:0190BD08 CFG_DB db ; DATA XREF: sub_40FFF0:loc_410049o
// 4 Bytes
.data:0190BD0C CFG_DB_TABLE<struct CFG_ENTRY[500], unsigned int> db ; DATA XREF: sub_A3DDD0+2Co
// 30 Bytes
.data:0190BD3C dword_190BD3C dd ? ; int dword_190BD3C[] DATA XREF: sub_5F5F70+B2r
With sub_40FFF0:loc_410049o =
CFG_DB_TABLE_Reset((int)&CFG_DB);
Here is the Virtual Function Table
of the first one:
.rdata:0137A1F0 dd offset CFG_DB
.rdata:0137A1F4 ??_7CFG_DB@@6B@ dd offset CFG_DB_Constructor
.rdata:0137A1F4 ; DATA XREF: CFG_DB_CreateInstance+8o
.rdata:0137A1F8 dd offset nullsub_008EF050
.rdata:0137A1FC dd offset sub_8EAB30
.rdata:0137A200 dd offset sub_8EF060
.rdata:0137A204 dd offset CFG_DB_TABLE_Reset
.rdata:0137A208 dd offset CFG_DB_ParseData
.rdata:0137A20C dd offset CFG_DB_ReadFile
And the Virtual Function Table
of the second one:
.rdata:0137A1D4 dd offset CFG_DB_TABLE
.rdata:0137A1D8 ??_7?$CFG_DB_TABLE@UCFG_ENTRY@@$0BPE@I@@6B@ dd offset CFG_DB_TABLE_Constructor
.rdata:0137A1D8 ; DATA XREF: CFG_DB_TABLE_Destructor+1Do
.rdata:0137A1D8 ; DATA XREF: CFG_DB_TABLE_CreateInstance+38o
.rdata:0137A1DC dd offset nullsub_008EF050
.rdata:0137A1E0 dd offset sub_8EAB30
.rdata:0137A1E4 dd offset sub_8EF060
.rdata:0137A1E8 dd offset CFG_DB_TABLE_Reset
.rdata:0137A1EC dd offset CFG_DB_ParseData
In pseudo-code all this should look like this:
static CFG_DB cfgDB;
class CFG_DB
{
int memoryAddress;
static CFG_DB_TABLE _DBTable;
// more data?
};
struct CFG_DB_TABLE
{
int memoryAddress;
CFG_ENTRY cfgEntries[500];
int filledSlotsCount;
// more data...
};
All I want to do is to increase the size of CFG_ENTRY
structure's array located in CFG_DB_TABLE
from 500
to 1000
. Knowing the size of CFG_ENTRY
structure (it's 996
bytes), it appears to be a quite simple task to do. Becaose of the fact that the filledSlotsCount
(referenced by many times in the code) is placed at the end of the struct I can proceed using two different approchaes:
- Increasing the size of the existing
cfgEntries
to1000
and increasing also every pointer reference tofilledSlotsCount
and other variables by 996*500. - Appending a
CFG_ENTRY newCfgEntries[1000]
to the end of the structure and setting every pointer reference tocfgEntries
by sizeof(CFG_DB_TABLE)-(996*1000). This one seems to be the simpler one.
So, for example, using the first approach, this small piece of CFG_DB_ParseData
's code:
while (true)
{
currentFilledSlotsCount = *(_DWORD *)(pointerToCFG_DB_TABLE + 498004);
if ( currentFilledSlotsCount >= 500 )
break;
*(_DWORD *)(pointerToCFG_DB_TABLE + 498004) = currentFilledSlotsCount + 1;
if (!CFG_DB_ParseEntry((void *)(pointerToCFG_DB_TABLE + 996 * currentFilledSlotsCount + 4), v5) )
{
Becomes:
while (true)
{
currentFilledSlotsCount = *(_DWORD *)(pointerToCFG_DB_TABLE + 996004);
if ( currentFilledSlotsCount >= 1000 )
break;
*(_DWORD *)(pointerToCFG_DB_TABLE + 996004) = currentFilledSlotsCount + 1;
if (!CFG_DB_ParseEntry((void *)(pointerToCFG_DB_TABLE + 996 * currentFilledSlotsCount + 4), v5) )
{
And the code of method CFG_DB_TABLE_CreateInstance
becomes:
int __thiscall CFG_DB_TABLE_CreateInstance(int this)
{
int v1; // esi@1
int v2; // [sp+18h] [bp-28h]@1
v1 = this;
v2 = this;
*(_DWORD *)this = &CFG_DB_TABLE<CFG_ENTRY_500_unsigned_int>::_vftable_;
unknown_libname_2672((void *)(this + 4), 996, 1000, sub_8EECA0, sub_8EEA00);
Now... doing these modifications I avoided memory overlapping/overwriting into the classes themselves, but I still have to deal with the .data segment
itself, right? In fact I think I have to extend its size by 996*500 and, as suggested by other users that helped me out in my previous question, I should also move:
.data:0190BD08 CFG_DB db
.data:0190BD0C CFG_DB_TABLE<struct CFG_ENTRY[500], unsigned int> db
To the bottom of the .data segment
, right? Otherwise the memory of those static classes risks to run over the memory of static instances that are located after them in the segment.
My questions are quite simple:
1) How can it be possible that the size of the static CFG_DB_TABLE
is only 30 bytes in the .data segment
(data:0190BD3C - data:0190BD0C) if it contains 4+996*500*4=498008
bytes minimum (but probably even more because I saw some pointer references starting from it like this+502036
)? Am I missing something very important in my calculations?
2) How can I move extend the size of the .data segment
by 996*500? Do I have to manually edit the PE header values?
3) If this is really necessary... how can I move my static data references concerning CFG_DB
and CFG_DB_TABLE
instances from the middle to the bottom of the .data segment
itself? Is there any tool out there that can do this also taking care of rewriting every reference to them?