Ru-MaNGOS

Вернуться   Ru-MaNGOS > Ядро > Опкоды, Формулы, Клиент > Копаем клиент

Важная информация

Копаем клиент Копаем клиент

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.12.2013, 10:57   #1
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию 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()
Собственно завис пока на функции 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   #2
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

получилось пока что следующее:
эта функция всего-то читает 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   #3
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Ладно фиг с ним, сделал так:
Код:
while (red.RemainigLength >= 4)
    questItems.Add(red.ReadInt32());
Хотя там и оставался 1 непрочитанный байт, но он все равно равен 0.

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

Последний раз редактировалось Konctantin; 07.12.2013 в 11:26.
Konctantin вне форума   Ответить с цитированием
Старый 07.12.2013, 15:51   #4
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
Ладно фиг с ним, сделал так:
Код:
while (red.RemainigLength >= 4)
    questItems.Add(red.ReadInt32());
Хотя там и оставался 1 непрочитанный байт, но он все равно равен 0.

ЗЫ. Думаю тему можно закрыть.
и получаем мусор
Amaru вне форума   Ответить с цитированием
Старый 07.12.2013, 16:41   #5
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Цитата:
и получаем мусор
да нет, я проверил данные получаются нормальные, а вот за что отвечает тот байт - не понятно.
Цитата:
RemainigLength
тьфу ошибка.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 07.12.2013, 18:30   #6
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

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

Последний раз редактировалось Amaru; 07.12.2013 в 18:33.
Amaru вне форума   Ответить с цитированием
Старый 09.12.2013, 10:14   #7
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Цитата:
и получаем мусор
Цитата:
там тоже было такое чтение строк и странные операции с длиной строки
ну судя по тому что я отреверсил, то получается так:
Код:
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;
}
в итоге все прочиталось без мусора,
прикладываю исходники
Вложения
Тип файла: rar WdbCreatureCacheReader.rar (11.7 Кб, 6 просмотров)
__________________

Последний раз редактировалось Konctantin; 09.12.2013 в 10:32.
Konctantin вне форума   Ответить с цитированием
3 пользователя(ей) сказали cпасибо:
Amaru (10.12.2013), blackmanos (11.12.2013), YuruY (10.12.2013)
Старый 09.12.2013, 11:18   #8
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Код:
// 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();
__________________
Konctantin вне форума   Ответить с цитированием
Старый 10.12.2013, 05:50   #9
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

Как все красиво в кэше
в хендлере пакета идет вот так
Код:
        [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

Последний раз редактировалось Amaru; 10.12.2013 в 05:55.
Amaru вне форума   Ответить с цитированием
Старый 10.12.2013, 07:56   #10
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Цитата:
причем близы, если строка пустая, шлют либо 0 либо 1 рандомом, строки всегда null-terminated
вот так же и в кеше, строки null-terminated но приходит из размер и если размер больше 1, тогда двигаем курсор и читаем данные.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 12.12.2013, 09:51   #11
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Цитата:
в хендлере пакета идет вот так
Можете дать адрес обработчика? интересно покопаться.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 12.12.2013, 10:01   #12
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Где-то видел скрипт для IDA для переименования Lua функций, но не могу найти.
Если у кого есть, поделитесь пожалуйста, а то вручную долго это делать, а ума написать свой скрипт - не хватает.
__________________
Konctantin вне форума   Ответить с цитированием
Старый 12.12.2013, 11:16   #13
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
Можете дать адрес обработчика? интересно покопаться.
17538
0x7108B9
Amaru вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Konctantin (12.12.2013)
Старый 12.12.2013, 12:22   #14
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

это что получается сюда они запихнули все обработчики?
Код:
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   #15
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

давно не смотрел в то что делается в клиенте, но это же просто пипец какой-то, это что они там такого курят?
Код:
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;
}
__________________
Konctantin вне форума   Ответить с цитированием
Старый 12.12.2013, 12:31   #16
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

Цитата:
Сообщение от Konctantin Посмотреть сообщение
это что получается сюда они запихнули все обработчики?
Код:
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;
}
да, это они, родимые
Amaru вне форума   Ответить с цитированием
Старый 15.12.2013, 17:37   #17
Konctantin
RuDB Dev
 
Аватар для Konctantin
 
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
Konctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всемKonctantin Это имя известно всем
По умолчанию

Скрипт для переименования 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;
}
__________________
Konctantin вне форума   Ответить с цитированием
Старый 16.12.2013, 10:59   #18
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

у меня смутное чувство, что он не все найдет скрипты
сейчас не единый массив объявлялок, а несколько, они разнесены по разным местам
Amaru вне форума   Ответить с цитированием
Старый 16.12.2013, 22:41   #19
TOM_RUS
MaNGOS Dev
 
Регистрация: 11.03.2010
Сообщений: 468
Сказал(а) спасибо: 0
Поблагодарили 514 раз(а) в 163 сообщениях
TOM_RUS Как свет с небесTOM_RUS Как свет с небесTOM_RUS Как свет с небесTOM_RUS Как свет с небесTOM_RUS Как свет с небесTOM_RUS Как свет с небес
По умолчанию

Я вот такой скрипт раньше юзал для переименования 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

Последний раз редактировалось TOM_RUS; 16.12.2013 в 22:54.
TOM_RUS вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
Amaru (17.12.2013)
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 15:16. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot