예제 #1
0
        //#endregion

        public void Read(EndianAwareBinaryReader reader)
        {
            this.magic = reader.ReadUInt16();
            if (magic != magicConst)
            {
                throw new BadImageFormatException();
            }
            this.lastPageSize            = reader.ReadUInt16();
            this.pageCount               = reader.ReadUInt16();
            this.relocations             = reader.ReadUInt16();
            this.headerSize              = reader.ReadUInt16();
            this.minimumParagraphsNeeded = reader.ReadUInt16();
            this.maximumParagraphsNeeded = reader.ReadUInt16();
            this.initialStackSegment     = reader.ReadUInt16();
            this.initialStackPointer     = reader.ReadUInt16();
            this.checksum = reader.ReadUInt16();
            this.initialInstructionPointer = reader.ReadUInt16();
            this.initialCodeSegment        = reader.ReadUInt16();
            this.relocationTablePtr        = reader.ReadUInt16();
            this.overlayNumber             = reader.ReadUInt16();
            this.reserved        = reader.ReadUInt64();
            this.oemIdentifier   = reader.ReadUInt16();
            this.oemInformation  = reader.ReadUInt16();
            this.reserved2A      = reader.ReadUInt64();
            this.reserved2B      = reader.ReadUInt64();
            this.reserved2C      = reader.ReadUInt32();
            this.peHeaderPointer = reader.ReadUInt32();
        }
예제 #2
0
        /// <summary>
        /// Reads elf header
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void Read32(EndianAwareBinaryReader reader)
        {
            Ident = reader.ReadBytes(16);

            // Check for magic number
            if (Ident[0] != MagicNumber[0] || Ident[1] != MagicNumber[1] || Ident[2] != MagicNumber[2] || Ident[3] != MagicNumber[3])
            {
                // Magic number not present, so it seems to be an invalid ELF file
                throw new NotSupportedException("This is not a valid ELF file");
            }

            Type                = (FileType)reader.ReadUInt16();
            Machine             = (MachineType)reader.ReadUInt16();
            Version             = (Version)reader.ReadUInt32();
            EntryAddress        = reader.ReadUInt32();
            ProgramHeaderOffset = reader.ReadUInt32();
            SectionHeaderOffset = reader.ReadUInt32();
            Flags               = reader.ReadUInt32();

            //ElfHeaderSize = reader.ReadUInt16();
            //ProgramHeaderEntrySize = reader.ReadUInt16();
            ProgramHeaderNumber = reader.ReadUInt16();

            //SectionHeaderEntrySize = reader.ReadUInt16();
            SectionHeaderNumber      = reader.ReadUInt16();
            SectionHeaderStringIndex = reader.ReadUInt16();
        }
예제 #3
0
        public readonly int Unknown15; // always 0

        public Layer(EndianAwareBinaryReader reader)
        {
            LayerType       = (LayerType)reader.ReadUInt32();
            Flags           = reader.ReadUInt32();
            Index           = reader.ReadInt32();
            TCES_Unknown3   = reader.ReadInt32();
            Unknown4        = reader.ReadInt32();
            Unknown5        = reader.ReadInt32();
            Unknown6        = reader.ReadInt32();
            PageOffset      = reader.ReadInt32();
            TotalLayerSize  = reader.ReadInt32();
            TotalLayerSize2 = reader.ReadInt32();
            PageSize        = reader.ReadInt32();
            Unknown11       = reader.ReadInt32();
            Unknown12       = reader.ReadInt32();
            Unknown13       = reader.ReadInt32();
            SubLayerOffset  = reader.ReadInt32();
            Unknown15       = reader.ReadInt32();

            // flags are always BE
            if (!reader.IsBigEndian)
            {
                Flags = BinaryPrimitives.ReverseEndianness(Flags);
            }
        }
예제 #4
0
 internal void Read(EndianAwareBinaryReader reader)
 {
     this.signature = reader.ReadUInt32();
     if (signature != peSignature)
     {
         throw new BadImageFormatException();
     }
     this.machine                 = (PEImageMachine)reader.ReadUInt16();
     this.sectionCount            = reader.ReadUInt16();
     this.secondsElapsedSinceEpoc = reader.ReadUInt32();
     this.symbolTableRVAndSize.Read(reader);
     this.optionalHeaderSize = reader.ReadUInt16();
     this.characteristics    = (CoffStandardCharacteristics)reader.ReadUInt16();
 }
예제 #5
0
        // FIXME: public byte[] ImageHash;

        #endregion Data members

        #region Methods

        /// <summary>
        /// Loads the CLI_HEADER from the reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            Cb = reader.ReadUInt32();
            MajorRuntimeVersion = reader.ReadUInt16();
            MinorRuntimeVersion = reader.ReadUInt16();
            Metadata.Read(reader);
            Flags           = (RuntimeImageFlags)reader.ReadUInt32();
            EntryPointToken = reader.ReadUInt32();
            Resources.Read(reader);
            StrongNameSignature.Read(reader);
            CodeManagerTable.Read(reader);
            VTableFixups.Read(reader);
            ExportAddressTableJumps.Read(reader);
            ManagedNativeHeader.Read(reader);
        }
예제 #6
0
 internal uint ReadIndex(EndianAwareBinaryReader reader)
 {
     if (this.Size > ushort.MaxValue)
     {
         return(reader.ReadUInt32());
     }
     return(reader.ReadUInt16());
 }
예제 #7
0
        /// <summary>
        /// Loads and validates the image file header.
        /// </summary>
        /// <param name="reader">The reader, to read From.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            this.Signature = reader.ReadUInt32();
            if (this.Signature != PE_SIGNATURE)
                throw new BadImageFormatException();

            this.FileHeader.Read(reader);
            this.OptionalHeader.Read(reader);
        }
예제 #8
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;
            }
        }
예제 #9
0
        /// <summary>
        /// Loads and validates the image file header.
        /// </summary>
        /// <param name="reader">The reader, to read From.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            this.Signature = reader.ReadUInt32();
            if (this.Signature != PE_SIGNATURE)
            {
                throw new BadImageFormatException();
            }

            this.FileHeader.Read(reader);
            this.OptionalHeader.Read(reader);
        }
예제 #10
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();
                }
            }
예제 #11
0
        public AssetEntry(EndianAwareBinaryReader reader, Layer layer)
        {
            Layer = layer;

            Size = reader.ReadInt32();
            RelativeDataOffset = reader.ReadInt32();
            DataSize           = reader.ReadInt32();
            Unknown1           = reader.ReadInt32();
            AssetID            = reader.ReadUInt64(); // this might be a hash of the filepath?
            AssetType          = (AssetType)reader.ReadUInt32();
            Unknown2           = reader.ReadInt16();
            Unknown3           = reader.ReadInt16();
        }
예제 #12
0
        public uint GetTypeFromMethodIndex(uint methodIndex)
        {
            /* *
             * String occupies Bit  2
             * Extends Occupies Bit 3
             * Field Occupies Bit   0
             * Method Occupies Bit  1
             * */
            bool s             = (this.state & 0x4) == 0x4,
                 e             = (this.state & 0x8) == 0x8,
                 f             = (this.state & 0x1) == 0x1,
                 m             = (this.state & 0x2) == 0x2;
            long offset        = this.streamOffset;
            int  miOffset      = 4 + (s ? 8 : 4) + (e ? 4 : 2) + (f ? 4 : 2);
            var  size          = this.__size;
            bool possibleMatch = false;

            for (uint i = 1; i <= this.Count - 1; i++, offset += size)
            {
                uint methodStartIndex;

                if (this.ItemLoaded(i))
                {
                    methodStartIndex = this[(int)i].MethodStartIndex;
                }
                else
                {
                    lock (this.syncObject)
                    {
                        this.reader.BaseStream.Seek(offset + miOffset, SeekOrigin.Begin);
                        if (m)
                        {
                            methodStartIndex = reader.ReadUInt32();
                        }
                        else
                        {
                            methodStartIndex = reader.ReadUInt16();
                        }
                    }
                }
                if (!possibleMatch && methodStartIndex <= methodIndex)
                {
                    possibleMatch = true;
                }
                else if (possibleMatch && methodStartIndex > methodIndex)
                {
                    return(i - 1);
                }
            }
            return((uint)this.Count);
        }
예제 #13
0
        internal static CoffSection Read(EndianAwareBinaryReader reader, bool keepImageOpen)
        {
            byte[] name = new byte[sizeOfName];
            reader.Read(name, 0, sizeOfName);
            var         actualName = GetNameFor(name);
            CoffSection result;

            switch (actualName)
            {
            case ".reloc":
                result = new CoffRelocSection();
                break;

            default:
                result = new CoffSection();
                break;
            }

            result.name                 = name;
            result._name                = actualName;
            result.virtualSize          = reader.ReadUInt32();
            result.virtualAddress       = reader.ReadUInt32();
            result.sizeOfRawData        = reader.ReadUInt32();
            result.pointerToRawData     = reader.ReadUInt32();
            result.pointerToRelocations = reader.ReadUInt32();
            result.pointerToLineNumbers = reader.ReadUInt32();
            result.numberOfRelocations  = reader.ReadUInt16();
            result.numberOfLineNumbers  = reader.ReadUInt16();
            result.characteristics      = (CoffSectionCharacteristics)reader.ReadUInt32();
            result.sectionData          = new Substream(reader.BaseStream, result.pointerToRawData, result.virtualSize);
            result.keepImageOpen        = keepImageOpen;
            if (result.HasCustomRead)
            {
                using (var subReader = new EndianAwareBinaryReader(result.sectionData, reader.TargetEndianess, reader.BitEndianness, true))
                    result.CustomRead(subReader);
            }
            //if (bufferSectionData)
            //{
            //    if (!reader.BaseStream.CanSeek)
            //        throw new InvalidOperationException();
            //    ReadSectionData(reader, result);
            //}
            //else
            //    result.sectionDataReader = reader;
            return(result);
        }
 internal void Read(EndianAwareBinaryReader reader)
 {
     this.imageBase        = reader.ReadUInt64();
     this.sectionAlignment = reader.ReadUInt32();
     this.fileAlignment    = reader.ReadUInt32();
     this.osVersion.Read(reader);
     this.binaryVersion.Read(reader);
     this.subsystemVersion.Read(reader);
     this.reserved           = reader.ReadUInt32();
     this.imageSize          = reader.ReadUInt32();
     this.headerSize         = reader.ReadUInt32();
     this.fileChecksum       = reader.ReadUInt32();
     this.subsystem          = (PEImageSubsystem)reader.ReadUInt16();
     this.dllCharacteristics = (PEImageDllCharacteristics)reader.ReadUInt16();
     this.stackReserveSize   = reader.ReadUInt64();
     this.stackCommitSize    = reader.ReadUInt64();
     this.heapReserveSize    = reader.ReadUInt64();
     this.heapCommitSize     = reader.ReadUInt64();
     this.loaderFlags        = reader.ReadUInt32();
     this.dataDirectoryCount = reader.ReadUInt32();
 }
예제 #15
0
        /// <summary>
        /// Loads and validates the DOS header.
        /// </summary>
        public void Read(EndianAwareBinaryReader reader)
        {
            e_magic    = reader.ReadUInt16();
            e_cblp     = reader.ReadUInt16();
            e_cp       = reader.ReadUInt16();
            e_crlc     = reader.ReadUInt16();
            e_cparhdr  = reader.ReadUInt16();
            e_minalloc = reader.ReadUInt16();
            e_maxalloc = reader.ReadUInt16();
            e_ss       = reader.ReadUInt16();
            e_sp       = reader.ReadUInt16();
            e_csum     = reader.ReadUInt16();
            e_ip       = reader.ReadUInt16();
            e_cs       = reader.ReadUInt16();
            e_lfarlc   = reader.ReadUInt16();
            e_ovno     = reader.ReadUInt16();
            e_res00    = reader.ReadUInt16();
            e_res01    = reader.ReadUInt16();
            e_res02    = reader.ReadUInt16();
            e_res03    = reader.ReadUInt16();
            e_oemid    = reader.ReadUInt16();
            e_oeminfo  = reader.ReadUInt16();
            e_res20    = reader.ReadUInt16();
            e_res21    = reader.ReadUInt16();
            e_res22    = reader.ReadUInt16();
            e_res23    = reader.ReadUInt16();
            e_res24    = reader.ReadUInt16();
            e_res25    = reader.ReadUInt16();
            e_res26    = reader.ReadUInt16();
            e_res27    = reader.ReadUInt16();
            e_res28    = reader.ReadUInt16();
            e_res29    = reader.ReadUInt16();
            e_lfanew   = reader.ReadUInt32();

            if (DOS_HEADER_MAGIC != e_magic)
            {
                throw new BadImageFormatException();
            }
        }
예제 #16
0
        public readonly int Unknown15; // always 0

        public TCES(EndianAwareBinaryReader reader)
        {
            Flags        = reader.ReadUInt32();
            Unknown2     = reader.ReadInt32();
            Unknown3     = reader.ReadInt32();
            Size         = reader.ReadInt32();
            Unknown5     = reader.ReadInt32();
            Unknown6     = reader.ReadInt32();
            PageOffset   = reader.ReadInt32(); // << 11
            SectionSize  = reader.ReadInt32();
            SectionSize2 = reader.ReadInt32();
            Unknown10    = reader.ReadInt32();
            Unknown11    = reader.ReadInt32();
            Unknown12    = reader.ReadInt32();
            Unknown13    = reader.ReadInt32();
            Unknown14    = reader.ReadInt32();
            Unknown15    = reader.ReadInt32();

            // flags are always BE
            if (!reader.IsBigEndian)
            {
                Flags = BinaryPrimitives.ReverseEndianness(Flags);
            }
        }
        /// <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);
            }
        }
예제 #18
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);
        }
예제 #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>
        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;
        }
예제 #20
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();
                }
            }
        }
예제 #21
0
 /// <summary>
 /// Loads the IMAGE_DATA_DIRECTORY from the reader.
 /// </summary>
 /// <param name="reader">The reader.</param>
 public void Read(EndianAwareBinaryReader reader)
 {
     VirtualAddress = reader.ReadUInt32();
     Size = reader.ReadInt32();
 }
예제 #22
0
        public static void PatchSyslinux_6_03(PartitionDevice partitionDevice, FatFileSystem fat)
        {
            // Locate ldlinux.sys file for patching
            string filename = "ldlinux.sys";
            string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

            var location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

            if (!location.IsValid)
                throw new InvalidProgramException("Unable to find syslinux.sys");

            // Get the file size & number of sectors used
            uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);

            var sectors = new List<uint>();

            // Create list of the sectors of the file
            for (uint cluster = location.FirstCluster; (cluster != 0); cluster = fat.GetNextCluster(cluster))
            {
                uint sec = fat.GetSectorByCluster(cluster);
                for (uint i = 0; i < fat.SectorsPerCluster; i++)
                {
                    sectors.Add(sec + i);
                }
            }

            // Get the ldlinux.sys file stream
            var ldlinux = new FatFileStream(fat, location);

            var ldlinuxReader = new EndianAwareBinaryReader(ldlinux, Endianness.Little);

            // Search for 0x3EB202FE (magic)
            while ((ldlinuxReader.ReadUInt32() != Syslinux.LDLINUX_MAGIC) && (ldlinux.Position < ldlinux.Length)) ;

            if (ldlinux.Position >= ldlinux.Length || ldlinux.Position <= 0)
                throw new InvalidProgramException("Unable to find patch location for syslinux");

            uint patchArea = (uint)ldlinux.Position - 4;

            // Get Extended Patch Area offset
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.EPAOffset;
            ushort epa = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr0;
            uint sect1Ptr0 = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr1;
            uint sect1Ptr1 = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrOffset;
            uint ex = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrCnt;
            uint nptrs = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.AdvPtrOffset;
            uint advptrs = (uint)ldlinuxReader.ReadUInt16();

            if (sectors.Count > nptrs)
                throw new InvalidProgramException("Insufficient space for patching syslinux");

            var ldlinuxWriter = new EndianAwareBinaryWriter(ldlinux, Endianness.Little);

            // Set up the totals
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)sectors.Count);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)2);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((uint)fileSize >> 2);

            // Generate Extents
            var extents = GenerateExtents(sectors);

            ldlinux.Position = ex;

            // Write out extents
            foreach (var extent in extents)
            {
                ldlinuxWriter.Write((ulong)extent.Start);
                ldlinuxWriter.Write((ushort)extent.Length);
            }

            // Write out ADV
            ldlinux.Position = advptrs;
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 2]);
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 1]);

            // Clear out checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write((uint)0);

            // Write back the updated cluster
            ldlinuxWriter.Flush();

            // Re-Calculate checksum
            ldlinux.Position = 0;
            uint csum = Syslinux.LDLINUX_MAGIC;
            for (uint index = 0; index < (ldlinux.Length >> 2); index++)
            {
                csum = csum + ldlinuxReader.ReadUInt32();
            }

            // Set the checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write(csum);

            // Write patched cluster back to disk
            ldlinuxWriter.Flush();

            // Read boot sector
            var fatBootSector = new BinaryFormat(partitionDevice.ReadBlock(0, 1));

            // Set the first sector location of the file
            fatBootSector.SetUInt(sect1Ptr0, fat.GetSectorByCluster(location.FirstCluster));
            fatBootSector.SetUInt(sect1Ptr1, 0);   // since only 32-bit offsets are support, the high portion of 64-bit value is zero

            // Write back patched boot sector
            partitionDevice.WriteBlock(0, 1, fatBootSector.Data);
        }
예제 #23
0
파일: Header.cs 프로젝트: tea/MOSA-Project
        /// <summary>
        /// Reads the specified reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            Ident = reader.ReadBytes(16);

            // Check for magic number
            if (Ident[0] != MagicNumber[0] || Ident[1] != MagicNumber[1] || Ident[2] != MagicNumber[2] || Ident[3] != MagicNumber[3])
            {
                // Magic number not present, so it seems to be an invalid ELF file
                throw new NotSupportedException("This is not a valid ELF file");
            }

            Type = (FileType)reader.ReadUInt16();
            Machine = (MachineType)reader.ReadUInt16();
            Version = (Version)reader.ReadUInt32();
            EntryAddress = reader.ReadUInt32();
            ProgramHeaderOffset = reader.ReadUInt32();
            SectionHeaderOffset = reader.ReadUInt32();
            Flags = reader.ReadUInt32();
            ElfHeaderSize = reader.ReadUInt16();
            ProgramHeaderEntrySize = reader.ReadUInt16();
            ProgramHeaderNumber = reader.ReadUInt16();
            SectionHeaderEntrySize = reader.ReadUInt16();
            SectionHeaderNumber = reader.ReadUInt16();
            SectionHeaderStringIndex = reader.ReadUInt16();
        }
예제 #24
0
 internal void Read(EndianAwareBinaryReader reader)
 {
     this.relativeVirtualAddress = reader.ReadUInt32();
     this.size = reader.ReadUInt32();
 }
예제 #25
0
 /// <summary>
 /// Loads the IMAGE_DATA_DIRECTORY from the reader.
 /// </summary>
 /// <param name="reader">The reader.</param>
 public void Read(EndianAwareBinaryReader reader)
 {
     VirtualAddress = reader.ReadUInt32();
     Size           = reader.ReadInt32();
 }
예제 #26
0
        /// <summary>
        /// Reads the root structure from the metadata.
        /// </summary>
        /// <param name="header">The <see cref="CliHeader"/> which denotes the location of the information.</param>
        /// <param name="originalStream">The <see cref="FileStream"/> being read from.</param>
        /// <param name="reader">The <see cref="EndianAwareBinaryReader"/> which handles reads.</param>
        /// <param name="relativeVirtualAddress">The <see cref="UInt32"/> value which denotes the relative
        /// virtual address of the metadata header.</param>
        /// <param name="sourceImage"></param>
        internal void Read(CliHeader header, FileStream originalStream, EndianAwareBinaryReader reader, uint relativeVirtualAddress, PEImage sourceImage)
        {
            this.originalStream = originalStream;
            this.header         = header;
            this.streamPosition = relativeVirtualAddress;
            this.signature      = reader.ReadUInt32();
            if (this.signature != metadataSignature)
            {
                throw new BadImageFormatException();
            }
            this.depreciatedVersion.Read(reader);
            this.reserved          = reader.ReadUInt32();
            this.realVersionLength = reader.ReadInt32();
            byte[] version = new byte[(this.realVersionLength + 3) & ~3];//Make it a multiple of four.
            reader.Read(version, 0, version.Length);
            this.version       = version;
            this.reservedFlags = reader.ReadUInt16();
            int streamCount = 0;

            streamCount      = reader.ReadUInt16();
            this.sourceImage = sourceImage;
            for (int i = 0; i < streamCount; i++)
            {
                var currentHeader = new CliMetadataStreamHeader();
                currentHeader.Read(reader, sourceImage);
                switch (currentHeader.Name)
                {
                case "#Strings":
                    if (this.strings != null)
                    {
                        goto sectionExists;
                    }
                    this.strings = new CliMetadataStringsHeaderAndHeap(currentHeader, sourceImage.SyncObject);
                    this.ScanAndReadSection(sourceImage, strings, this.strings.Read);
                    break;

                case "#Blob":
                    if (this.blob != null)
                    {
                        goto sectionExists;
                    }
                    this.blob = new CliMetadataBlobHeaderAndHeap(currentHeader, this);
                    this.ScanAndReadSection(sourceImage, blob, this.blob.Read);
                    break;

                case "#US":
                    if (this.userStrings != null)
                    {
                        goto sectionExists;
                    }
                    this.userStrings = new CliMetadataUserStringsHeaderAndHeap(currentHeader, sourceImage.SyncObject);
                    this.ScanAndReadSection(sourceImage, this.userStrings, this.userStrings.Read);
                    break;

                case "#GUID":
                    if (this.guids != null)
                    {
                        goto sectionExists;
                    }
                    this.guids = new CliMetadataGuidHeaderAndHeap(currentHeader, sourceImage.SyncObject);
                    this.ScanAndReadSection(sourceImage, guids, this.guids.Read);
                    break;

                case "#-":     //https://github.com/jbevain/cecil/blob/8b689ecdc890cbf3715ba8775de1d713d71f09f3/Mono.Cecil.PE/ImageReader.cs#L359
                case "#~":
                    if (this.tableStream != null)
                    {
                        goto sectionExists;
                    }
                    this.tableStream = new CliMetadataTableStreamAndHeader(currentHeader);
                    this.ScanAndReadSection(sourceImage, tableStream, sdReader => this.tableStream.Read(sdReader, this));
                    break;
                }
                continue;
sectionExists:
                throw new BadImageFormatException(string.Format("Duplicate {0} section encountered.", currentHeader.Name));
            }
            if (this.tableStream == null)
            {
                throw new BadImageFormatException("#~ or #- stream not present in image.");
            }
        }
예제 #27
0
        /// <summary>
        /// Loads and validates the DOS header.
        /// </summary>
        public void Read(EndianAwareBinaryReader reader)
        {
            e_magic = reader.ReadUInt16();
            e_cblp = reader.ReadUInt16();
            e_cp = reader.ReadUInt16();
            e_crlc = reader.ReadUInt16();
            e_cparhdr = reader.ReadUInt16();
            e_minalloc = reader.ReadUInt16();
            e_maxalloc = reader.ReadUInt16();
            e_ss = reader.ReadUInt16();
            e_sp = reader.ReadUInt16();
            e_csum = reader.ReadUInt16();
            e_ip = reader.ReadUInt16();
            e_cs = reader.ReadUInt16();
            e_lfarlc = reader.ReadUInt16();
            e_ovno = reader.ReadUInt16();
            e_res00 = reader.ReadUInt16();
            e_res01 = reader.ReadUInt16();
            e_res02 = reader.ReadUInt16();
            e_res03 = reader.ReadUInt16();
            e_oemid = reader.ReadUInt16();
            e_oeminfo = reader.ReadUInt16();
            e_res20 = reader.ReadUInt16();
            e_res21 = reader.ReadUInt16();
            e_res22 = reader.ReadUInt16();
            e_res23 = reader.ReadUInt16();
            e_res24 = reader.ReadUInt16();
            e_res25 = reader.ReadUInt16();
            e_res26 = reader.ReadUInt16();
            e_res27 = reader.ReadUInt16();
            e_res28 = reader.ReadUInt16();
            e_res29 = reader.ReadUInt16();
            e_lfanew = reader.ReadUInt32();

            if (DOS_HEADER_MAGIC != e_magic)
                throw new BadImageFormatException();
        }
예제 #28
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;
            }
        }
예제 #29
0
        /// <summary>
        /// Load the mesh from a stream
        /// </summary>
        /// <param name="filename">The filename and path of the file containing the mesh data</param>
        public virtual void LoadMesh(string filename)
        {
            using(FileStream meshData = new FileStream(filename, FileMode.Open, FileAccess.Read))
            using (EndianAwareBinaryReader reader = new EndianAwareBinaryReader(meshData))
            {
                Header = TrimAt0(reader.ReadString(24));
                if (!String.Equals(Header, MeshHeader))
                    throw new FileLoadException("Unrecognized mesh format");

                // Populate base mesh parameters
                HasWeights = (reader.ReadByte() != 0);
                HasDetailTexCoords = (reader.ReadByte() != 0);
                Position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                RotationAngles = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                /* RotationOrder = */ reader.ReadByte();
                Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                // Populate the vertex array
                NumVertices = reader.ReadUInt16();
                Vertices = new Vertex[NumVertices];
                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                if (HasDetailTexCoords)
                {
                    for (int i = 0; i < NumVertices; i++)
                        Vertices[i].DetailTexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                }

                if (HasWeights)
                {
                    for (int i = 0; i < NumVertices; i++)
                        Vertices[i].Weight = reader.ReadSingle();
                }

                NumFaces = reader.ReadUInt16();
                Faces = new Face[NumFaces];

                for (int i = 0; i < NumFaces; i++)
                    Faces[i].Indices = new[] { reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16() };

                if (HasWeights)
                {
                    NumSkinJoints = reader.ReadUInt16();
                    SkinJoints = new string[NumSkinJoints];

                    for (int i = 0; i < NumSkinJoints; i++)
                    {
                        SkinJoints[i] = TrimAt0(reader.ReadString(64));
                    }
                }
                else
                {
                    NumSkinJoints = 0;
                    SkinJoints = new string[0];
                }

                // Grab morphs
                List<Morph> morphs = new List<Morph>();
                string morphName = TrimAt0(reader.ReadString(64));

                while (morphName != MorphFooter)
                {
                    if (reader.BaseStream.Position + 48 >= reader.BaseStream.Length)
                        throw new FileLoadException("Encountered end of file while parsing morphs");

                    Morph morph = new Morph();
                    morph.Name = morphName;
                    morph.NumVertices = reader.ReadInt32();
                    morph.Vertices = new MorphVertex[morph.NumVertices];

                    for (int i = 0; i < morph.NumVertices; i++)
                    {
                        morph.Vertices[i].VertexIndex = reader.ReadUInt32();
                        morph.Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }

                    morphs.Add(morph);

                    // Grab the next name
                    morphName = TrimAt0(reader.ReadString(64));
                }

                Morphs = morphs.ToArray();

                // Check if there are remaps or if we're at the end of the file
                if (reader.BaseStream.Position < reader.BaseStream.Length - 1)
                {
                    NumRemaps = reader.ReadInt32();
                    VertexRemaps = new VertexRemap[NumRemaps];

                    for (int i = 0; i < NumRemaps; i++)
                    {
                        VertexRemaps[i].RemapSource = reader.ReadInt32();
                        VertexRemaps[i].RemapDestination = reader.ReadInt32();
                    }
                }
                else
                {
                    NumRemaps = 0;
                    VertexRemaps = new VertexRemap[0];
                }
            }

            // uncompress the skin weights
            if (Skeleton != null)
            {
                // some meshes aren't weighted, which doesn't make much sense.
                // we check for left and right eyeballs, and assign them a 100%
                // to their respective bone
                List<string> expandedJointList = Skeleton.BuildExpandedJointList(SkinJoints);
                if (expandedJointList.Count == 0)
                {
                    if (Name == "eyeBallLeftMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeLeft", "mSkull" });
                    }
                    else if (Name == "eyeBallRightMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeRight", "mSkull" });
                    }
                }

                if (expandedJointList.Count > 0)
                    ExpandCompressedSkinWeights(expandedJointList);
            }
        }
예제 #30
0
 /// <summary>
 /// Loads the CLI_HEADER from the reader.
 /// </summary>
 /// <param name="reader">The reader.</param>
 public void Read(EndianAwareBinaryReader reader)
 {
     Cb = reader.ReadUInt32();
     MajorRuntimeVersion = reader.ReadUInt16();
     MinorRuntimeVersion = reader.ReadUInt16();
     Metadata.Read(reader);
     Flags = (RuntimeImageFlags)reader.ReadUInt32();
     EntryPointToken = reader.ReadUInt32();
     Resources.Read(reader);
     StrongNameSignature.Read(reader);
     CodeManagerTable.Read(reader);
     VTableFixups.Read(reader);
     ExportAddressTableJumps.Read(reader);
     ManagedNativeHeader.Read(reader);
 }
예제 #31
0
        public static void PatchSyslinux_6_03(PartitionDeviceDriver partitionDevice, FatFileSystem fat)
        {
            // Locate ldlinux.sys file for patching
            string filename = "ldlinux.sys";
            string name     = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

            var location = fat.FindEntry(name);

            if (!location.IsValid)
            {
                throw new InvalidProgramException("Unable to find syslinux.sys");
            }

            // Get the file size & number of sectors used
            uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);

            var sectors = new List <uint>();

            // Create list of the sectors of the file
            for (uint cluster = location.FirstCluster; (cluster != 0); cluster = fat.GetNextCluster(cluster))
            {
                uint sec = fat.GetSectorByCluster(cluster);
                for (uint i = 0; i < fat.SectorsPerCluster; i++)
                {
                    sectors.Add(sec + i);
                }
            }

            // Get the ldlinux.sys file stream
            var ldlinux = new FatFileStream(fat, location);

            var ldlinuxReader = new EndianAwareBinaryReader(ldlinux, Endianness.Little);

            // Search for 0x3EB202FE (magic)
            while ((ldlinuxReader.ReadUInt32() != Syslinux.LDLINUX_MAGIC) && (ldlinux.Position < ldlinux.Length))
            {
                ;
            }

            if (ldlinux.Position >= ldlinux.Length || ldlinux.Position <= 0)
            {
                throw new InvalidProgramException("Unable to find patch location for syslinux");
            }

            uint patchArea = (uint)ldlinux.Position - 4;

            // Get Extended Patch Area offset
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.EPAOffset;
            ushort epa = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr0;
            uint sect1Ptr0 = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr1;
            uint sect1Ptr1 = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrOffset;
            uint ex = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrCnt;
            uint nptrs = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.AdvPtrOffset;
            uint advptrs = ldlinuxReader.ReadUInt16();

            if (sectors.Count > nptrs)
            {
                throw new InvalidProgramException("Insufficient space for patching syslinux");
            }

            var ldlinuxWriter = new EndianAwareBinaryWriter(ldlinux, Endianness.Little);

            // Set up the totals
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)sectors.Count);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)2);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write(fileSize >> 2);

            // Generate Extents
            var extents = GenerateExtents(sectors);

            ldlinux.Position = ex;

            // Write out extents
            foreach (var extent in extents)
            {
                ldlinuxWriter.Write(extent.Start);
                ldlinuxWriter.Write(extent.Length);
            }

            // Write out ADV
            ldlinux.Position = advptrs;
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 2]);
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 1]);

            // Clear out checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write((uint)0);

            // Write back the updated cluster
            ldlinuxWriter.Flush();

            // Re-Calculate checksum
            ldlinux.Position = 0;
            uint csum = Syslinux.LDLINUX_MAGIC;

            for (uint index = 0; index < (ldlinux.Length >> 2); index++)
            {
                csum = csum + ldlinuxReader.ReadUInt32();
            }

            // Set the checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write(csum);

            // Write patched cluster back to disk
            ldlinuxWriter.Flush();

            // Read boot sector
            var fatBootSector = new DataBlock(partitionDevice.ReadBlock(0, 1));

            // Set the first sector location of the file
            fatBootSector.SetUInt(sect1Ptr0, fat.GetSectorByCluster(location.FirstCluster));
            fatBootSector.SetUInt(sect1Ptr1, 0);               // since only 32-bit offsets are support, the high portion of 64-bit value is zero

            // Write back patched boot sector
            partitionDevice.WriteBlock(0, 1, fatBootSector.Data);
        }
예제 #32
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;
        }