我正在为闭源程序创建一个工具。调试后,我有了要访问的结构的基地址。经过仔细检查,我看到它是一个多链表,其中前 3 个整数是指针,所有其他值都是数据。
我已经设法从我的分析中重建了这个结构:
struct UnitsInfo
{
//pointers to UnitsInfo structures, null when no structure available at that location
DWORD * a;//0x00
DWORD * b;//0x04
DWORD * c;//0x08
//data
int unkown_1; //0x0C
unsigned int Type; //0x10
unsigned int Amount;//ox14
};
UnitsInfo * Base_Node = ((UnitsInfo*)( (*(DWORD*)( (*(DWORD*)(0x00400000+0x008E98EC)) + 0x38)) + 0x0C);
现在,我对链接结构真的很陌生,更不用说多链接结构了。
我在想的是制作地图并进行暴力破解,直到我拥有所有地址。(可能无限循环)?
但我知道这不是遍历这个链表的方法。在不知道它是如何连接的情况下,我如何有效地遍历这个多链表中的所有节点(并避免我已经拥有的节点)?
编辑:感谢我终于成功的答案!
这是我的代码,可能对其他人有用吗?
#define MAX_PLAYERS (6)
#define POINTER(type,addr) (*(type*)(addr))
struct UnitsInfo
{
//pointers to UnitsInfo structures, null when no structure available at that location
DWORD * nodes[3];//0x00
//data
int unkown_1; //0x0C
unsigned int Type; //0x10
unsigned int Amount;//ox14
};
struct pinfo
{
bool in;
enum Controller {Ctrl_UNKNOWN, Ctrl_HUMAN, Ctrl_AI };
enum Nation {N_UNKNOWN, N_ALLIES, N_SOVIET, N_JAPAN };
std::string Name;
Nation Side;
short Team;
Controller Who;
int *Money;
int *Power;
int *Usage;
unsigned int *Color;
bool GotUnits;
DWORD *unit_start_node;
};
std::map<DWORD*,UnitsInfo*> UnitList[MAX_PLAYERS];
void GenerateUnitList(unsigned short slot)
{
std::set<DWORD*> todo;
unsigned int inserted = 1;
while(inserted)
{
inserted = 0;
for(auto it = UnitList[slot].begin(); it != UnitList[slot].end(); ++it)
{
for(short i = 0; i < 3; ++i)
{
if(it->second->nodes[i] != NULL)
{
if(UnitList[slot].find(it->second->nodes[i]) == UnitList[slot].end())
{
todo.insert(it->second->nodes[i]);
++inserted;
}
}
}
}
while(!todo.empty())
{
UnitList[slot][*todo.begin()] = &POINTER(UnitsInfo,*todo.begin());
todo.erase(todo.begin());
}
}
}
pinfo Player[MAX_PLAYERS];
//adding the first node
unsigned int CurrentSlot = (0xD8+(0x4*slot));
if(POINTER(DWORD,POINTER(DWORD,0x00400000+0x008E98EC)+CurrentSlot) != NULL)
{
Player[slot].unit_start_node = &POINTER(DWORD,POINTER(DWORD,POINTER(DWORD,POINTER(DWORD,0x00400000+0x008E98EC)+CurrentSlot) + 0x38) + 0x0C);
}
//adding first unit if available, if yes continue generating list
if(!Player[i].GotUnits)
{
if(POINTER(DWORD,*Player[i].unit_start_node+0x10) != NULL)
{
Player[i].GotUnits = true;
UnitList[i][(Player[i].unit_start_node)] = &POINTER(UnitsInfo,*Player[i].unit_start_node);
}
}
else
{
GenerateUnitList(i);
}
最棒的是,它就像一种魅力,而且不会滞后:)