06.12.2013, 10:57 | #1 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
creaturecache.wdb
Разбираю структуру "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() скорее всего эта функция считывает строку с размером, который ранее был прочитан и за'xor'ен, что-то в этом роде: Код:
*(_DWORD *)(v3 + 4) ^= (unsigned int)&unk_FFFFFF & (CDataStore__Read11Bits((int)&v23, v27) ^ *(_DWORD *)(v3 + 4)); Код:
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; } Ибо если просто считывать как строку, то поля сдвигаются и дальше идут не верные значения. |
07.12.2013, 11:02 | #2 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
получилось пока что следующее:
эта функция всего-то читает 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; } Код:
0 1 4 5 8 12 16 20 |
07.12.2013, 11:21 | #3 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Ладно фиг с ним, сделал так:
Код:
while (red.RemainigLength >= 4) questItems.Add(red.ReadInt32()); ЗЫ. Думаю тему можно закрыть. Последний раз редактировалось Konctantin; 07.12.2013 в 11:26. |
07.12.2013, 15:51 | #4 |
MaNGOS Dev
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
|
|
07.12.2013, 16:41 | #5 | ||
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Цитата:
Цитата:
|
||
07.12.2013, 18:30 | #6 |
MaNGOS Dev
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
|
я когда разбирал сниф 5.4.0, нормально разбирались только пакеты буржуйские пакеты, на пакетах с русскими строками вываливались ошибки
там тоже было такое чтение строк и странные операции с длиной строки Последний раз редактировалось Amaru; 07.12.2013 в 18:33. |
09.12.2013, 10:14 | #7 | ||
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Цитата:
Цитата:
Код:
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 в 10:32. |
||
3 пользователя(ей) сказали cпасибо: |
09.12.2013, 11:18 | #8 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Код:
// 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(); |
10.12.2013, 05:50 | #9 |
MaNGOS Dev
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
|
Как все красиво в кэше
в хендлере пакета идет вот так Код:
[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"); } } Последний раз редактировалось Amaru; 10.12.2013 в 05:55. |
10.12.2013, 07:56 | #10 | |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Цитата:
|
|
12.12.2013, 10:01 | #12 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Где-то видел скрипт для IDA для переименования Lua функций, но не могу найти.
Если у кого есть, поделитесь пожалуйста, а то вручную долго это делать, а ума написать свой скрипт - не хватает. |
12.12.2013, 11:16 | #13 |
MaNGOS Dev
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
|
|
Пользователь сказал cпасибо: | Konctantin (12.12.2013) |
12.12.2013, 12:22 | #14 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
это что получается сюда они запихнули все обработчики?
Код:
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; } |
12.12.2013, 12:27 | #15 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
давно не смотрел в то что делается в клиенте, но это же просто пипец какой-то, это что они там такого курят?
Код:
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; } |
12.12.2013, 12:31 | #16 | |
MaNGOS Dev
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
|
Цитата:
|
|
15.12.2013, 17:37 | #17 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Скрипт для переименования 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; } |
16.12.2013, 10:59 | #18 |
MaNGOS Dev
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
|
у меня смутное чувство, что он не все найдет скрипты
сейчас не единый массив объявлялок, а несколько, они разнесены по разным местам |
16.12.2013, 22:41 | #19 |
MaNGOS Dev
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
|
Я вот такой скрипт раньше юзал для переименования 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 ); } Последний раз редактировалось TOM_RUS; 16.12.2013 в 22:54. |
Пользователь сказал cпасибо: | Amaru (17.12.2013) |