PDA

Просмотр полной версии : creaturecache.wdb


Konctantin
06.12.2013, 10:57
Разбираю структуру "creaturecache.wdb", вот исходная функция:

bool __thiscall sub_75CE08(void *this, int a2, unsigned int a3)
{
int v3; // esi@1
unsigned int v5; // eax@5
unsigned int v6; // eax@6
int v7; // ecx@6
unsigned int v8; // eax@7
int v9; // ecx@7
int v10; // ecx@9
int v11; // edi@11
int v12; // ecx@15
bool v13; // zf@15
int v14; // eax@16
int v15; // eax@16
int v16; // ecx@17
int v17; // ecx@19
__int128 v18; // xmm0@20
int v19; // eax@21
char v20; // ST08_1@21
unsigned int v21; // eax@25
int v22; // eax@28
int v23; // [sp+Ch] [bp-18h]@1
__int16 v24; // [sp+10h] [bp-14h]@1
int v25; // [sp+14h] [bp-10h]@7
int v26; // [sp+18h] [bp-Ch]@6
int v27; // [sp+1Ch] [bp-8h]@1
int i; // [sp+20h] [bp-4h]@5

v23 = a2;
LOBYTE(v27) = 0;
v3 = (int)this;
v24 = 2048;
*(_DWORD *)(v3 + 4) ^= (unsigned int)&unk_FFFFFF & (CDataStore__Read11Bits((int)&v23, v27) ^ *(_DWORD *)(v3 + 4));
if ( ((unsigned int)&unk_FFFFFF & *(_DWORD *)(v3 + 4)) <= 0x400 )
{
LOBYTE(v27) = 0;
*(_DWORD *)(v3 + 12) ^= (unsigned int)&unk_FFFFFF & (CDataStore__Read11Bits((int)&v23, v27) ^ *(_DWORD *)(v3 + 12));
if ( ((unsigned int)&unk_FFFFFF & *(_DWORD *)(v3 + 12)) <= 0x400 )
{
LOBYTE(v27) = 0;
*(_DWORD *)(v3 + 20) ^= (unsigned int)&unk_FFFFFF & (CDataStore__Read6Bits((int)&v23, v27) ^ *(_DWORD *)(v3 + 20));
if ( ((unsigned int)&unk_FFFFFF & *(_DWORD *)(v3 + 20)) <= 0x20 )
{
v5 = CDataStore__ReadBit((int)&v23);
v27 = 0;
*(_BYTE *)(v3 + 44) = v5 != 0;
i = v3 + 144;
while ( 1 )
{
LOBYTE(v26) = 0;
v6 = CDataStore__Read11Bits((int)&v23, v26);
v7 = i;
*(_DWORD *)(v7 - 32) ^= (unsigned int)&unk_FFFFFF & (v6 ^ *(_DWORD *)(i - 32));
if ( ((unsigned int)&unk_FFFFFF & *(_DWORD *)(v7 - 32)) > 0x401 )
break;
LOBYTE(v25) = 0;
v8 = CDataStore__Read11Bits((int)&v23, v25);
v9 = i;
*(_DWORD *)v9 ^= (unsigned int)&unk_FFFFFF & (v8 ^ *(_DWORD *)i);
if ( ((unsigned int)&unk_FFFFFF & *(_DWORD *)v9) > 0x401 )
break;
++v27;
i = v9 + 8;
if ( (unsigned int)v27 >= 4 )
{
v27 = 0;
v10 = v3 + 108;
for ( i = v3 + 108; ; v10 = i )
{
v11 = a2;
if ( !sub_A45DED(v10, a2, (unsigned int)&unk_FFFFFF & *(_DWORD *)(v10 + 4), a3) )// read string ???
break;
if ( !sub_A45DED(i + 32, v11, (unsigned int)&unk_FFFFFF & *(_DWORD *)(i + 36), a3) )
break;
++v27;
i += 8;
if ( (unsigned int)v27 >= 4 )
{
a2 = v3 + 76;
i = 2;
do
{
v27 = 0;
CDataStore__GetInt32(v11, (int)&v27);
v12 = a2;
a2 += 4;
v13 = i-- == 1;
*(_DWORD *)v12 = v27;
}
while ( !v13 );
a2 = 0;
CDataStore__GetInt32(v11, (int)&a2);
v14 = a2;
a2 = 0;
*(_DWORD *)(v3 + 24) = v14;
CDataStore__GetInt32(v11, (int)&a2);
v15 = a2;
a2 = 0;
*(_DWORD *)(v3 + 28) = v15;
CDataStore__GetInt32(v11, (int)&a2);
*(_DWORD *)(v3 + 32) = a2;
a2 = v3 + 84;
i = 2;
do
{
v27 = 0;
CDataStore__GetInt32(v11, (int)&v27);
v16 = a2;
a2 += 4;
v13 = i-- == 1;
*(_DWORD *)v16 = v27;
}
while ( !v13 );
a2 = v3 + 92;
i = 4;
do
{
v27 = 0;
CDataStore__GetInt32(v11, (int)&v27);
v17 = a2;
a2 += 4;
v13 = i-- == 1;
*(_DWORD *)v17 = v27;
}
while ( !v13 );
a2 = 0;
CDataStore__GetFloat(v11, (int)&a2);
*(_DWORD *)(v3 + 36) = a2;
a2 = 0;
CDataStore__GetFloat(v11, (int)&a2);
v18 = (unsigned int)a2;
a2 = 0;
*(_DWORD *)(v3 + 40) = v18;
CDataStore__GetInt32(v11, (int)&a2);
if ( *(_DWORD *)(v11 + 16) - *(_DWORD *)(v11 + 20) < (unsigned int)(4 * a2)
|| (CDataStore__Write22Bits_0(v3 + 48, a2),
a2 = 0,
CDataStore__GetInt32(v11, (int)&a2),
v19 = a2,
a2 = 0,
*(_DWORD *)(v3 + 68) = v19,
CDataStore__GetInt32(v11, (int)&a2),
v20 = a3,
*(_DWORD *)(v3 + 72) = a2,
!sub_A45DED(v3, v11, (unsigned int)&unk_FFFFFF & *(_DWORD *)(v3 + 4), v20))
|| !sub_A45DED(v3 + 8, v11, (unsigned int)&unk_FFFFFF & *(_DWORD *)(v3 + 12), a3)
|| !sub_A45DED(v3 + 16, v11, (unsigned int)&unk_FFFFFF & *(_DWORD *)(v3 + 20), a3) )
return 0;
a3 = 0;
while ( 1 )
{
v21 = *(_DWORD *)(v3 + 64);
if ( v21 == -1 )
v21 = *(_DWORD *)(v3 + 48);
if ( a3 >= v21 )
break;
a2 = 0;
CDataStore__GetInt32(v11, (int)&a2);
v22 = sub_7DA455(v3 + 48, a3++);
*(_DWORD *)v22 = a2;
}
return (*(int (__thiscall **)(int))(*(_DWORD *)v11 + 20))(v11) && sub_75BF7E(v3);
}
}
return 0;
}
}
}
}
}
return 0;
}

получилось следующее:

int()
xor_int(11) //[1]
xor_int(11) //[2]
xor_int(6) //[3]

bit()

while(4)
xor_int(11) // [1,i]
xor_int(11) // [2,i]

while(4)
read_unk_str(/*[1,i]*/)
read_unk_str(/*[2,i]*/)

int()
int()
int()
int()
int()
int()
int()
int()
int()
int()
int()
float()
float()
int()
int()
int()
read_unk_str(/*[1]*/)
read_unk_str(/*[2]*/)
read_unk_str(/*[3]*/)

while(???)
int()

Собственно завис пока на функции read_unk_str (sub_A45DED)
скорее всего эта функция считывает строку с размером, который ранее был прочитан и за'xor'ен, что-то в этом роде:
*(_DWORD *)(v3 + 4) ^= (unsigned int)&unk_FFFFFF & (CDataStore__Read11Bits((int)&v23, v27) ^ *(_DWORD *)(v3 + 4));
размер строки получается в виде len(str) + 1

char __thiscall sub_A45DED(int this, int a2, int a3, char a4)
{
int v4; // edi@1
int v5; // esi@1

v4 = a3;
v5 = this;
if ( a3 )
{
if ( a3 == 1 )
{
*(_DWORD *)(this + 4) &= 0xFE000000u;
*(_DWORD *)this = &unk_D115FF;
}
else
{
CDataStore__GetData(a2, (int)&a3, a3);
if ( !a3 || *(_BYTE *)(v4 - 1 + a3) )
return 0;
if ( a4 )
{
*(_DWORD *)v5 = a3;
*(_DWORD *)(v5 + 4) = *(_DWORD *)(v5 + 4) & 0xFE000000 | (unsigned int)&unk_FFFFFF & (v4 - 1);
}
else
{
sub_A45D2C((void *)v5, a3, v4 - 1);
}
}
}
return 1;
}

Собственно вопрос, что делает эта функция?
Ибо если просто считывать как строку, то поля сдвигаются и дальше идут не верные значения.

Konctantin
07.12.2013, 11:02
получилось пока что следующее:
эта функция всего-то читает cшную строку без последнего символа (\0) по размеру считанному выше.

internal string ReadString2(int m_size)
{
if (this.RemainigLength < m_size)
throw new ArgumentOutOfRangeException("m_size");

var size = m_size > 0 ? m_size - 1 : 0;
var str = Encoding.UTF8.GetString(buffer, index, size);
index += m_size;
return str;
}

но пока что смущает этот кусок:

while ( 1 )
{
v21 = *(_DWORD *)(v3 + 64);
if ( v21 == -1 )
v21 = *(_DWORD *)(v3 + 48);
if ( a3 >= v21 )
break;
a2 = 0;
CDataStore__GetInt32(v11, (int)&a2);
v22 = sub_7DA455(v3 + 48, a3++);
*(_DWORD *)v22 = a2;
}

на сколько мне понятно, тут считывается 4 байта до тех пор пока не наступит конец потока, но остаток не всегда кратное 4
0 1 4 5 8 12 16 20

Konctantin
07.12.2013, 11:21
Ладно фиг с ним, сделал так:

while (red.RemainigLength >= 4)
questItems.Add(red.ReadInt32());

Хотя там и оставался 1 непрочитанный байт, но он все равно равен 0.

ЗЫ. Думаю тему можно закрыть.

Amaru
07.12.2013, 15:51
Ладно фиг с ним, сделал так:

while (red.RemainigLength >= 4)
questItems.Add(red.ReadInt32());

Хотя там и оставался 1 непрочитанный байт, но он все равно равен 0.

ЗЫ. Думаю тему можно закрыть.и получаем мусор

Konctantin
07.12.2013, 16:41
и получаем мусор
да нет, я проверил данные получаются нормальные, а вот за что отвечает тот байт - не понятно.
RemainigLength
тьфу ошибка.

Amaru
07.12.2013, 18:30
я когда разбирал сниф 5.4.0, нормально разбирались только пакеты буржуйские пакеты, на пакетах с русскими строками вываливались ошибки
там тоже было такое чтение строк и странные операции с длиной строки

Konctantin
09.12.2013, 10:14
и получаем мусор
там тоже было такое чтение строк и странные операции с длиной строки
ну судя по тому что я отреверсил, то получается так:
char __thiscall CDataStore__GetSizedString2(int this, int a2, int a3, char a4)
{
int v4; // edi@1
int v5; // esi@1

v4 = a3;
v5 = this;
if ( a3 )
{
if ( a3 == 1 ) // ответ на вопрос с лишним байтом
{
*(_DWORD *)(this + 4) &= 0xFE000000u;
*(_DWORD *)this = &unk_D115FF;
}
else
{
CDataStore__GetData(a2, (int)&a3, a3);
if ( !a3 || *(_BYTE *)(v4 - 1 + a3) )
return 0;
if ( a4 )
{
*(_DWORD *)v5 = a3;
*(_DWORD *)(v5 + 4) = *(_DWORD *)(v5 + 4) & 0xFE000000 | (unsigned int)&unk_FFFFFF & (v4 - 1);
}
else
{
sub_A45D2C((void *)v5, a3, v4 - 1);
}
}
}
return 1;
}
сделал так:

public string ReadString2(int m_size)
{
if (m_size <= 1)
return string.Empty;

var str = Encoding.UTF8.GetString(buffer, index, m_size - 1);
index += (int)m_size;
return str;
}

в итоге все прочиталось без мусора,
прикладываю исходники

Konctantin
09.12.2013, 11:18
// entry = wdb_stream.ReadInt32();
int subname_len = (int)reader.ReadUInt32(11);
int unk_text_len = (int)reader.ReadUInt32(11);
int icon_name_len = (int)reader.ReadUInt32(6);

var unk_bit = reader.ReadBit() ? 1 : 0; // ???

int[] names_len = new int[4];
int[] unk_name_len = new int[4];
string[] names = new string[4];
string[] unk_names = new string[4];

for (int i2 = 0; i2 < 4; ++i2)
{
names_len[i2] = (int)reader.ReadUInt32(11);// name size
unk_name_len[i2] = (int)reader.ReadUInt32(11);// unk size
}

for (int i2 = 0; i2 < 4; ++i2)
{
names[i2] = reader.ReadEsqapedSqlString2(names_len[i2]);//name
unk_names[i2] = reader.ReadEsqapedSqlString2(unk_name_len[i2]);//unk str
}

var flag = reader.ReadUInt32(); // flag
var type_flag = reader.ReadInt32(); // type flag

var family = reader.ReadInt32(); // family
var rank = reader.ReadInt32(); // rank
var recial_leader = reader.ReadInt32();

var kill_kredit1 = reader.ReadInt32(); // kill kredit 1
var kill_kredit2 = reader.ReadInt32(); // kill kredit 2

var modelid1 = reader.ReadInt32();
var modelid2 = reader.ReadInt32();
var modelid3 = reader.ReadInt32();
var modelid4 = reader.ReadInt32();

var HealthModifier = reader.ReadFloat();
var PowerModifier = reader.ReadFloat();

var quest_item_count = reader.ReadInt32();
var movement_id = reader.ReadInt32(); // movement id ???
var unk2 = reader.ReadInt32(); // unk ???

var sub_name = reader.ReadEsqapedSqlString2(subname_len);
var unk_text = reader.ReadEsqapedSqlString2(unk_text_len);
var icon_name = reader.ReadEsqapedSqlString2(icon_name_len);

int[] QuestItem = new int[6];
for (int i = 0; i < quest_item_count; ++i)
QuestItem[i] = reader.ReadInt32();

Amaru
10.12.2013, 05:50
Как все красиво в кэше
в хендлере пакета идет вот так

[Parser(Opcode.SMSG_CREATURE_QUERY_RESPONSE)]
public static void HandleCreatureQueryResponse(Packet p)
{
var entry = p.ReadUInt32("Entry");
var hasData = p.ReadBit("Has Data");

var maleLen = new uint[4];
var femaleLen = new uint[4];
var subNameLen = 0u;
var unk505Len = 0u;
var iconNameLen = 0u;
var questItemCount = 0u;
if (hasData)
{
for (var i = 0; i < 4; ++i)
{
maleLen[i] = p.ReadBits(11);
femaleLen[i] = p.ReadBits(11);
}
questItemCount = p.ReadBits(22);
iconNameLen = p.ReadBits("Icon name size", 6);
subNameLen = p.ReadBits("Sub name size", 11);
unk505Len = p.ReadBits("unk505 len", 11);
p.ReadBit("Is racial leader");
}
if (hasData)
{
p.ReadInt32("Type");
p.ReadInt32("Kill Credit 1");
p.ReadInt32("Model Id 4");
p.ReadInt32("Model Id 3");

for (var i = 0; i < questItemCount; ++i)
p.ReadInt32("Quest Item", i);

p.ReadInt32("Expansion Unk");

for (var i = 0; i < 4; ++i)
{
if (femaleLen[i] > 1)
p.ReadCString("Name Female", i);
if (maleLen[i] > 1)
p.ReadCString("Name Male", i);
}

if (unk505Len > 1)
p.ReadCString("Unk505");

p.ReadSingle("Mana Mod");
p.ReadInt32("Model Id 1");
if (iconNameLen > 1)
p.ReadCString("Icon Name");
p.ReadInt32("Kill Credit 0");
p.ReadInt32("Model Id 2");
if (subNameLen > 1)
p.ReadCString("Subname");
for (var i = 0; i < 2; ++i)
p.ReadUInt32("Type Flags", i);
p.ReadSingle("Health Mod");
p.ReadInt32("Family");
p.ReadInt32("Rank");
p.ReadInt32("Movement Id");
}
}причем близы, если строка пустая, шлют либо 0 либо 1 рандомом, строки всегда null-terminated

Konctantin
10.12.2013, 07:56
причем близы, если строка пустая, шлют либо 0 либо 1 рандомом, строки всегда null-terminated
вот так же и в кеше, строки null-terminated но приходит из размер и если размер больше 1, тогда двигаем курсор и читаем данные.

Konctantin
12.12.2013, 09:51
в хендлере пакета идет вот так
Можете дать адрес обработчика? интересно покопаться.

Konctantin
12.12.2013, 10:01
Где-то видел скрипт для IDA для переименования Lua функций, но не могу найти.
Если у кого есть, поделитесь пожалуйста, а то вручную долго это делать, а ума написать свой скрипт - не хватает.

Amaru
12.12.2013, 11:16
Можете дать адрес обработчика? интересно покопаться.
17538
0x7108B9

Konctantin
12.12.2013, 12:22
это что получается сюда они запихнули все обработчики?
char __thiscall sub_78D225(void *this, int a2, int a3, int a4)
{
int v4; // esi@1
int v5; // ebx@1
unsigned int v6; // edi@1
char result; // al@2
unsigned int v8; // eax@11
int v9; // ecx@12
unsigned int dwOpcode; // [sp+Ch] [bp-4h]@1

++dword_108D6D4;
v4 = (int)this;
CDataStore__GetInt32(a3, (int)&dwOpcode); // opcode
v5 = dwOpcode & 0x244;
v6 = dwOpcode;
if ( (dwOpcode & 0x244) == 4 )
{
result = sub_65261C(v4, v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x276) == 80 )
{
result = sub_687488(v4, v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x1240) == 512 )
{
result = sub_C68651(v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x1244) == 580 )
{
result = sub_6880A4(v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x252) == 64 )
{
result = sub_C4B8A2(v4, 0, a2, dwOpcode, a3);
}
else
{
(*(void (__thiscall **)(int, unsigned int))(*(_DWORD *)v4 + 68))(v4, dwOpcode);
v8 = v6 & 3 | ((v6 & 0x38 | ((v6 & 0x180 | (v6 >> 1) & 0x7E00) >> 1)) >> 1);
if ( v5 || (v9 = *(_DWORD *)(v4 + 4 * v8 + 1360)) == 0 )
result = (*(int (**)(void))(*(_DWORD *)a3 + 24))();
else
result = ((int (__cdecl *)(_DWORD, unsigned int, int, int))(v9
- ((v6 | (v6 << 16)) ^ 0x62A3A31D)))(
*(_DWORD *)(v4 + 4 * v8 + 9552),
v6,
a2,
a3);
}
}
}
}
}
return result;
}

Konctantin
12.12.2013, 12:27
давно не смотрел в то что делается в клиенте, но это же просто пипец какой-то, это что они там такого курят?char __thiscall sub_724F6A(int this, int a2, int a3)
{
int v3; // esi@1
unsigned int v4; // eax@1
int v5; // eax@1
unsigned int v6; // edi@7
int v8; // [sp+Ch] [bp-10h]@1
__int16 v9; // [sp+10h] [bp-Ch]@1
int v10; // [sp+14h] [bp-8h]@1
char v11; // [sp+1Bh] [bp-1h]@2

v3 = this;
v8 = a2;
v9 = 2048;
*(_BYTE *)(this + 17) = CDataStore__ReadBit((int)&v8);
LOBYTE(v10) = 0;
v4 = CDataStore__Read21Bits(&v8, v10);
sub_71F448((void *)(v3 + 24), v4);
*(_BYTE *)(v3 + 19) = CDataStore__ReadBit((int)&v8);
*(_BYTE *)(v3 + 22) = CDataStore__ReadBit((int)&v8);
*(_BYTE *)(v3 + 16) = CDataStore__ReadBit((int)&v8);
*(_BYTE *)(v3 + 20) = CDataStore__ReadBit((int)&v8);
*(_BYTE *)(v3 + 18) = CDataStore__ReadBit((int)&v8);
*(_BYTE *)(v3 + 21) = CDataStore__ReadBit((int)&v8);
LOBYTE(v5) = CDataStore__ReadBit((int)&v8);
*(_BYTE *)(v3 + 23) = v5;
if ( *(_BYTE *)(v3 + 17) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 17) ^= v11;
}
if ( *(_BYTE *)(v3 + 18) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 18) ^= v11;
}
if ( *(_BYTE *)(v3 + 16) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 16) ^= v11;
}
v6 = 0;
if ( *(_DWORD *)(v3 + 24) > 0u )
{
do
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
*(_BYTE *)(*(_DWORD *)(v3 + 28) + 8 * v6 + 4) = v11;
v10 = 0;
CDataStore__GetInt32(a2, (int)&v10);
v5 = *(_DWORD *)(v3 + 28);
*(_DWORD *)(v5 + 8 * v6++) = v10;
}
while ( v6 < *(_DWORD *)(v3 + 24) );
}
if ( *(_BYTE *)(v3 + 23) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 23) ^= v11;
}
if ( *(_BYTE *)(v3 + 20) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 20) ^= v11;
}
if ( *(_BYTE *)(v3 + 21) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 21) ^= v11;
}
if ( *(_BYTE *)(v3 + 22) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 22) ^= v11;
}
if ( *(_BYTE *)(v3 + 19) )
{
v11 = 0;
CDataStore__GetInt8(a2, (int)&v11);
LOBYTE(v5) = v11;
*(_BYTE *)(v3 + 19) ^= v11;
}
return v5;
}

Amaru
12.12.2013, 12:31
это что получается сюда они запихнули все обработчики?
char __thiscall sub_78D225(void *this, int a2, int a3, int a4)
{
int v4; // esi@1
int v5; // ebx@1
unsigned int v6; // edi@1
char result; // al@2
unsigned int v8; // eax@11
int v9; // ecx@12
unsigned int dwOpcode; // [sp+Ch] [bp-4h]@1

++dword_108D6D4;
v4 = (int)this;
CDataStore__GetInt32(a3, (int)&dwOpcode); // opcode
v5 = dwOpcode & 0x244;
v6 = dwOpcode;
if ( (dwOpcode & 0x244) == 4 )
{
result = sub_65261C(v4, v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x276) == 80 )
{
result = sub_687488(v4, v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x1240) == 512 )
{
result = sub_C68651(v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x1244) == 580 )
{
result = sub_6880A4(v4, 0, a2, dwOpcode, a3);
}
else
{
if ( (dwOpcode & 0x252) == 64 )
{
result = sub_C4B8A2(v4, 0, a2, dwOpcode, a3);
}
else
{
(*(void (__thiscall **)(int, unsigned int))(*(_DWORD *)v4 + 68))(v4, dwOpcode);
v8 = v6 & 3 | ((v6 & 0x38 | ((v6 & 0x180 | (v6 >> 1) & 0x7E00) >> 1)) >> 1);
if ( v5 || (v9 = *(_DWORD *)(v4 + 4 * v8 + 1360)) == 0 )
result = (*(int (**)(void))(*(_DWORD *)a3 + 24))();
else
result = ((int (__cdecl *)(_DWORD, unsigned int, int, int))(v9
- ((v6 | (v6 << 16)) ^ 0x62A3A31D)))(
*(_DWORD *)(v4 + 4 * v8 + 9552),
v6,
a2,
a3);
}
}
}
}
}
return result;
}
да, это они, родимые :D

Konctantin
15.12.2013, 17:37
Скрипт для переименования Lua функций:
Завтра приду на работу проверю работоспособность.

typedef char* string;
#include <idc.idc>

static long getRegisterFunction()
{
string str = "";
auto dwAddress = 0;

dwAddress = FindBinary(dwAddress + 1, SEARCH_DOWN|SEARCH_NEXT, "\"Usage: SetCharCustomizeFrame\"");
//Message("dwAddress %x\n", dwAddress);
dwAddress = DfirstB(DfirstB(PrevFunction(DfirstB(dwAddress)))) +0xE;
str = GetOpnd (dwAddress,0);

if(IsAddrStartOfFunction(LocByName(str)) == 0)
return -1;

RenameFunc(LocByName(str), "RegisterScriptFunction");
return LocByName(str);
}

static long main()
{
string prefix = "Script_";
long dwAddress, nameptr, maxentries;
long dwRegisterFunction;
string name,fname;
long i;
dwRegisterFunction = getRegisterFunction();
//Message("dwRegisterFunction = %x\n", dwRegisterFunction);
if(dwRegisterFunction == -1)
return;

dwAddress = 0;

while (dwAddress != BADADDR)
{
dwAddress = RnextB (dwRegisterFunction, dwAddress);
//Message("dwAddress %x\n", dwAddress);
nameptr = GetNamesPtrFromAdr(dwAddress);
//Message("nameptr %x\n", nameptr);
maxentries = Dword(dwAddress + 0xD);
for (i=0;i<maxentries/8;i++)
{
name = GetString(Dword(nameptr), -1, ASCSTR_C);
//Message("name %s\n", name);

if(strlen(name) < 4)
break;
if(IsAddrStartOfFunction(Dword(nameptr+4)) == 0)
break;
fname = prefix + name;
Message("%x : %s%s\n", Dword(nameptr+4), prefix, name);

if (RenameFunc(Dword(nameptr+4), fname) == 0)
break;
nameptr = nameptr + 8;
}
}
Message("Done.\n");
}

static long GetNamesPtrFromAdr(long adr)
{
long dwRet;
dwRet = adr - 0x10 + 0x4;
return (Dword(dwRet) - 4);
}

// 1 = Success, 0 = Failure
static long RenameFunc(long dwAddress, string sFunction)
{
long dwRet;
if(hasUserName(GetFlags(dwAddress)))
{
Message("%x already has custom name %s... skipping\n", dwAddress, Name(dwAddress));
return 1;
}

dwRet = MakeNameEx(dwAddress, sFunction, SN_NOCHECK);

if(dwRet == 0)
{
string sTemp;
long i;
for(i = 0; i < 32; i++)
{
sTemp = form("%s_%i", sFunction, i);

if((dwRet = MakeNameEx(dwAddress, sTemp, SN_NOCHECK)) != 0)
{
Message("Info: Renamed to %s instead of %s\n", sTemp, sFunction);
break;
}
}
}
return dwRet;
}

static long IsAddrStartOfFunction(long addr)
{
if(GetFunctionAttr(addr, FUNCATTR_START) == addr)
return 1;
return 0;
}

Amaru
16.12.2013, 10:59
у меня смутное чувство, что он не все найдет скрипты
сейчас не единый массив объявлялок, а несколько, они разнесены по разным местам

TOM_RUS
16.12.2013, 22:41
Я вот такой скрипт раньше юзал для переименования lua скритп функций: http://paste2.org/PGvInAsW


#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 );
}



И вообще может кому пригодится: http://fbe.am/pEj