Example #1
0
        public StructViewer(int pid, IntPtr address, StructDef struc)
        {
            InitializeComponent();

            _pid = pid;
            _address = address;
            _struct = struc;
            treeStruct.Model = _model;
            treeStruct.ContextMenu = menuStruct;

            GenericViewMenu.AddMenuItems(copyMenuItem.MenuItems, treeStruct);

            try
            {
                FieldValue[] values;

                _struct.Offset = address;
                _struct.IOProvider = new ProcessMemoryIO(pid);
                _struct.Structs = Program.Structs;
                values = _struct.Read();

                _model.Nodes.Add(new StructNode(new FieldValue() 
                { Name = "Struct", FieldType = FieldType.StringUTF16, Value = "" }));

                foreach (FieldValue val in values)
                    this.AddNode(_model.Nodes[0], val);

                treeStruct.Root.Children[0].IsExpanded = true;
            }
            catch (Exception ex)
            {
                PhUtils.ShowException("Unable to view the struct", ex);
                this.Error = true;
            }
        }
Example #2
0
        public StructWindow(int pid, IntPtr address, StructDef struc)
        {
            InitializeComponent();
            this.AddEscapeToClose();
            this.SetTopMost();

            _pid = pid;
            _address = address;
            _struct = struc;
        }
Example #3
0
        private void ParseStructDef(string text, ref int i)
        {
            StructDef def = new StructDef();

            _eatResult = EatWhitespace(text, ref i);
            string structName = EatId(text, ref i);

            if (_eatResult || string.IsNullOrEmpty(structName))
            {
                throw new ParserException(_fileName, _lineNumber, "Expected identifier (struct name)");
            }

            if (_structs.ContainsKey(structName))
            {
                throw new ParserException(_fileName, _lineNumber, "Struct name '" + structName + "' already used");
            }

            // add it first so that structs can be self-referential
            _structs.Add(structName, null);

            // {
            _eatResult = EatWhitespace(text, ref i);
            string openingBrace = EatSymbol(text, ref i);

            if (_eatResult || openingBrace != "{")
            {
                throw new ParserException(_fileName, _lineNumber, "Expected '{'");
            }

            while (true)
            {
                // }
                _eatResult = EatWhitespace(text, ref i);
                string endBrace = EatSymbol(text, ref i);

                if (_eatResult)
                {
                    throw new ParserException(_fileName, _lineNumber, "Expected type name or '}'");
                }
                if (endBrace == "}")
                {
                    break;
                }
                if (endBrace.Length > 0)
                {
                    throw new ParserException(_fileName, _lineNumber, "Unexpected '" + endBrace + "'");
                }

                // TYPE
                _eatResult = EatWhitespace(text, ref i);
                string typeName = EatId(text, ref i);

                if (_eatResult || string.IsNullOrEmpty(typeName))
                {
                    throw new ParserException(_fileName, _lineNumber, "Expected type name");
                }

                FieldType type;

                if (_typeDefs.ContainsKey(typeName))
                {
                    type = this.GetType(typeName);
                }
                else
                {
                    type = FieldType.Struct;

                    if (!_structs.ContainsKey(typeName))
                    {
                        throw new ParserException(_fileName, _lineNumber, "Unknown identifier '" + typeName + "' (type or struct name)");
                    }
                }

                // type, without the pointer or array flag
                FieldType justType = type;

                // TYPE*
                // optional asterisk (pointer)
                _eatResult = EatWhitespace(text, ref i);

                if (EatSymbol(text, ref i) == "*")
                {
                    if (this.IsTypePointer(type))
                    {
                        throw new ParserException(_fileName, _lineNumber, "Invalid '*'; type '" + typeName + "' is already a pointer");
                    }

                    type |= FieldType.Pointer;
                }

                // TYPE* FIELDNAME
                _eatResult = EatWhitespace(text, ref i);
                string fieldName = EatId(text, ref i);

                if (_eatResult || string.IsNullOrEmpty(fieldName))
                {
                    throw new ParserException(_fileName, _lineNumber, "Expected identifier (struct field name)");
                }

                if (def.ContainsField(fieldName))
                {
                    throw new ParserException(_fileName, _lineNumber, "Field name '" + fieldName + "' already used");
                }

                _eatResult = EatWhitespace(text, ref i);
                string leftSqBracket = EatSymbol(text, ref i);
                int    varLength     = 0;

                if (leftSqBracket == "[")
                {
                    _eatResult = EatWhitespace(text, ref i);
                    string fieldRefName  = EatId(text, ref i);
                    string fieldSizeSpec = EatNumber(text, ref i);

                    if (!string.IsNullOrEmpty(fieldRefName))
                    {
                        if (!def.ContainsField(fieldRefName))
                        {
                            throw new ParserException(_fileName, _lineNumber, "Unknown identifier '" + fieldRefName + "' (field name)");
                        }

                        def.GetField(fieldRefName).SetsVarOn = fieldName;

                        // const add/multiply
                        int iSave = i;

                        _eatResult = EatWhitespace(text, ref i);
                        string plusOrMulOrDivSign = EatSymbol(text, ref i);

                        if (plusOrMulOrDivSign == "+")
                        {
                            def.GetField(fieldRefName).SetsVarOnAdd = EatParseInt(text, ref i);
                        }
                        else if (plusOrMulOrDivSign == "*")
                        {
                            def.GetField(fieldRefName).SetsVarOnMultiply = EatParseFloat(text, ref i);

                            int iSave2 = i;
                            _eatResult = EatWhitespace(text, ref i);
                            string plusSign = EatSymbol(text, ref i);

                            if (plusSign == "+")
                            {
                                def.GetField(fieldRefName).SetsVarOnAdd = EatParseInt(text, ref i);
                            }
                            else if (plusSign == "-")
                            {
                                def.GetField(fieldRefName).SetsVarOnAdd = -EatParseInt(text, ref i);
                            }
                            else
                            {
                                i = iSave2;
                            }
                        }
                        else if (plusOrMulOrDivSign == "/")
                        {
                            // here we just set SetsVarOnMultiply to 1 / value
                            def.GetField(fieldRefName).SetsVarOnMultiply = 1 / EatParseFloat(text, ref i);

                            int iSave2 = i;
                            _eatResult = EatWhitespace(text, ref i);
                            string plusSign = EatSymbol(text, ref i);

                            if (plusSign == "+")
                            {
                                def.GetField(fieldRefName).SetsVarOnAdd = EatParseInt(text, ref i);
                            }
                            else if (plusSign == "-")
                            {
                                def.GetField(fieldRefName).SetsVarOnAdd = -EatParseInt(text, ref i);
                            }
                            else
                            {
                                i = iSave2;
                            }
                        }
                        else
                        {
                            // that didn't work; restore the index
                            i = iSave;
                        }
                    }
                    else if (!string.IsNullOrEmpty(fieldSizeSpec))
                    {
                        try
                        {
                            //varLength = (int)BaseConverter.ToNumberParse(fieldSizeSpec);
                            varLength = (int)BaseConverter.ToNumberParse(fieldSizeSpec);
                        }
                        catch
                        {
                            throw new ParserException(_fileName, _lineNumber, "Could not parse number '" + fieldSizeSpec + "'");
                        }
                    }
                    else
                    {
                        throw new ParserException(_fileName, _lineNumber, "Number or identifier expected (size specifier)");
                    }

                    // if it's not a string, it's an array
                    if (justType != FieldType.StringASCII && justType != FieldType.StringUTF16)
                    {
                        type |= FieldType.Array;
                    }

                    _eatResult = EatWhitespace(text, ref i);
                    string rightSqBracket = EatSymbol(text, ref i);

                    if (_eatResult || rightSqBracket != "]")
                    {
                        throw new ParserException(_fileName, _lineNumber, "Expected ']'");
                    }

                    // fix up the semicolon
                    _eatResult    = EatWhitespace(text, ref i);
                    leftSqBracket = EatSymbol(text, ref i);
                }

                // TYPE* FIELDNAME;
                string endSemicolon = leftSqBracket;

                if (_eatResult || endSemicolon != ";")
                {
                    throw new ParserException(_fileName, _lineNumber, "Expected ';'");
                }

                StructField field = new StructField(fieldName, type);

                if (field.Type == FieldType.Struct)
                {
                    field.StructName = typeName;
                }

                field.VarArrayLength = varLength;
                field.VarLength      = varLength;

                def.AddField(field);
            }

            _structs[structName] = def;
        }
Example #4
0
        private void ParseStructDef(string text, ref int i)
        {
            StructDef def = new StructDef();

            _eatResult = EatWhitespace(text, ref i);
            string structName = EatId(text, ref i);

            if (_eatResult || structName == "")
                throw new ParserException(_fileName, _lineNumber, "Expected identifier (struct name)");

            if (_structs.ContainsKey(structName))
                throw new ParserException(_fileName, _lineNumber, "Struct name '" + structName + "' already used");

            // add it first so that structs can be self-referential
            _structs.Add(structName, null);

            // {
            _eatResult = EatWhitespace(text, ref i);
            string openingBrace = EatSymbol(text, ref i);

            if (_eatResult || openingBrace != "{")
                throw new ParserException(_fileName, _lineNumber, "Expected '{'");

            while (true)
            {
                // }
                _eatResult = EatWhitespace(text, ref i);
                string endBrace = EatSymbol(text, ref i);

                if (_eatResult)
                    throw new ParserException(_fileName, _lineNumber, "Expected type name or '}'");
                if (endBrace == "}")
                    break;
                if (endBrace.Length > 0)
                    throw new ParserException(_fileName, _lineNumber, "Unexpected '" + endBrace + "'");

                // TYPE
                _eatResult = EatWhitespace(text, ref i);
                string typeName = EatId(text, ref i);

                if (_eatResult || typeName == "")
                    throw new ParserException(_fileName, _lineNumber, "Expected type name");

                FieldType type;

                if (_typeDefs.ContainsKey(typeName))
                {
                    type = this.GetType(typeName);
                }
                else
                {
                    type = FieldType.Struct;

                    if (!_structs.ContainsKey(typeName))
                        throw new ParserException(_fileName, _lineNumber, "Unknown identifier '" + typeName + "' (type or struct name)");
                }

                // type, without the pointer or array flag
                FieldType justType = type;

                // TYPE*
                // optional asterisk (pointer)
                _eatResult = EatWhitespace(text, ref i);

                if (EatSymbol(text, ref i) == "*")
                {
                    if (this.IsTypePointer(type))
                        throw new ParserException(_fileName, _lineNumber, "Invalid '*'; type '" + typeName + "' is already a pointer");

                    type |= FieldType.Pointer;
                }

                // TYPE* FIELDNAME
                _eatResult = EatWhitespace(text, ref i);
                string fieldName = EatId(text, ref i);

                if (_eatResult || fieldName == "")
                    throw new ParserException(_fileName, _lineNumber, "Expected identifier (struct field name)");

                if (def.ContainsField(fieldName))
                    throw new ParserException(_fileName, _lineNumber, "Field name '" + fieldName + "' already used");

                _eatResult = EatWhitespace(text, ref i);
                string leftSqBracket = EatSymbol(text, ref i);
                int varLength = 0;

                if (leftSqBracket == "[")
                {
                    _eatResult = EatWhitespace(text, ref i);
                    string fieldRefName = EatId(text, ref i);
                    string fieldSizeSpec = EatNumber(text, ref i);

                    if (fieldRefName != "")
                    {
                        if (!def.ContainsField(fieldRefName))
                            throw new ParserException(_fileName, _lineNumber, "Unknown identifier '" + fieldRefName + "' (field name)");

                        def.GetField(fieldRefName).SetsVarOn = fieldName;

                        // const add/multiply
                        int iSave = i;

                        _eatResult = EatWhitespace(text, ref i);
                        string plusOrMulOrDivSign = EatSymbol(text, ref i);

                        if (plusOrMulOrDivSign == "+")
                        {
                            def.GetField(fieldRefName).SetsVarOnAdd = EatParseInt(text, ref i);
                        }
                        else if (plusOrMulOrDivSign == "*")
                        {
                            def.GetField(fieldRefName).SetsVarOnMultiply = EatParseFloat(text, ref i);

                            int iSave2 = i;
                            _eatResult = EatWhitespace(text, ref i);
                            string plusSign = EatSymbol(text, ref i);

                            if (plusSign == "+")
                                def.GetField(fieldRefName).SetsVarOnAdd = EatParseInt(text, ref i);
                            else if (plusSign == "-")
                                def.GetField(fieldRefName).SetsVarOnAdd = -EatParseInt(text, ref i);
                            else
                                i = iSave2;
                        }
                        else if (plusOrMulOrDivSign == "/")
                        {
                            // here we just set SetsVarOnMultiply to 1 / value
                            def.GetField(fieldRefName).SetsVarOnMultiply = 1 / EatParseFloat(text, ref i);

                            int iSave2 = i;
                            _eatResult = EatWhitespace(text, ref i);
                            string plusSign = EatSymbol(text, ref i);

                            if (plusSign == "+")
                                def.GetField(fieldRefName).SetsVarOnAdd = EatParseInt(text, ref i);
                            else if (plusSign == "-")
                                def.GetField(fieldRefName).SetsVarOnAdd = -EatParseInt(text, ref i);
                            else
                                i = iSave2;
                        }
                        else
                        {
                            // that didn't work; restore the index
                            i = iSave;
                        }
                    }
                    else if (fieldSizeSpec != "")
                    {
                        try
                        {
                            varLength = (int)BaseConverter.ToNumberParse(fieldSizeSpec);
                            varLength = (int)BaseConverter.ToNumberParse(fieldSizeSpec);
                        }
                        catch
                        {
                            throw new ParserException(_fileName, _lineNumber, "Could not parse number '" + fieldSizeSpec + "'");
                        }
                    }
                    else
                    {
                        throw new ParserException(_fileName, _lineNumber, "Number or identifier expected (size specifier)");
                    }

                    // if it's not a string, it's an array
                    if (justType != FieldType.StringASCII && justType != FieldType.StringUTF16)
                        type |= FieldType.Array;

                    _eatResult = EatWhitespace(text, ref i);
                    string rightSqBracket = EatSymbol(text, ref i);

                    if (_eatResult || rightSqBracket != "]")
                        throw new ParserException(_fileName, _lineNumber, "Expected ']'");

                    // fix up the semicolon
                    _eatResult = EatWhitespace(text, ref i);
                    leftSqBracket = EatSymbol(text, ref i);
                }

                // TYPE* FIELDNAME;
                string endSemicolon = leftSqBracket;

                if (_eatResult || endSemicolon != ";")
                    throw new ParserException(_fileName, _lineNumber, "Expected ';'");

                StructField field = new StructField(fieldName, type);

                if (field.Type == FieldType.Struct)
                    field.StructName = typeName;

                field.VarArrayLength = varLength;
                field.VarLength = varLength;

                def.AddField(field);
            }

            _structs[structName] = def;
        }
Example #5
0
        private unsafe int ReadOnce(StructField field, IntPtr offset, out FieldValue valueOut)
        {
            FieldValue value = new FieldValue()
            {
                FieldType = field.Type, Name = field.Name
            };
            int readSize = 0;

            switch (field.Type)
            {
            case FieldType.Bool32:
                value.Value = Utils.ToInt32(IOProvider.ReadBytes(offset, 4),
                                            Utils.Endianness.Little) != 0;
                readSize = 4;
                break;

            case FieldType.Bool8:
                value.Value = IOProvider.ReadBytes(offset, 1)[0] != 0;
                readSize    = 1;
                break;

            case FieldType.CharASCII:
                value.Value = (char)IOProvider.ReadBytes(offset, 1)[0];
                readSize    = 1;
                break;

            case FieldType.CharUTF16:
                value.Value = Encoding.Unicode.GetString(IOProvider.ReadBytes(offset, 2))[0];
                readSize    = 2;
                break;

            case FieldType.Double:
            {
                long data = Utils.ToInt64(
                    IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little);

                value.Value = *(double *)&data;
                readSize    = 8;
            }
            break;

            case FieldType.Int16:
                value.Value = (short)Utils.ToUInt16(
                    IOProvider.ReadBytes(offset, 2), Utils.Endianness.Little);
                readSize = 2;
                break;

            case FieldType.Int32:
                value.Value = Utils.ToInt32(
                    IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little);
                readSize = 4;
                break;

            case FieldType.Int64:
                value.Value = Utils.ToInt64(
                    IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little);
                readSize = 8;
                break;

            case FieldType.Int8:
                value.Value = (sbyte)IOProvider.ReadBytes(offset, 1)[0];
                readSize    = 1;
                break;

            case FieldType.PVoid:
                value.Value = IOProvider.ReadBytes(offset, IntPtr.Size).ToIntPtr();
                readSize    = IntPtr.Size;
                break;

            case FieldType.Single:
            {
                int data = Utils.ToInt32(
                    IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little);

                value.Value = *(float *)&data;
                readSize    = 4;
            }
            break;

            case FieldType.StringASCII:
            {
                StringBuilder str = new StringBuilder();

                if (field.VarLength == -1)
                {
                    int i;

                    for (i = 0; ; i++)
                    {
                        byte b = IOProvider.ReadBytes(offset.Increment(i), 1)[0];

                        if (b == 0)
                        {
                            break;
                        }

                        str.Append((char)b);
                    }

                    readSize = i;
                }
                else
                {
                    str.Append(Encoding.ASCII.GetString(
                                   IOProvider.ReadBytes(offset, field.VarLength)));
                    readSize = field.VarLength;
                }

                value.Value = str.ToString();
            }

            break;

            case FieldType.StringUTF16:
            {
                StringBuilder str = new StringBuilder();

                if (field.VarLength == -1)
                {
                    int i;

                    for (i = 0; ; i += 2)
                    {
                        byte[] b = IOProvider.ReadBytes(offset.Increment(i), 2);

                        if (Utils.IsEmpty(b))
                        {
                            break;
                        }

                        str.Append(Encoding.Unicode.GetString(b));
                    }

                    readSize = i;
                }
                else
                {
                    str.Append(Encoding.Unicode.GetString(
                                   IOProvider.ReadBytes(offset, field.VarLength * 2))); // each char is 2 bytes
                    readSize = field.VarLength;
                }

                value.Value = str.ToString();
            }

            break;

            case FieldType.Struct:
            {
                FieldValue[] valuesOut;
                StructDef    struc = Structs[field.StructName];

                struc.IOProvider = this.IOProvider;
                struc.Offset     = offset;
                struc.Structs    = this.Structs;
                readSize         = struc.Read(out valuesOut);
                value.Value      = valuesOut;
                value.StructName = field.StructName;
            }

            break;

            case FieldType.UInt16:
                value.Value = Utils.ToUInt16(
                    IOProvider.ReadBytes(offset, 2), Utils.Endianness.Little);
                readSize = 2;
                break;

            case FieldType.UInt32:
                value.Value = Utils.ToUInt32(
                    IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little);
                readSize = 4;
                break;

            case FieldType.UInt64:
                value.Value = (ulong)Utils.ToInt64(
                    IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little);
                readSize = 8;
                break;

            case FieldType.UInt8:
                value.Value = IOProvider.ReadBytes(offset, 1)[0];
                readSize    = 1;
                break;

            default:
                readSize = 0;
                break;
            }

            valueOut = value;

            return(readSize);
        }