这是一个与我前几天问的另一个问题相关的问题;我建议您在这里快速阅读它,因为它可以包含有用的信息。无论如何,我的目标可执行文件中有两个静态类(ECXregister 总是在类的方法中发现),很明显第一个包含第二个:
.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);
这是Virtual Function Table第一个的:
.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
和Virtual Function Table第二个:
.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
在伪代码中,所有这些都应该是这样的:
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...
};
所有我想要做的是增加的大小CFG_ENTRY位于结构的阵列CFG_DB_TABLE从500到1000。知道CFG_ENTRY结构的大小(它是996字节),这似乎是一项非常简单的任务。由于filledSlotsCount(在代码中多次引用)放置在结构的末尾,我可以使用两种不同的方法进行处理:
- 增加现有
cfgEntriesto的大小1000并将每个指针引用filledSlotsCount和其他变量增加 996*500。 - 将 a 附加
CFG_ENTRY newCfgEntries[1000]到结构的末尾并cfgEntries通过 sizeof(CFG_DB_TABLE)-(996*1000)设置每个指针引用。这个好像比较简单。
因此,例如,使用第一种方法,这一小段CFG_DB_ParseData代码:
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) )
{
变成:
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) )
{
方法的代码CFG_DB_TABLE_CreateInstance变为:
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);
现在......做这些修改我避免了内存重叠/覆盖到类本身,但我仍然需要处理.data segment它本身,对吗?事实上,我认为我必须将其大小扩展 996*500,并且正如在我之前的问题中帮助我的其他用户所建议的那样,我也应该移动:
.data:0190BD08 CFG_DB db
.data:0190BD0C CFG_DB_TABLE<struct CFG_ENTRY[500], unsigned int> db
到底部.data segment,对吧?否则,这些静态类的内存可能会超过段中位于它们之后的静态实例的内存。
我的问题很简单:
1)如果 (data:0190BD3C - data:0190BD0C)中的静态大小包含最小字节(但可能更多,因为我看到一些从它开始的指针引用),它怎么可能CFG_DB_TABLE只有 30 个字节?我在计算中是否遗漏了一些非常重要的东西?.data segment4+996*500*4=498008this+502036
2) 如何将.data segment996*500的大小移动扩展?我是否必须手动编辑 PE 标头值?
3)如果这是真的有必要......我怎么能就动静态数据的引用CFG_DB和CFG_DB_TABLE实例,从中间向底部.data segment本身?是否有任何工具可以做到这一点,同时还可以重写对它们的每个引用?