Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Копаем клиент (http://mangos.ytdb.ru/forumdisplay.php?f=35)
-   -   creaturecache.wdb (http://mangos.ytdb.ru/showthread.php?t=7761)

Konctantin 06.12.2013 10:57

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

получилось пока что следующее:
эта функция всего-то читает 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

Цитата:

Сообщение от Konctantin (Сообщение 32283)
Ладно фиг с ним, сделал так:
Код:

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

Вложений: 1
Цитата:

и получаем мусор
Цитата:

там тоже было такое чтение строк и странные операции с длиной строки
ну судя по тому что я отреверсил, то получается так:
Код:

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

Цитата:

Сообщение от Konctantin (Сообщение 32293)
Можете дать адрес обработчика? интересно покопаться.

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

Цитата:

Сообщение от Konctantin (Сообщение 32298)
это что получается сюда они запихнули все обработчики?
Код:

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


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

ru-mangos.ru - Русское сообщество MaNGOS