Показать сообщение отдельно
Старый 22.01.2014, 01:21   #4
Fabian
Новичок
 
Регистрация: 02.07.2010
Сообщений: 23
Сказал(а) спасибо: 2
Поблагодарили 20 раз(а) в 12 сообщениях
Fabian На верном пути
По умолчанию

The old handlers will be removed step by step.
I guess only round about 35?! are left and they will be replaced with the jam opcode functions.

The same for client messages. They are replaced step by step with the jam opcode functions which is just another handler definition.

Код:
        public static uint JAMClientDispatch(uint value)
        {
            if ((value & 0x1EF0) == 0)
                return value & 0xF | ((value & 0x100 | (value >> 4) & 0xE00) >> 4);

            if ((value & 0x1F54) == 768)
                return (value & 3 | ((value & 8 | ((value & 0x20 | (((value & 0x80) | (value >> 5) & 0x700) >> 1)) >> 1)) >> 1)) + 32;

            if ((value & 0x1C52) == 3072)
                return (value & 1 | ((value & 0xC | ((value & 0x20 | ((value & 0x380 | (value >> 3) & 0x1C00) >> 1)) >> 1)) >> 1)) + 64;

            if ((value & 0x15D8) == 64)
                return (value & 7 | ((value & 0x20 | ((value & 0x200 | ((value & 0x800 | (value >> 1) & 0x7000) >> 1)) >> 3)) >> 2)) + 192;

            if ((value & 0x11D8) == 72)
                return (value & 7 | ((value & 0x20 | ((value & 0xE00 | (value >> 1) & 0x7000) >> 3)) >> 2)) + 256;

            if ((value & 0x1D90) == 2064)
                return (value & 0xF | ((value & 0x60 | ((value & 0x200 | (value >> 3) & 0x1C00) >> 2)) >> 1)) + 384;

            if ((value & 0x1D90) == 2192)
                return 512 + (value & 0xF | ((value & 0x60 | (value & 0x200 | (value >> 3) & 0x1C00) >> 2) >> 1));
            else
            {
                if ((value & 0x1472) == 4162)
                    return (value & 1 | ((value & 0xC | ((value & 0x380 | ((value & 0x800 | (value >> 1) & 0x7000) >> 1)) >> 3)) >> 1)) + 640;

                return 768 + (value & 1 | ((value & 0xC | (value & 0x60 | ((value & 0x300 | ((value & 0x800 | (value >> 1) & 0x7000) >> 1)) >> 1)) >> 1) >> 1));
        }

        public static bool JamClientDispatchConditions(uint value)
        {
            if ((value & 0x1EF0) != 0 && (value & 0x1C52) != 3072 && (value & 0x15D8) != 64
                && (value & 0x11D8) != 72 && (value & 0x1F54) != 768 && (value & 0x1D90) != 2064
                && (value & 0x1D90) != 2192 && (value & 0x1472) != 4162 && (value & 0x1492) != 4114)
                return false;

            return true;
        }
Calculate a JamClientdispatch opcode to the case value:

Код:
var caseVal = JAMClientDispatch(opcode);
The other way calculating from case value to opcode:

Код:
            for (uint i = 0; i <= 0x1FFF; ++i)
                if (JamClientDispatchConditions(i) && JAMClientDispatch(i) == caseValue)
                    Console.WriteLine("NetMessage: {0}", i);
Then the legacy opcodes (the old way over index things...):

Код:
        public static uint ServerMessageCalc(uint value)
        {
            uint offset = value & 3 | ((value & 8 | ((value & 0x1E0 | (value >> 1) & 0x7E00) >> 1)) >> 1);
            return (offset * 4) + 0x550;
        }
And then the conditions from NetClient::ProcessMessage for it to get unique opcode values.

Here a little snippet for legacy opcode handlers:

Код:
            Memory.Initialize("WoW");

            var connectionPtr = Memory.Read<uint>(0xEA239C);
            var handlerPtr = 0u;
            var offset = 0u;

            List<uint> possibleOffsets = new List<uint>();
            List<uint> opcodeList = new List<uint>();
            List<uint> offsetList = new List<uint>();
            List<uint> handlerList = new List<uint>();

            for (uint i = 0; i <= 0x1FFF; ++i)
                if (IsLegacyMessage(i, offset) && (offset = LegacyMessageOffset(i)) != 0)
                    possibleOffsets.Add(offset);

            foreach (uint o in possibleOffsets)
            {
                if ((handlerPtr = Memory.Read<uint>((connectionPtr + o), false)) != 0)
                {
                    for (uint i = 0; i <= 0x1FFF; ++i)
                    {
                        if (IsLegacyMessage(i, o) && LegacyMessageOffset(i) == o)
                        {
                            offsetList.Add(o);
                            opcodeList.Add(i);

                            var handler = handlerPtr - ((i | (i << 16)) ^ 0x62A3A31D);
                            handler = (uint)(handler - Memory.BaseAddress + 0x400000);

                            handlerList.Add(handler);
                        }
                    }
                }
            }

            Memory.Dispose();

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < handlerList.Count; i++)
            {
                sb.AppendLine(String.Format("Offset:  {0}", offsetList[i]));
                sb.AppendLine(String.Format("Message{0} = 0x{1:X4},", i, opcodeList[i]));
                sb.AppendLine(String.Format("Handler: 0x{0:X}", handlerList[i]));
                sb.AppendLine();
            }

            using (StreamWriter sw = new StreamWriter("finished.txt"))
            {
                sw.WriteLine(sb.ToString());
                sw.Close();
            }

            Console.WriteLine("Legacy opcode dump finished");
            Console.ReadLine();
        }

Последний раз редактировалось Fabian; 22.01.2014 в 01:26.
Fabian вне форума   Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
crAwling (09.02.2014), Konctantin (21.05.2014)