Beispiel #1
0
        public static void DumpDescriptors()
        {
            foreach (var p in Process.GetProcesses())
            {
                if (p.ProcessName == "Diablo III")
                {
                    Mem32 m = new Mem32(p);
                    GetMessageOpcodes(m);

                    DumpAttributes(m);

                    XDocument doc = new XDocument();
                    XElement root = new XElement("TypeDescriptors");
                    int hash = m[HashAddress].Ptr[HashOffset].Int32;
                    root.Add(new XAttribute("ProtocolHash", hash));

                    var descriptors = GetAllDescriptors(m);
                    foreach (var desc in descriptors)
                    {
                        root.Add(desc.ToXml());
                    }
                    doc.Add(root);

                    doc.Save("typedescriptors.xml");

                    m.Dispose();
                    DumpOpcodes(descriptors);
                    return;
                }
            }
            Console.WriteLine("Was unable to find any 'Diablo III' process.");
        }
Beispiel #2
0
        public static void DumpDescriptors()
        {
            foreach (var p in Process.GetProcesses())
            {
                if (p.ProcessName == "Diablo III")
                {
                    Mem32 m = new Mem32(p);
                    GetMessageOpcodes(m);
                    DumpAttributes(m);

                    XDocument doc  = new XDocument();
                    XElement  root = new XElement("TypeDescriptors");
                    int       hash = m[HashAddress].Ptr[HashOffset].Int32;
                    root.Add(new XAttribute("ProtocolHash", hash));

                    foreach (var desc in GetAllDescriptors(m))
                    {
                        root.Add(desc.ToXml());
                    }
                    doc.Add(root);

                    doc.Save("typedescriptors.xml");

                    m.Dispose();
                    return;
                }
            }
            Console.WriteLine("Was unable to find any 'Diablo III' process.");
        }
Beispiel #3
0
        static void GetMessageOpcodes(Mem32 m)
        {
            _gameMessageLookUp = new Dictionary <int, GameMessageInfo>();

            var func        = m[OpcodeSwitch_Address];
            int maxOpcode   = func[0x1B].Int32 + 1;
            int jaOffset    = func[0x21].Int32;
            int defaultCase = func.Offset + 0x25 + jaOffset;
            var switchTable = func[0x28].Ptr;

            for (int i = 0; i < maxOpcode; i++)
            {
                int caseOffset = switchTable[i * 4].Int32;
                if (caseOffset == defaultCase)
                {
                    continue;
                }

                int offTypeDescriptor = m[caseOffset + 2].Ptr.Int32;
                int size   = m[caseOffset + 13].Int32;
                int opcode = i + 1;

                GameMessageInfo gmi;
                if (_gameMessageLookUp.TryGetValue(offTypeDescriptor, out gmi))
                {
                    if (gmi.Size != size)
                    {
                        throw new Exception("Size mismatch.");
                    }
                }
                else
                {
                    gmi        = new GameMessageInfo();
                    gmi.Offset = offTypeDescriptor;
                    gmi.Size   = size;
                    _gameMessageLookUp.Add(offTypeDescriptor, gmi);
                }
                gmi.Opcodes.Add(opcode);
            }
        }
Beispiel #4
0
        static void GetMessageOpcodes(Mem32 m)
        {
            _gameMessageLookUp = new Dictionary<int, GameMessageInfo>();

            var func = m[OpcodeSwitch_Address];
            int maxOpcode = func[0x1B].Int32 + 1;
            int jaOffset = func[0x21].Int32;
            int defaultCase = func.Offset + 0x25 + jaOffset;
            var switchTable = func[0x28].Ptr;
            for (int i = 0; i < maxOpcode; i++)
            {
                int caseOffset = switchTable[i * 4].Int32;
                if (caseOffset == defaultCase)
                    continue;

                int offTypeDescriptor = m[caseOffset + 2].Ptr.Int32;
                int size = m[caseOffset + 13].Int32;
                int opcode = i + 1;

                GameMessageInfo gmi;
                if (_gameMessageLookUp.TryGetValue(offTypeDescriptor, out gmi))
                {
                    if (gmi.Size != size)
                        throw new Exception("Size mismatch.");
                }
                else
                {
                    gmi = new GameMessageInfo();
                    gmi.Offset = offTypeDescriptor;
                    gmi.Size = size;
                    _gameMessageLookUp.Add(offTypeDescriptor, gmi);
                }
                gmi.Opcodes.Add(opcode);
            }

        }
Beispiel #5
0
        static TypeDescriptor[] GetAllDescriptors(Mem32 mem)
        {
            Dictionary <int, TypeDescriptor> table = new Dictionary <int, TypeDescriptor>();
            var link  = mem[TypeDescriptorsAddress].Ptr;
            int count = 0;

            while (link.Int32 != 0)
            {
                if (table.ContainsKey(link.Offset) == false)
                {
                    var desc = DiscoverMessageDescriptors(mem, table, link.Offset);
                }
                count++;
                link = link[TypeDescriptorsOffset].Ptr;
            }

            var result = table.Values.ToArray();

            for (int i = 0; i < result.Length; i++)
            {
                result[i].Index = i;
            }
            return(result);
        }
Beispiel #6
0
        static void DumpAttributes(Mem32 mem)
        {
            // could get the max num from descriptor
            var attribList = mem[AttributesAddress];
            NetAttribute.Attributes = new NetAttribute[AttributeCount];
            for (int i = 0; i < AttributeCount; i++)
            {
                var attrib = attribList[i * 40];

                int id = attrib.Int32;
                int u2 = attrib[4].Int32;
                int u3 = attrib[8].Int32;
                int u4 = attrib[12].Int32;
                int u5 = attrib[16].Int32;

                string scriptA = attrib[20].CStringPtr;
                string scriptB = attrib[24].CStringPtr;
                string name = attrib[28].CStringPtr;
                var decoder = attrib[32].Ptr;
                byte u10 = attrib[36].Byte;
                switch (decoder.Int32)
                {
                    case Attribute_Int:
                        {
                            int bitCount = decoder[12].Int32;
                            NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.Int, u10, 0, 0, bitCount);
                            break;
                        }
                    case Attribute_IntMinMax:
                        {
                            int bitCount = decoder[20].Int32;
                            int min = decoder[12].Int32;
                            int max = decoder[16].Int32;
                            NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.IntMinMax, u10, min, max, bitCount);
                            break;
                        }
                    case Attribute_Float16: // Decode16BitFloat(bits)
                        {
                            int bitCount = decoder[12].Int32;
                            NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.Float16, u10, 0, 0, bitCount);
                        }
                        break;
                    case Attribute_Float16Or32:
                        {
                            NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.Float16Or32, u10, 0, 0, 0);
                        }
                        break;
                    case Attribute_FloatMinMax: // DecodeFloatMinMax
                        throw new Exception("FloatMinMax used");
                    default:
                        throw new Exception("Unknown decoder used");
                }
            }
            NetAttribute.SaveXml("attributes.xml");
        }
Beispiel #7
0
        static TypeDescriptor[] GetAllDescriptors(Mem32 mem)
        {
            Dictionary<int, TypeDescriptor> table = new Dictionary<int, TypeDescriptor>();
            var link = mem[TypeDescriptorsAddress].Ptr;
            int count = 0;
            while (link.Int32 != 0)
            {
                if (table.ContainsKey(link.Offset) == false)
                {
                    var desc = DiscoverMessageDescriptors(mem, table, link.Offset);
                }
                count++;
                link = link[TypeDescriptorsOffset].Ptr;
            }

            var result = table.Values.ToArray();
            for (int i = 0; i < result.Length; i++)
                result[i].Index = i;
            return result;

        }
Beispiel #8
0
        static TypeDescriptor DiscoverMessageDescriptors(Mem32 mem, Dictionary<int, TypeDescriptor> table, int offset)
        {
            if (offset == 0)
                return null;
            string name = mem[offset + 4].CStringPtr;
            int unkValue = mem[offset + 8].Int32;
            var fields = mem[offset + 12].Ptr;

            if (fields.Offset == 0)
            {
                var basicType = TypeDescriptor.AllocateBasicType(name);
                basicType.Name = name;
                basicType.UnkValue = unkValue;
                table.Add(offset, basicType);
                return basicType;
            }

            StructureTypeDescriptor typeDesc;

            GameMessageInfo gmi;

            if (_gameMessageLookUp.TryGetValue(offset, out gmi))
            {
                var gm = TypeDescriptor.AllocateGameMessage(name);
                gm.Size = gmi.Size;
                gm.NetworkIds = gmi.Opcodes.ToArray();
                typeDesc = gm;
            }
            else
                typeDesc = TypeDescriptor.AllocateStructure(name);
            typeDesc.Name = name;
            typeDesc.UnkValue = unkValue;

            table.Add(offset, typeDesc);

            List<FieldDescriptor> list = new List<FieldDescriptor>();
            for (; ; )
            {
                FieldDescriptor f = new FieldDescriptor();
                f.Name = fields.CStringPtr;
                int type = fields[4].Int32;
                if (mem[type + 4].CStringPtr != "DT_NULL" && !table.TryGetValue(type, out f.Type))
                    f.Type = DiscoverMessageDescriptors(mem, table, type);
                f.Offset = fields[8].Int32;
                var defaultValuePtr = fields[12].Ptr;
                f.Min = fields[0x10].Int32;
                f.Max = fields[0x14].Int32;
                f.Flags = fields[0x18].Int32;
                type = fields[0x1C].Int32;
                if (mem[type + 4].CStringPtr != "DT_NULL" && !table.TryGetValue(type, out f.SubType))
                    f.SubType = DiscoverMessageDescriptors(mem, table, type);
                f.VariableOffset = fields[0x20].Int32;
                f.ArrayLength = fields[0x24].Int32;
                f.ArrayLengthOffset = fields[0x28].Int32;
                f.EncodedBits = fields[0x2C].UInt16;
                f.EncodedBits2 = fields[0x2E].UInt16;
                f.SnoType = fields[0x30].Int32;
                f.TagMapRelated = fields[0x34].Int32;
                var enumFields = fields[0x38].Ptr;
                if (enumFields.Offset != 0)
                {
                    List<Tuple<string, int>> enums = new List<Tuple<string, int>>();
                    for (; ; )
                    {
                        if (enumFields[4].Int32 == 0)
                            break;
                        enums.Add(new Tuple<string, int>(enumFields[4].CStringPtr, enumFields.Int32));
                        enumFields = enumFields[8];
                    }
                    f.EnumFields = enums.ToArray();
                }
                f.FlagIndex = fields[0x3C].Int32;
                int funcA = fields[0x40].Int32; // TODO
                int funcB = fields[0x44].Int32; // TODO
                f.DspIndex = fields[0x48].Int32;

                var str = fields[0x4C].CString;
                // 0x4C 64 bytes, unused string
                //if (str != string.Empty)  Console.WriteLine(str);

                list.Add(f);
                if (fields.Int32 == 0)
                    break;
                fields = fields[140];

            }


            typeDesc.Fields = list.ToArray();
            return typeDesc;
        }
Beispiel #9
0
 public MemAddress32(Mem32 mem, int offset) { Memory = mem; Offset = offset; }
Beispiel #10
0
        static void DumpAttributes(Mem32 mem)
        {
            // could get the max num from descriptor
            var attribList = mem[AttributesAddress];

            NetAttribute.Attributes = new NetAttribute[AttributeCount];
            for (int i = 0; i < AttributeCount; i++)
            {
                var attrib = attribList[i * 40];

                int id = attrib.Int32;
                int u2 = attrib[4].Int32;
                int u3 = attrib[8].Int32;
                int u4 = attrib[12].Int32;
                int u5 = attrib[16].Int32;

                string scriptA = attrib[20].CStringPtr;
                string scriptB = attrib[24].CStringPtr;
                string name    = attrib[28].CStringPtr;
                var    decoder = attrib[32].Ptr;
                byte   u10     = attrib[36].Byte;
                switch (decoder.Int32)
                {
                case Attribute_Int:
                {
                    int bitCount = decoder[12].Int32;
                    NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.Int, u10, 0, 0, bitCount);
                    break;
                }

                case Attribute_IntMinMax:
                {
                    int bitCount = decoder[20].Int32;
                    int min      = decoder[12].Int32;
                    int max      = decoder[16].Int32;
                    NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.IntMinMax, u10, min, max, bitCount);
                    break;
                }

                case Attribute_Float16:     // Decode16BitFloat(bits)
                {
                    int bitCount = decoder[12].Int32;
                    NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.Float16, u10, 0, 0, bitCount);
                }
                break;

                case Attribute_Float16Or32:
                {
                    NetAttribute.Attributes[id] = new NetAttribute(id, u2, u3, u4, u5, scriptA, scriptB, name, NetAttributeEncoding.Float16Or32, u10, 0, 0, 0);
                }
                break;

                case Attribute_FloatMinMax:     // DecodeFloatMinMax
                    throw new Exception("FloatMinMax used");

                default:
                    throw new Exception("Unknown decoder used");
                }
            }
            NetAttribute.SaveXml("attributes.xml");
        }
Beispiel #11
0
        static TypeDescriptor DiscoverMessageDescriptors(Mem32 mem, Dictionary <int, TypeDescriptor> table, int offset)
        {
            if (offset == 0)
            {
                return(null);
            }
            string name     = mem[offset + 4].CStringPtr;
            int    unkValue = mem[offset + 8].Int32;
            var    fields   = mem[offset + 12].Ptr;

            if (fields.Offset == 0)
            {
                var basicType = TypeDescriptor.AllocateBasicType(name);
                basicType.Name     = name;
                basicType.UnkValue = unkValue;
                table.Add(offset, basicType);
                return(basicType);
            }

            StructureTypeDescriptor typeDesc;

            GameMessageInfo gmi;

            if (_gameMessageLookUp.TryGetValue(offset, out gmi))
            {
                var gm = TypeDescriptor.AllocateGameMessage(name);
                gm.Size       = gmi.Size;
                gm.NetworkIds = gmi.Opcodes.ToArray();
                typeDesc      = gm;
            }
            else
            {
                typeDesc = TypeDescriptor.AllocateStructure(name);
            }
            typeDesc.Name     = name;
            typeDesc.UnkValue = unkValue;

            table.Add(offset, typeDesc);

            List <FieldDescriptor> list = new List <FieldDescriptor>();

            for (; ;)
            {
                FieldDescriptor f = new FieldDescriptor();
                f.Name = fields.CStringPtr;
                int type = fields[4].Int32;
                if (mem[type + 4].CStringPtr != "DT_NULL" && !table.TryGetValue(type, out f.Type))
                {
                    f.Type = DiscoverMessageDescriptors(mem, table, type);
                }
                f.Offset = fields[8].Int32;
                var defaultValuePtr = fields[12].Ptr;
                f.Min   = fields[0x10].Int32;
                f.Max   = fields[0x14].Int32;
                f.Flags = fields[0x18].Int32;
                type    = fields[0x1C].Int32;
                if (mem[type + 4].CStringPtr != "DT_NULL" && !table.TryGetValue(type, out f.SubType))
                {
                    f.SubType = DiscoverMessageDescriptors(mem, table, type);
                }
                f.VariableOffset    = fields[0x20].Int32;
                f.ArrayLength       = fields[0x24].Int32;
                f.ArrayLengthOffset = fields[0x28].Int32;
                f.EncodedBits       = fields[0x2C].UInt16;
                f.EncodedBits2      = fields[0x2E].UInt16;
                f.SnoType           = fields[0x30].Int32;
                f.TagMapRelated     = fields[0x34].Int32;
                var enumFields = fields[0x38].Ptr;
                if (enumFields.Offset != 0)
                {
                    List <Tuple <string, int> > enums = new List <Tuple <string, int> >();
                    for (; ;)
                    {
                        if (enumFields[4].Int32 == 0)
                        {
                            break;
                        }
                        enums.Add(new Tuple <string, int>(enumFields[4].CStringPtr, enumFields.Int32));
                        enumFields = enumFields[8];
                    }
                    f.EnumFields = enums.ToArray();
                }
                f.FlagIndex = fields[0x3C].Int32;
                int funcA = fields[0x40].Int32; // TODO
                int funcB = fields[0x44].Int32; // TODO
                f.DspIndex = fields[0x48].Int32;

                var str = fields[0x4C].CString;
                // 0x4C 64 bytes, unused string
                //if (str != string.Empty)  Console.WriteLine(str);

                list.Add(f);
                if (fields.Int32 == 0)
                {
                    break;
                }
                fields = fields[140];
            }


            typeDesc.Fields = list.ToArray();
            return(typeDesc);
        }
Beispiel #12
0
 public MemAddress32(Mem32 mem, int offset)
 {
     Memory = mem; Offset = offset;
 }