Code:
#include <idc.idc>
static getRegisterFunction()
{
auto dwAddress;
dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "55 8B EC 83 E4 F8 83 EC 1C 53 56 8B C2");
if(IsAddrStartOfFunction(dwAddress) == 0)
return -1;
else
return dwAddress;
}
static ExtractPath( sPath )
{
auto dwIndex;
for ( dwIndex = strlen( sPath ); strstr( substr( sPath, dwIndex, -1 ), "/" ) && dwIndex > 0; dwIndex-- );
return substr( sPath, 0, dwIndex + 1 );
}
static IsAddrStartOfFunction(dwAddress)
{
if(GetFunctionAttr(dwAddress, FUNCATTR_START) == dwAddress)
return 1;
return 0;
}
static GetLibnameFromAddr(dwAddress)
{
auto dwLibnameptr = FindText(dwAddress - 0xC, SEARCH_DOWN|SEARCH_NEXT, 0, 0, "mov edx");
if(dwLibnameptr >= dwAddress)
return "";
auto dwLibnameAddress = GetOperandValue(dwLibnameptr, 1);
return GetString(dwLibnameAddress, -1, ASCSTR_C);
}
static GetLibtable1FromAddr(dwAddress)
{
auto dwTable1Ptr = FindText(dwAddress - 0xC, SEARCH_DOWN|SEARCH_NEXT, 0, 0, "push");
//Message("t1ptr %x\n", dwTable1Ptr);
if (dwTable1Ptr <= GetFunctionAttr(dwAddress, FUNCATTR_START) || dwTable1Ptr >= GetFunctionAttr(dwAddress, FUNCATTR_END))
return BADADDR;
auto dwTable1 = GetOperandValue(dwTable1Ptr, 0);
//Message("t1addr %x\n", dwTable1);
return dwTable1;
}
static GetLibtable2FromAddr(dwAddress)
{
auto dwTable2Ptr = FindText(dwAddress - 0x1B, SEARCH_DOWN|SEARCH_NEXT, 0, 0, "push");
//Message("t2ptr %x\n", dwTable2Ptr);
if (dwTable2Ptr <= GetFunctionAttr(dwAddress, FUNCATTR_START) || dwTable2Ptr >= GetFunctionAttr(dwAddress, FUNCATTR_END))
return BADADDR;
auto dwTable2 = GetOperandValue(dwTable2Ptr, 0);
//Message("t2addr %x\n", dwTable2);
return dwTable2;
}
static DumpLua(hFile, name, table)
{
auto dwCurrent = table;
auto functionname, functionaddr;
//fprintf(hFile, "\n\n# %s start #\n", name);
while(Dword(dwCurrent) != 0x0)
{
functionname = GetString(Dword(dwCurrent), -1, ASCSTR_C);
if (!IsString(functionname))
continue;
functionaddr = Dword(dwCurrent + 4);
if (functionaddr == 0xFFFFFFFF)
break;
dwCurrent = dwCurrent + 8;
//Message("%x %s_%s\n", functionaddr, name, functionname);
fprintf(hFile, "%x %s_%s\n", functionaddr, name, functionname);
}
//fprintf(hFile, "# %s end #\n", name);
}
static main()
{
auto hFile, sPath;
auto prefix = "Script_";
auto dwRegisterFunction = getRegisterFunction();
auto dwAddress = 0;
auto libname;
auto libtable1, libtable2;
sPath = ExtractPath(GetIdbPath()) + "Dump.txt";
hFile = fopen(sPath, "w");
if(hFile != -1)
{
fprintf(hFile, "[WildStar Lua Function Dumper]\n");
fprintf(hFile, "\n");
}
while(dwAddress != BADADDR)
{
dwAddress = RnextB(dwRegisterFunction, dwAddress);
libname = GetLibnameFromAddr(dwAddress);
if (libname == "")
continue;
Message("dumping name %s : %x\n", libname, dwAddress);
libtable1 = GetLibtable1FromAddr(dwAddress);
libtable2 = GetLibtable2FromAddr(dwAddress);
if (libtable1 == BADADDR|| libtable1 < 0x1000)
{
Message("'BADADDR' or 'libtable1 < 0x1000' result on function GetLibtable1FromAddr (skipping) (unexpected behavious)\n");
continue;
}
DumpLua(hFile, prefix + libname, libtable1);
if (libtable2 == BADADDR || libtable2 < 0x1000 || libtable2 == libtable1)
{
Message("'BADADDR' or 'libtable2 < 0x1000' or 'libtable2 == libtable1' result on function GetLibtable2FromAddr (skipping) (it can be an expected behaviour)\n");
continue;
}
DumpLua(hFile, prefix + libname, libtable2);
}
fprintf(hFile, "Dump Complete.\n");
fclose(hFile);
Message("Dump complete.\n");
}
Credits : The guy who made the WoW lua dump idc script, his code was a huge base + copy/pasted some funcs from it.