Code:
#include <ida.idc>
/************************************************************************
Desc: Label each database with an appropriate name and struct
Author: kynox
Modified for Cataclysm by TOM_RUS
Website: http://www.gamedeception.net
*************************************************************************/
static WoWDb_GetName( dbBase )
{
auto dbName;
// mov eax, offset aDbfilesclientA ; "DBFilesClient\\Achievement.dbc"
dbName = GetString( Dword(dbBase), -1, ASCSTR_C );
//Message("%s", dbName);
// Return the the token after \ and before .
return substr( dbName, strstr( dbName, "\\" ) + 1, -5 );
}
static BuildStruct()
{
// struct size changed, need figure out what was removed....
auto id;
id = AddStrucEx(-1,"WoWClientDB",0);
AddStrucMember(id, "funcTable", 0X00, 0x20500400, 0X0, 4, 0XFFFFFFFF, 0X0, 0x000002);
AddStrucMember(id, "numRows", 0X04, 0x20000400, -1, 4);
AddStrucMember(id, "maxIndex", 0X08, 0x20000400, -1, 4);
AddStrucMember(id, "minIndex", 0X0C, 0x20000400, -1, 4);
AddStrucMember(id, "stringTable", 0X10, 0x20000400, -1, 4);
AddStrucMember(id, "FirstRow", 0X14, 0x20000400, -1, 4);
AddStrucMember(id, "Rows", 0X18, 0x25500400, 0XFFFFFFFF, 4, 0XFFFFFFFF, 0X0, 0x000002);
return id;
}
static StructBuilt()
{
return ( GetStrucIdByName( "WoWClientDB" ) != -1 );
}
static main()
{
auto curAddr, y, count;
// 55 8B EC 51 53 56 57 8B 7D 08 8D 45 08 89 4D FC 8B 0F 50 51 E8 ? ? ? ? 83 7D 08 00 75 15 8B
//curAddr = FindBinary( 0, SEARCH_DOWN, "55 8B EC 51 53 56 8B 75 08 57 8D 45 08 8B D9 8B 0E 50 51 E8 ? ? ? ? 83 7D 08 00 75 15 8B 16" );
// 55 8B EC 81 EC 04 01 00 00 53 56 57 8B 7D 08 8D 45 08 89 4D FC 8B 0F 50 51 E8 ? ? ? ? 83 7D
//curAddr = FindBinary( 0, SEARCH_DOWN, "55 8B EC 51 53 56 57 8B 7D 08 8D 45 08 89 4D FC 8B 0F 50 51 E8 ? ? ? ? 83 7D 08 00 75 15 8B" );
curAddr = FindBinary( 0, SEARCH_DOWN, "55 8B EC 81 EC 04 01 00 00 53 56 57 8B 7D 08 8D 45 08 89 4D FC 8B 0F 50 51 E8 ? ? ? ? 83 7D" );
if(curAddr == BADADDR)
{
Message("Can't find dbcLoadFunction, aborting...\n");
return -1;
}
if ( !StructBuilt() )
{
Message( "Building struct..\n" );
if( BuildStruct() == -1 )
{
Message( "Failed to build struct..\n" );
return;
}
}
for(y = RfirstB(curAddr); y != BADADDR; y = RnextB(curAddr, y))
{
auto dbNameOffset, dbStruct, dbName;
dbStruct = ReadOperand(y, "mov", "offset");
dbNameOffset = GetNameEffset(y);
Message("%X %X %X\n", y, dbStruct, dbNameOffset);
if(dbNameOffset == BADADDR)
{
count = count + HandleLoadLoop(dbStruct);
continue;
}
SetType( dbStruct, "WoWClientDB;" );
MakeStruct( dbStruct, "WoWClientDB" );
dbName = WoWDb_GetName( dbNameOffset );
Message("%s\n", dbName);
MakeName( dbStruct, form( "g_%sDB", dbName ) );
count++;
}
Message("DBC count %u\n", count);
}
static HandleLoadLoop(xref)
{
auto count;
do
{
auto dbNameOffset, dbStruct, dbName;
dbStruct = Dword(xref);
dbNameOffset = Dword(xref + 4);
if(dbStruct == 0 || dbNameOffset == 0)
break;
dbName = WoWDb_GetName(dbNameOffset);
Message("%X %X %s\n", dbStruct, dbNameOffset, dbName);
SetType( dbStruct, "WoWClientDB;" );
MakeStruct( dbStruct, "WoWClientDB" );
MakeName( dbStruct, form( "g_%sDB", dbName ) );
xref = xref + 8;
count++;
} while(1);
return count;
}
static GetNameEffset( xref )
{
auto offset, dbName;
offset = ReadOperand( xref, "push", "offset" );
dbName = GetString( Dword(offset), -1, ASCSTR_C );
if(strstr( dbName, ".dbc" ) > -1)
return offset;
return BADADDR;
}
static ReadOperand( xref, operand, filter )
{
auto prevFunc;
prevFunc = PrevFunction( xref );
//Message("%X %X\n", xref, prevFunc);
do
{
auto disasm;
disasm = GetDisasm( xref );
if ( strstr( disasm, operand ) > -1 && strstr( disasm, filter ) > -1 )
break;
xref = PrevHead( xref, prevFunc );
} while ( 1 );
return GetOperandValue( xref, operand == "mov" ? 1 : 0);
}