Код:
#include <ida.idc>
/************************************************************************
Desc: Label all lua functions with proper name
Author: TOM_RUS
Credit: bobbysing for RenameFunc
*************************************************************************/
// 1 = Success, 0 = Failure
static RenameFunc(dwAddress, sFunction)
{
auto dwRet;
//return 1;
dwRet = MakeNameEx(dwAddress, sFunction, SN_NOWARN);
if(dwRet == 0)
{
auto sTemp, i;
for(i = 0; i < 32; ++i)
{
sTemp = form("%s_%i", sFunction, i);
if((dwRet = MakeNameEx(dwAddress, sTemp, SN_NOWARN)) != 0)
{
Message("Info: Renamed to %s instead of %s\n", sTemp, sFunction);
break;
}
}
}
return dwRet;
}
static main()
{
auto counter, x, y, count, i, luaName, luaFunc, luaGlobal;
// Live client 3.2.0.10314
x = FindBinary(0, SEARCH_DOWN, "55 8B EC 8B 45 0C 56 8B 35 ? ? ? ? 6A 00 50 56 E8 ? ? ? ? 8B 4D 08 51 56 E8 ? ? ? ?");
// PTR client 0.2.2.10433
//x = FindBinary(0, SEARCH_DOWN, "55 8B EC 56 8B 35 ? ? ? ? 85 F6 75 22 6A 01 56 68 ? ? ? ? 68 9E 06 00 00 68 ? ? ? ?");
if(x == BADADDR)
{
Message("Can't find FrameScript::RegisterFunction, aborting...\n");
return -1;
}
Message("FrameScript::RegisterFunction found at: %X\n", x);
for(y = RfirstB(x); y != BADADDR; y = RnextB(x, y))
{
auto dwRet, nameOffset, luaOffset, op1, op2, op3;
//Message("Reference at: %X\n", y);
nameOffset = y - 8;
luaOffset = y - 14; // -13 if no loop
//Message("%X %X\n", nameOffset, luaOffset);
//Message("%X %X\n", GetOperandValue(nameOffset, 1), GetOperandValue(luaOffset, 1));
op1 = GetOperandValue(y + 0x05, 1);
op2 = GetOperandValue(y + 0x08, 1);
op3 = GetOperandValue(y + 0x0B, 1);
//Message("op1 %i\n", op1);
//Message("op2 %i\n", op2);
//Message("op3 %i\n", op3);
if(op2 == BADADDR) // all this shit only because of Lua_PlayDance...
{
luaOffset++;
luaName = GetString(Dword(GetOperandValue(nameOffset, 1)), -1, ASCSTR_C);
luaFunc = GetOperandValue(luaOffset, 1);
//Message("%s %X %X\n", luaName, luaFunc, Dword(luaFunc));
if((dwRet = RenameFunc(Dword(luaFunc), form( "Script_%s", luaName))) == 0)
Message("Failed to rename 0x%08X to %s\n", Dword(luaFunc), luaName);
else
counter++;
}
else
{
count = op3 / op2;
//Message("count %i\n", count);
for(i = 0; i < count; ++i)
{
luaName = GetString(Dword(GetOperandValue(nameOffset, 1) + (i * 8)), -1, ASCSTR_C);
luaFunc = GetOperandValue(luaOffset, 1) + (i * 8);
//Message("%s %X %X\n", luaName, luaFunc, Dword(luaFunc));
if((dwRet = RenameFunc(Dword(luaFunc), form("Script_%s", luaName))) == 0)
Message("Failed to rename 0x%08X to %s\n", Dword(luaFunc), luaName);
else
counter++;
}
}
}
// Live client 4.0.1.13164, seems work with PTR too
x = FindBinary(0, SEARCH_DOWN, "55 8B EC 56 33 F6 39 75 10 7E ? 53 8B 5D 0C 57 8B 7D 08 8B 04 F3 50 57 E8 ? ? ? ? 8B 4C F3");
if(x == BADADDR)
{
Message("Can't find FrameScript::FillScriptMethodTable, aborting...\n");
return -1;
}
Message("FrameScript::FillScriptMethodTable found at: %X\n", x);
for(y = RfirstB(x); y != BADADDR; y = RnextB(x, y))
{
auto offset, classCount;
offset = GetOperandValue(y - 6, 0);
count = GetOperandValue(y - 8, 0);
//Message("%X %X %i\n", y, offset, count);
for(i = 0; i < count; ++i)
{
luaName = GetString(Dword(offset + (i * 8)), -1, ASCSTR_C);
luaFunc = Dword(offset + (i * 8) + 4);
//Message("%s %X\n", luaName, luaFunc);
// those functions belong to some FrameScript object class, but we don't know which one...
if((dwRet = RenameFunc(luaFunc, form("Script_%s_class%i", luaName, classCount))) == 0)
Message("Failed to rename 0x%08X to %s\n", luaFunc, luaName);
else
counter++;
}
classCount++;
}
// Live client 3.2.2.10505
x = FindBinary(0, SEARCH_DOWN, "55 8B EC 8B 45 10 8B 4D 0C 8B 55 08 6A 00 50 51 52 E8 ? ? ? ? 83 C4 10 5D C3 ? ? ? ? ?");
if(x == BADADDR)
{
Message("Can't find RegisterLuaApi, aborting...\n");
return -1;
}
Message("RegisterLuaApi found at: %X\n", x);
for(y = RfirstB(x); y != BADADDR; y = RnextB(x, y))
{
offset = ReadPushOperand(y - 11, "offset");
luaGlobal = GetString(ReadPushOperand(y - 1, "offset"), -1, ASCSTR_C);
Message("%X %X %s\n", y, offset, luaGlobal);
i = 0;
while((luaFunc = Dword(offset + (i * 8) + 4)) != 0 && (luaName = GetString(Dword(offset + (i * 8)), -1, ASCSTR_C)) != "")
{
Message("%s %X\n", luaName, luaFunc);
if((dwRet = RenameFunc(luaFunc, form("LuaApi_%s::%s", luaGlobal, luaName))) == 0)
Message("Failed to rename 0x%08X to %s\n", luaFunc, luaName);
else
counter++;
i++;
}
}
Message("Successfully renamed %i lua functions!\n", counter);
return 0;
}
static ReadPushOperand( xref, filter )
{
do
{
auto disasm;
disasm = GetDisasm( xref );
if ( strstr( disasm, "push" ) > -1 && strstr( disasm, filter ) > -1 )
break;
xref = PrevHead( xref, PrevFunction( xref ) );
} while ( 1 );
return GetOperandValue( xref, 0 );
}