예제 #1
0
        public static int ReadCompressedUnsignedInt(EndianAwareBinaryReader reader, out byte bytesUsed)
        {
            byte      compressedFirstByte = reader.ReadByte();
            const int sevenBitMask        = 0x7F;
            const int fourteenBitmask     = 0xBF;
            const int twentyNineBitMask   = 0xDF;

            bytesUsed = 1;
            int decompressedResult = 0;

            if ((compressedFirstByte & sevenBitMask) == compressedFirstByte)
            {
                decompressedResult = compressedFirstByte;
            }
            else if ((compressedFirstByte & fourteenBitmask) == compressedFirstByte)
            {
                byte hiByte = (byte)(compressedFirstByte & 0x3F);
                byte loByte = reader.ReadByte();
                decompressedResult = loByte | hiByte << 8;
                bytesUsed          = 2;
            }
            else if ((compressedFirstByte & twentyNineBitMask) == compressedFirstByte)
            {
                byte hiWordHiByte = (byte)(compressedFirstByte & 0x1F);
                byte hiWordLoByte = reader.ReadByte();
                byte loWordHiByte = reader.ReadByte();
                byte loWordLoByte = reader.ReadByte();
                decompressedResult = loWordLoByte | loWordHiByte << 8 | hiWordLoByte << 16 | hiWordHiByte << 24;
                bytesUsed          = 4;
            }
            return(decompressedResult);
        }
예제 #2
0
            internal void Read(EndianAwareBinaryReader reader)
            {
                this.imageKind             = (PEImageKind)reader.ReadUInt16();
                this.lMajor                = reader.ReadByte();
                this.lMinor                = reader.ReadByte();
                this.codeSize              = reader.ReadUInt32();
                this.initializedDataSize   = reader.ReadUInt32();
                this.uninitializedDataSize = reader.ReadUInt32();
                this.entryPointRVA         = reader.ReadUInt32();
                this.baseOfCode            = reader.ReadUInt32();
                switch (this.imageKind)
                {
                case PEImageKind.x86Image:
                    this.baseOfData = reader.ReadUInt32();
                    break;

                case PEImageKind.x64Image:
                    break;

                case PEImageKind.RomImage:
                    throw new NotImplementedException();

                default:
                    throw new BadImageFormatException();
                }
            }
예제 #3
0
        private void ReadNarrow(EndianAwareBinaryReader reader, ICliMetadataRoot metadataRoot, Action <byte[]> bodyBuilder)
        {
            var firstByte = reader.ReadByte();

            this.codeSize = (byte)((firstByte & 0xFC) >> 2);
            bodyBuilder(reader.ReadBytes((int)this.CodeSize));
        }
        /// <summary>
        /// Loads the header from the reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            Magic = reader.ReadUInt16();
            if (IMAGE_OPTIONAL_HEADER_MAGIC != Magic)
            {
                throw new BadImageFormatException();
            }

            MajorLinkerVersion      = reader.ReadByte();
            MinorLinkerVersion      = reader.ReadByte();
            SizeOfCode              = reader.ReadUInt32();
            SizeOfInitializedData   = reader.ReadUInt32();
            SizeOfUninitializedData = reader.ReadUInt32();
            AddressOfEntryPoint     = reader.ReadUInt32();
            BaseOfCode              = reader.ReadUInt32();
            BaseOfData              = reader.ReadUInt32();

            ImageBase                   = reader.ReadUInt32();
            SectionAlignment            = reader.ReadUInt32();
            FileAlignment               = reader.ReadUInt32();
            MajorOperatingSystemVersion = reader.ReadUInt16();
            MinorOperatingSystemVersion = reader.ReadUInt16();
            MajorImageVersion           = reader.ReadUInt16();
            MinorImageVersion           = reader.ReadUInt16();
            MajorSubsystemVersion       = reader.ReadUInt16();
            MinorSubsystemVersion       = reader.ReadUInt16();
            Win32VersionValue           = reader.ReadUInt32();
            SizeOfImage                 = reader.ReadUInt32();
            SizeOfHeaders               = reader.ReadUInt32();
            CheckSum            = reader.ReadUInt32();
            Subsystem           = reader.ReadUInt16();
            DllCharacteristics  = reader.ReadUInt16();
            SizeOfStackReserve  = reader.ReadUInt32();
            SizeOfStackCommit   = reader.ReadUInt32();
            SizeOfHeapReserve   = reader.ReadUInt32();
            SizeOfHeapCommit    = reader.ReadUInt32();
            LoaderFlags         = reader.ReadUInt32();
            NumberOfRvaAndSizes = reader.ReadUInt32();

            DataDirectory = new ImageDataDirectory[NumberOfRvaAndSizes];
            for (int i = 0; i < NumberOfRvaAndSizes; i++)
            {
                DataDirectory[i].Read(reader);
            }
        }
예제 #5
0
        internal void Read(EndianAwareBinaryReader reader, PEImage sourceImage)
        {
            this.offset = reader.ReadUInt32();
            this.size   = reader.ReadUInt32();
            byte[] name  = new byte[32];
            bool   broke = false;
            int    index = 0;

            for (index = 0; index < name.Length; index++)
            {
                name[index] = reader.ReadByte();
                if (name[index] == '\0')
                {
                    broke = true;
                    index++;
                    break;
                }
            }
            if (broke)
            {
                int remainder      = index & 3; // aka: index % 4
                int bytesRemaining = 4 - remainder;
                if (remainder > 0)
                {
                    for (int i = 0; i < bytesRemaining; i++)
                    {
                        reader.ReadByte();
                    }
                    int paddedLength = index + bytesRemaining;
                    this.name = new byte[paddedLength];
                    Array.ConstrainedCopy(name, 0, this.name, 0, paddedLength);
                }
                else
                {
                    this.name = new byte[index];
                    Array.ConstrainedCopy(name, 0, this.name, 0, index);
                }
            }
            else
            {
                this.name = name;
            }
        }
예제 #6
0
        public static TypeHeader Deserialize(EndianAwareBinaryReader reader)
        {
            var typeId   = reader.ReadInt32();
            var typeName = Util.ReadLengthPrefixedString(reader);
            var containsExtraDataByte = reader.ReadByte();
            var instanceCount         = reader.ReadInt32();
            var referentArray         = Util.ReadReferentArray(reader, instanceCount);
            var extraData             = (containsExtraDataByte != 0) ? reader.ReadBytes(instanceCount) : null;

            return(new TypeHeader(typeName, typeId, referentArray, extraData));
        }
예제 #7
0
        private unsafe bool ReadSubstring(uint index)
        {
            lock (this.syncObject)
            {
                reader.BaseStream.Position = index;

                /* *
                 * To save space, smaller strings that exist as the
                 * tail end of another string, are condensed accordingly.
                 * *
                 * It's quicker to construct the strings from the
                 * original source than it is to iterate through the
                 * location table used to quickly look items up.
                 * */
                uint loc = index;
                while (loc < base.Size)
                {
                    byte current = reader.ReadByte();
                    if (current == 0)
                    {
                        break;
                    }
                    loc++;
                }
                uint size = loc - index;
                reader.BaseStream.Position = index;
                byte[] result = new byte[size];

                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadByte();
                }
                this.AddSubstring(ConvertUTF8ByteArray(result), index);
                return(loc < base.Size);
            }
        }
예제 #8
0
파일: Util.cs 프로젝트: ShitpostMDX/LibRbxl
        public static Tuple <int, int>[] ReadParentData(EndianAwareBinaryReader reader) // Tuple format is (Child, Parent)
        {
            reader.ReadByte();                                                          // Reserved
            var entryCount = reader.ReadInt32();

            var childReferents  = ReadReferentArray(reader, entryCount);
            var parentReferents = ReadReferentArray(reader, entryCount);

            var pairs = new Tuple <int, int> [entryCount];

            for (var i = 0; i < entryCount; i++)
            {
                pairs[i] = new Tuple <int, int>(childReferents[i], parentReferents[i]);
            }
            return(pairs);
        }
        internal bool ReadEntry()
        {
            var tailLength = this.tailLength;

            if (tailLength + 1 >= this.Size)
            {
                return(false);
            }
            byte compressedIntBytes = 0;

            byte[] currentData      = null;
            int    currentDataCount = 0;

            currentDataCount = CliMetadataFixedRoot.ReadCompressedUnsignedInt(reader, out compressedIntBytes);
            if (tailLength + compressedIntBytes >= this.Size)
            {
                reader.BaseStream.Seek(-(tailLength + compressedIntBytes - this.Size), SeekOrigin.Current);
                return(false);
            }
            else
            {
                tailLength += compressedIntBytes;
            }
            if (currentDataCount == 0)
            {
                /* *
                 * Reached the end of the heap which is padded
                 * with zeroes until the next 4-byte boundry.
                 * */
                return(false);
            }
            if (tailLength + currentDataCount > this.Size)
            {
                throw new BadImageFormatException(string.Format("The data within the {0} heap entry is longer than expected.", this.Name));
            }
            currentData = new byte[currentDataCount];
            for (int i = 0; i < currentDataCount && tailLength < this.Size; i++, tailLength++)
            {
                currentData[i] = reader.ReadByte();
            }
            this.AddData(this.GetData(currentData), compressedIntBytes);
            if (tailLength >= this.Size)
            {
                return(false);
            }
            return(true);
        }
예제 #10
0
파일: Util.cs 프로젝트: ShitpostMDX/LibRbxl
        public static PhysicalProperties ReadPhysicalProperties(EndianAwareBinaryReader reader)
        {
            var enabled = (reader.ReadByte() != 0);

            if (enabled)
            {
                var density          = reader.ReadSingle();
                var friction         = reader.ReadSingle();
                var elasticity       = reader.ReadSingle();
                var frictionWeight   = reader.ReadSingle();
                var elasticityWeight = reader.ReadSingle();
                return(new PhysicalProperties(density, friction, elasticity, frictionWeight, elasticityWeight));
            }
            else
            {
                return(new PhysicalProperties(false));
            }
        }
예제 #11
0
파일: Util.cs 프로젝트: ShitpostMDX/LibRbxl
        public static CFrame[] ReadCFrameArray(EndianAwareBinaryReader reader, int count)
        {
            var values    = new CFrame[count];
            var positions = new Vector3[count];
            var matrices  = new Matrix3[count];

            for (var i = 0; i < count; i++)
            {
                var specialMatrixType = reader.ReadByte();
                if (specialMatrixType == 0)
                {
                    var r00 = reader.ReadSingle();
                    var r01 = reader.ReadSingle();
                    var r02 = reader.ReadSingle();
                    var r10 = reader.ReadSingle();
                    var r11 = reader.ReadSingle();
                    var r12 = reader.ReadSingle();
                    var r20 = reader.ReadSingle();
                    var r21 = reader.ReadSingle();
                    var r22 = reader.ReadSingle();
                    matrices[i] = new Matrix3(r00, r01, r02, r10, r11, r12, r20, r21, r22);
                }
                else
                {
                    var mat = GetSpecialMatrix(specialMatrixType);
                    matrices[i] = mat;
                }
            }

            var xValues = ReadFloatArray(reader, count);
            var yValues = ReadFloatArray(reader, count);
            var zValues = ReadFloatArray(reader, count);

            for (var i = 0; i < count; i++)
            {
                positions[i] = new Vector3(xValues[i], yValues[i], zValues[i]);
            }

            for (var i = 0; i < count; i++)
            {
                values[i] = new CFrame(positions[i], matrices[i]);
            }
            return(values);
        }
예제 #12
0
        private string GetServerVersionFromResponse(Stream stream)
        {
            using (var reader = new EndianAwareBinaryReader(stream, Encoding.UTF8, true, false))
            {
                //Read Type (should be response = 4)
                int type = reader.ReadByte();
                if (type != 4)
                {
                    throw new NAMEException($"{SupportedDependencies.SqlServer}: Server responded with wrong Type ({type}).", NAMEStatusLevel.Error);
                }
                //Skip Status bit mask
                reader.ReadByte();
                //Read the full message length
                ushort length = reader.ReadUInt16();
                //Skip Channel
                reader.ReadUInt16();
                //Skip Packet Number
                reader.ReadByte();
                //Skip Window
                reader.ReadByte();
                //Read the rest of the message
                //preLoginBuffer = reader.ReadBytes(length - 2 - 1 - 1 - 2 - 1 - 1);
                //Read first option token (should be Version = 0)
                int token = reader.ReadByte();
                if (token != 0)
                {
                    throw new NAMEException($"{SupportedDependencies.SqlServer}: Server responded with wrong Token ({token}).", NAMEStatusLevel.Error);
                }
                //Read the offset
                ushort offset = reader.ReadUInt16();
                //Read the length (should be 6)
                ushort optionlength = reader.ReadUInt16();
                if (optionlength != 6)
                {
                    throw new NAMEException($"{SupportedDependencies.SqlServer}: Server responded with an invalid version length ({length}).", NAMEStatusLevel.Error);
                }
                //Skip everything until the version.
                reader.ReadBytes(offset - 2 - 2 - 1);
                int major = reader.ReadByte();
                int minor = reader.ReadByte();
                int build = reader.ReadUInt16();

                return($"{major}.{minor}.{build}");
            }
        }
예제 #13
0
        private static PropertyBlock Deserialize(EndianAwareBinaryReader reader, TypeHeader[] typeHeaders)
        {
            var typeId   = reader.ReadInt32();
            var name     = Util.ReadLengthPrefixedString(reader);
            var dataType = (PropertyType)reader.ReadByte();

            var typeHeader = typeHeaders.FirstOrDefault(n => n.TypeId == typeId);

            if (typeHeader == null)
            {
                throw new ArgumentException("No type header matches type id specified in property block.");
            }

            switch (dataType)
            {
            case PropertyType.String:
            {
                var values = Util.ReadStringArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <string>(name, dataType, typeId, values));
            }

            case PropertyType.Boolean:
            {
                var values = Util.ReadBoolArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <bool>(name, dataType, typeId, values));
            }

            case PropertyType.Int32:
            {
                var values = Util.ReadInt32Array(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <int>(name, dataType, typeId, values));
            }

            case PropertyType.Float:
            {
                var values = Util.ReadFloatArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <float>(name, dataType, typeId, values));
            }

            case PropertyType.Double:
            {
                var values = Util.ReadDoubleArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <double>(name, dataType, typeId, values));
            }

            case PropertyType.UDim2:
            {
                var values = Util.ReadUDim2Array(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <UDim2>(name, dataType, typeId, values));
            }

            case PropertyType.Ray:
            {
                var values = Util.ReadRayArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Ray>(name, dataType, typeId, values));
            }

            case PropertyType.Faces:
            {
                var values = Util.ReadFacesArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Faces>(name, dataType, typeId, values));
            }

            case PropertyType.Axis:
            {
                var values = Util.ReadAxisArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Axis>(name, dataType, typeId, values));
            }

            case PropertyType.BrickColor:
            {
                var values = Util.ReadBrickColorArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <BrickColor>(name, dataType, typeId, values));
            }

            case PropertyType.Color3:
            {
                var values = Util.ReadColor3Array(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Color3>(name, dataType, typeId, values));
            }

            case PropertyType.Vector2:
            {
                var values = Util.ReadVector2Array(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Vector2>(name, dataType, typeId, values));
            }

            case PropertyType.Vector3:
            {
                var values = Util.ReadVector3Array(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Vector3>(name, dataType, typeId, values));
            }

            case PropertyType.CFrame:
            {
                var values = Util.ReadCFrameArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <CFrame>(name, dataType, typeId, values));
            }

            case PropertyType.Enumeration:
            {
                var values = Util.ReadEnumerationArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <int>(name, dataType, typeId, values));
            }

            case PropertyType.Referent:
            {
                var values = Util.ReadReferentArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <int>(name, dataType, typeId, values));
            }

            case PropertyType.NumberSequence:
            {
                var values = Util.ReadNumberSequenceArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <NumberSequence>(name, dataType, typeId, values));
            }

            case PropertyType.ColorSequence:
            {
                var values = Util.ReadColorSequenceArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <ColorSequence>(name, dataType, typeId, values));
            }

            case PropertyType.NumberRange:
            {
                var values = Util.ReadNumberRangeArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <NumberRange>(name, dataType, typeId, values));
            }

            case PropertyType.Rectangle:
            {
                var values = Util.ReadRectangleArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <Rectangle>(name, dataType, typeId, values));
            }

            case PropertyType.PhysicalProperties:
            {
                var values = Util.ReadPhysicalPropertiesArray(reader, typeHeader.InstanceCount);
                return(new PropertyBlock <PhysicalProperties>(name, dataType, typeId, values));
            }

            default:
            {
                return(null);
            }
            }
        }
예제 #14
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        private MethodHeader ReadMethodHeader(EndianAwareBinaryReader reader)
        {
            MethodHeader header = new MethodHeader();

            // Read first byte
            header.Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (header.Flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    header.CodeSize = ((uint)(header.Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    header.Flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    // Read second byte of flags
                    header.Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)header.Flags);
                    if (MethodFlags.ValidHeader != (header.Flags & MethodFlags.HeaderSizeMask))
                        throw new InvalidDataException(@"Invalid method header.");
                    header.MaxStack = reader.ReadUInt16();
                    header.CodeSize = reader.ReadUInt32();
                    header.LocalsSignature = new Token(reader.ReadUInt32()); // ReadStandAloneSigRow
                    break;

                default:
                    throw new InvalidDataException(@"Invalid method header while trying to decode " + this.methodCompiler.Method.ToString() + ". (Flags = " + header.Flags.ToString("X") + ", Rva = " + this.methodCompiler.Method.Rva + ")");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (header.Flags & MethodFlags.MoreSections))
                return header;

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + header.CodeSize;
            if (0 != (dataSectPos & 3))
                dataSectPos += (4 - (dataSectPos % 4));
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int length;
                int blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), @"Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    methodCompiler.ExceptionClauseHeader.AddClause(clause);
                }
            }
            while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;

            return header;
        }
예제 #15
0
        private static string GetVersionFromServerReponse(TcpClient client)
        {
            EndianAwareBinaryReader reader = new EndianAwareBinaryReader(client.GetStream(), false);

            try
            {
                byte type = reader.ReadByte();
                if (type != 1)
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server responded with wrong type ({type}).");
                }
                //Skip channel
                reader.ReadUInt16();
                //Read Length
                uint length = reader.ReadUInt32();
                //Read the rest of the message into memory. The length of Connection.Start will never be bigger than int.max
                byte[] buffer = reader.ReadBytes((int)length);
                reader.Dispose();
                reader = new EndianAwareBinaryReader(new MemoryStream(buffer), false);
                //Read class (should be Connection (10))
                ushort rClass = reader.ReadUInt16();
                if (rClass != 10)
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server responded with wrong class ({rClass}).");
                }
                //Read method (should be Start (10))
                ushort rMethod = reader.ReadUInt16();
                if (rMethod != 10)
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server responded with wrong method ({rMethod}).");
                }
                //Read AMQP major version (should be 0)
                byte major = reader.ReadByte();
                if (major != 0)
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server responded with wrong AMQP major version ({major}).");
                }
                //Read AMQP minor version (should be 9)
                byte minor = reader.ReadByte();
                if (major != 0)
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server responded with wrong AMQP minor version ({minor}).");
                }
                IDictionary <string, object> serverProperties = AmqpTypesReader.ReadTable(reader);
                if (!serverProperties.ContainsKey("version"))
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server did not send a server-properties table!");
                }
                if (!(serverProperties["version"] is byte[]))
                {
                    throw new NAMEException($"{SupportedDependencies.RabbitMq}: Server returned a version which is not a string!");
                }
                var versionStr = Encoding.UTF8.GetString((byte[])serverProperties["version"]);
                return(versionStr);
            }
            finally
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
            }
        }
예제 #16
0
 public void Read(EndianAwareBinaryReader reader)
 {
     this.majorVersion = reader.ReadByte();
     this.minorVersion = reader.ReadByte();
 }
예제 #17
0
        public object Deserialize(EndianAwareBinaryReader reader, SerializedType serializedType, int?length = null)
        {
            int?effectiveLength = null;

            var typeParent = TypeNode.Parent as TypeNode;

            if (length != null)
            {
                effectiveLength = length.Value;
            }
            else if (TypeNode.FieldLengthBinding != null)
            {
                object lengthValue = TypeNode.FieldLengthBinding.GetValue(this);
                effectiveLength = Convert.ToInt32(lengthValue);
            }
            else if (typeParent != null && typeParent.ItemLengthBinding != null)
            {
                object lengthValue = typeParent.ItemLengthBinding.GetValue((ValueNode)Parent);
                effectiveLength = Convert.ToInt32(lengthValue);
            }
            else if (TypeNode.FieldCountBinding != null)
            {
                object countValue = TypeNode.FieldCountBinding.GetValue(this);
                effectiveLength = Convert.ToInt32(countValue);
            }
            else if (serializedType == SerializedType.ByteArray || serializedType == SerializedType.SizedString)
            {
                checked
                {
                    effectiveLength = (int)_remainder;
                }
            }

            object value;

            switch (serializedType)
            {
            case SerializedType.Int1:
                value = reader.ReadSByte();
                break;

            case SerializedType.UInt1:
                value = reader.ReadByte(GetBitSize());
                break;

            case SerializedType.Int2:
                value = reader.ReadInt16();
                break;

            case SerializedType.UInt2:
                value = reader.ReadUInt16();
                break;

            case SerializedType.Int4:
                value = reader.ReadInt32();
                break;

            case SerializedType.UInt4:
                value = reader.ReadUInt32();
                break;

            case SerializedType.Int8:
                value = reader.ReadInt64();
                break;

            case SerializedType.UInt8:
                value = reader.ReadUInt64();
                break;

            case SerializedType.Float4:
                value = reader.ReadSingle();
                break;

            case SerializedType.Float8:
                value = reader.ReadDouble();
                break;

            case SerializedType.ByteArray:
            {
                Debug.Assert(effectiveLength != null, "effectiveLength != null");
                value = reader.ReadBytes(effectiveLength.Value);
                break;
            }

            case SerializedType.NullTerminatedString:
            {
                byte[] data = ReadNullTerminatedString(reader).ToArray();
                value = Encoding.GetString(data, 0, data.Length);
                break;
            }

            case SerializedType.SizedString:
            {
                Debug.Assert(effectiveLength != null, "effectiveLength != null");
                byte[] data = reader.ReadBytes(effectiveLength.Value);
                value = Encoding.GetString(data, 0, data.Length).TrimEnd('\0');
                break;
            }

            case SerializedType.LengthPrefixedString:
            {
                value = reader.ReadString();
                break;
            }

            default:
                throw new NotSupportedException();
            }

            return(value);
        }
예제 #18
0
        private void ReadWide(EndianAwareBinaryReader reader, ICliMetadataRoot metadataRoot, Action <byte[]> bodyBuilder)
        {
            var flagsAndSize = reader.ReadUInt16();

            this.flags      = ((MethodHeaderFlags)(flagsAndSize & 0x0FFF)) & ~MethodHeaderFlags.WideFormat;
            this.headerSize = (byte)((flagsAndSize & 0xF000) >> 0xA);
            this.maxStack   = reader.ReadUInt16();
            this.codeSize   = reader.ReadUInt32();
            var localVarSigToken = reader.ReadUInt32();

            if (localVarSigToken != 0)
            {
                var sigTableKind = (CliMetadataTableKinds)(1UL << (int)((localVarSigToken & 0xFF000000) >> 24));
                var sigIndex     = localVarSigToken & 0x00FFFFFF;
                ICliMetadataTable table;
                if (metadataRoot.TableStream.TryGetValue(sigTableKind, out table))
                {
                    if (table is ICliMetadataStandAloneSigTable)
                    {
                        ICliMetadataStandAloneSigTable sigTable = (ICliMetadataStandAloneSigTable)table;
                        var entry = sigTable[(int)sigIndex];
                        if (entry.Signature is ICliMetadataLocalVarSignature)
                        {
                            var sigEntry = (ICliMetadataLocalVarSignature)entry.Signature;
                            this.locals = sigEntry;
                        }
                    }
                }
                long codePosition = reader.BaseStream.Position;
                bodyBuilder(reader.ReadBytes((int)this.codeSize));
                if ((reader.BaseStream.Position % 4) != 0)
                {
                    reader.BaseStream.Position += 4 - reader.BaseStream.Position % 4;
                }
                var ehTable = new byte[0];
                if ((flags & MethodHeaderFlags.ContainsMoreSections) == MethodHeaderFlags.ContainsMoreSections)
                {
readSection:
                    MethodHeaderSectionFlags sectionFlags = (MethodHeaderSectionFlags)reader.ReadByte();
                    var smallFormat = ((sectionFlags & MethodHeaderSectionFlags.FatFormat) != MethodHeaderSectionFlags.FatFormat);
                    int dataSize    = 0;
                    if (smallFormat)
                    {
                        dataSize = reader.ReadByte();
                        reader.ReadUInt16();
                    }
                    else
                    {
                        dataSize = (int)new BitVector(new byte[] { reader.ReadByte(), reader.ReadByte(), reader.ReadByte() }).GetUInt32Nibbits(0, 24);
                    }
                    if ((sectionFlags & MethodHeaderSectionFlags.ExceptionHandlerTable) == MethodHeaderSectionFlags.ExceptionHandlerTable)
                    {
                        ehTable = ehTable.AddInlineArray(reader.ReadBytes(dataSize - 4));
                    }
                    else
                    {
                        reader.BaseStream.Position += dataSize - 4;
                    }
                    if ((sectionFlags & MethodHeaderSectionFlags.ContainsMoreSections) == MethodHeaderSectionFlags.ContainsMoreSections)
                    {
                        goto readSection;
                    }
                }
                if (ehTable.Length > 0)
                {
                    this.exceptionTable = new CliMetadataMethodExceptionTable(ehTable);
                }
                reader.BaseStream.Position = codePosition;
            }
        }
예제 #19
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        public MethodHeader(EndianAwareBinaryReader reader)
        {
            Clauses = new List <ExceptionHandlingClause>();

            // Read first byte
            Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (Flags & MethodFlags.HeaderMask)
            {
            case MethodFlags.TinyFormat:
                CodeSize = ((int)(Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                Flags   &= MethodFlags.HeaderMask;
                break;

            case MethodFlags.FatFormat:
                // Read second byte of flags
                Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)Flags);

                if (MethodFlags.ValidHeader != (Flags & MethodFlags.HeaderSizeMask))
                {
                    throw new CompilerException("Invalid method ");
                }

                MaxStack       = reader.ReadUInt16();
                CodeSize       = reader.ReadInt32();
                LocalVarSigTok = new Token(reader.ReadUInt32());                         // ReadStandAloneSigRow
                break;

            default:
                throw new CompilerException("Invalid method header");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (Flags & MethodFlags.MoreSections))
            {
                return;
            }

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + CodeSize;

            if (0 != (dataSectPos & 3))
            {
                dataSectPos += (4 - (dataSectPos % 4));
            }
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int  length;
                int  blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), "Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    Clauses.Add(clause);
                }
            }while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;
        }