Beispiel #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="reader">PE file reader pointing to the start of this section</param>
 /// <param name="verify">Verify section</param>
 /// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
 public MetaDataHeader(IImageStream reader, bool verify)
 {
     SetStartOffset(reader);
     //Interaction.MsgBox(reader.Position);
     this.signature = reader.ReadUInt32();
     if (verify && this.signature != 0x424A5342)
     {
         throw new BadImageFormatException("Invalid MetaData header signature");
     }
     this.majorVersion = reader.ReadUInt16();
     this.minorVersion = reader.ReadUInt16();
     if (verify && !((majorVersion == 1 && minorVersion == 1) || (majorVersion == 0 && minorVersion >= 19)))
     {
         throw new BadImageFormatException(string.Format("Unknown MetaData header version: {0}.{1}", majorVersion, minorVersion));
     }
     this.reserved1     = reader.ReadUInt32();
     this.stringLength  = reader.ReadUInt32();
     this.versionString = ReadString(reader, stringLength);
     this.offset2ndPart = reader.FileOffset + reader.Position;
     this.flags         = (StorageFlags)reader.ReadByte();
     this.reserved2     = reader.ReadByte();
     this.streams       = reader.ReadUInt16();
     this.streamHeaders = new StreamHeader[streams];
     for (int i = 0; i < streamHeaders.Count; i++)
     {
         streamHeaders[i] = new StreamHeader(reader, verify);
     }
     SetEndoffset(reader);
 }
Beispiel #2
0
        bool StringsStreamNameEquals(IImageStream stringsStream, uint offset, byte[] nameData)
        {
            if (offset == 0)
            {
                return(nameData.Length == 0);
            }
            stringsStream.Position = offset;
            long pos = offset;
            var  end = stringsStream.Length;

            for (int i = 0; i < nameData.Length; i++)
            {
                if (pos >= end)
                {
                    return(false);
                }
                if (stringsStream.ReadByte() != nameData[i])
                {
                    return(false);
                }
            }
            if (pos >= end)
            {
                return(false);
            }
            return(stringsStream.ReadByte() == 0);
        }
Beispiel #3
0
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="reader">PE file reader pointing to the start of this section</param>
 /// <param name="verify">Verify section</param>
 /// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
 public MetaDataHeader(IImageStream reader, bool verify)
 {
     SetStartOffset(reader);
     Signature = reader.ReadUInt32();
     if (verify && Signature != 0x424A5342)
     {
         throw new BadImageFormatException("Invalid MetaData header signature");
     }
     MajorVersion = reader.ReadUInt16();
     MinorVersion = reader.ReadUInt16();
     if (verify && !(MajorVersion == 1 && MinorVersion == 1 || MajorVersion == 0 && MinorVersion >= 19))
     {
         throw new BadImageFormatException(string.Format("Unknown MetaData header version: {0}.{1}", MajorVersion, MinorVersion));
     }
     Reserved1           = reader.ReadUInt32();
     StringLength        = reader.ReadUInt32();
     VersionString       = ReadString(reader, StringLength);
     StorageHeaderOffset = reader.FileOffset + reader.Position;
     Flags         = (StorageFlags)reader.ReadByte();
     Reserved2     = reader.ReadByte();
     Streams       = reader.ReadUInt16();
     StreamHeaders = new StreamHeader[Streams];
     for (var i = 0; i < StreamHeaders.Count; i++)
     {
         StreamHeaders[i] = new StreamHeader(reader, verify);
     }
     SetEndoffset(reader);
 }
Beispiel #4
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="reader">PE file reader pointing to the start of this section</param>
 /// <param name="totalSize">Total size of this optional header (from the file header)</param>
 /// <param name="verify">Verify section</param>
 /// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
 public ImageOptionalHeader32(IImageStream reader, uint totalSize, bool verify)
 {
     if (totalSize < 0x60)
     {
         throw new BadImageFormatException("Invalid optional header size");
     }
     if (verify && reader.Position + totalSize > reader.Length)
     {
         throw new BadImageFormatException("Invalid optional header size");
     }
     SetStartOffset(reader);
     this.magic = reader.ReadUInt16();
     this.majorLinkerVersion      = reader.ReadByte();
     this.minorLinkerVersion      = reader.ReadByte();
     this.sizeOfCode              = reader.ReadUInt32();
     this.sizeOfInitializedData   = reader.ReadUInt32();
     this.sizeOfUninitializedData = reader.ReadUInt32();
     this.addressOfEntryPoint     = (RVA)reader.ReadUInt32();
     this.baseOfCode              = (RVA)reader.ReadUInt32();
     this.baseOfData              = (RVA)reader.ReadUInt32();
     this.imageBase                   = reader.ReadUInt32();
     this.sectionAlignment            = reader.ReadUInt32();
     this.fileAlignment               = reader.ReadUInt32();
     this.majorOperatingSystemVersion = reader.ReadUInt16();
     this.minorOperatingSystemVersion = reader.ReadUInt16();
     this.majorImageVersion           = reader.ReadUInt16();
     this.minorImageVersion           = reader.ReadUInt16();
     this.majorSubsystemVersion       = reader.ReadUInt16();
     this.minorSubsystemVersion       = reader.ReadUInt16();
     this.win32VersionValue           = reader.ReadUInt32();
     this.sizeOfImage                 = reader.ReadUInt32();
     this.sizeOfHeaders               = reader.ReadUInt32();
     this.checkSum            = reader.ReadUInt32();
     this.subsystem           = (Subsystem)reader.ReadUInt16();
     this.dllCharacteristics  = (DllCharacteristics)reader.ReadUInt16();
     this.sizeOfStackReserve  = reader.ReadUInt32();
     this.sizeOfStackCommit   = reader.ReadUInt32();
     this.sizeOfHeapReserve   = reader.ReadUInt32();
     this.sizeOfHeapCommit    = reader.ReadUInt32();
     this.loaderFlags         = reader.ReadUInt32();
     this.numberOfRvaAndSizes = reader.ReadUInt32();
     for (int i = 0; i < dataDirectories.Length; i++)
     {
         uint len = (uint)(reader.Position - startOffset);
         if (len + 8 <= totalSize)
         {
             dataDirectories[i] = new ImageDataDirectory(reader, verify);
         }
         else
         {
             dataDirectories[i] = new ImageDataDirectory();
         }
     }
     reader.Position = (long)startOffset + totalSize;
     SetEndoffset(reader);
 }
Beispiel #5
0
        char[] ReadSeparatorChar(IImageStream stream, out int charLength)
        {
            if (prevSepCharBytesCount != 0 && prevSepCharBytesCount <= stream.Length)
            {
                var  pos = stream.Position;
                bool ok  = true;
                for (int i = 0; i < prevSepCharBytesCount; i++)
                {
                    if (i >= prevSepCharBytes.Length || stream.ReadByte() != prevSepCharBytes[i])
                    {
                        ok = false;
                        break;
                    }
                }
                if (ok)
                {
                    charLength = prevSepCharsLength;
                    return(prevSepChars);
                }
                stream.Position = pos;
            }

            var decoder = Encoding.UTF8.GetDecoder();
            var bytes   = new byte[1];

            prevSepCharBytesCount = 0;
            for (int i = 0; ; i++)
            {
                byte b = stream.ReadByte();
                prevSepCharBytesCount++;
                if (i == 0 && b == 0)
                {
                    break;
                }
                if (i < prevSepCharBytes.Length)
                {
                    prevSepCharBytes[i] = b;
                }
                bytes[0] = b;
                bool isLastByte = stream.Position + 1 == stream.Length;
                int  bytesUsed;
                bool completed;
                decoder.Convert(bytes, 0, 1, prevSepChars, 0, prevSepChars.Length, isLastByte, out bytesUsed, out prevSepCharsLength, out completed);
                if (prevSepCharsLength > 0)
                {
                    break;
                }
            }
            charLength = prevSepCharsLength;
            return(prevSepChars);
        }
        static string ReadString(IImageStream reader, int maxLen, bool verify)
        {
            var origPos = reader.Position;
            var sb      = new StringBuilder(maxLen);
            int i;

            for (i = 0; i < maxLen; i++)
            {
                byte b = reader.ReadByte();
                if (b == 0)
                {
                    break;
                }
                sb.Append((char)b);
            }
            if (verify && i == maxLen)
            {
                throw new BadImageFormatException("Invalid stream name string");
            }
            if (i != maxLen)
            {
                reader.Position = origPos + ((i + 1 + 3) & ~3);
            }
            return(sb.ToString());
        }
		void Populate(IImageStream reader) {
			var chars = new char[0x200];
			reader.Position = 1;
			while (reader.Position < reader.Length) {
				uint offset = (uint)reader.Position;
				uint len;
				if (!reader.ReadCompressedUInt32(out len)) {
					if (offset == reader.Position)
						reader.Position++;
					continue;
				}
				if (len == 0 || reader.Position + len > reader.Length)
					continue;

				int stringLen = (int)len / 2;
				if (stringLen > chars.Length)
					Array.Resize(ref chars, stringLen);
				for (int i = 0; i < stringLen; i++)
					chars[i] = (char)reader.ReadUInt16();
				if ((len & 1) != 0)
					reader.ReadByte();
				var s = new string(chars, 0, stringLen);

				if (!cachedDict.ContainsKey(s))
					cachedDict[s] = offset;
			}
		}
Beispiel #8
0
        void Populate(IImageStream reader)
        {
            reader.Position = 1;
            while (reader.Position < reader.Length)
            {
                uint offset = (uint)reader.Position;
                var  bytes  = reader.ReadBytesUntilByte(0);
                if (bytes == null)
                {
                    break;
                }

                reader.ReadByte();                      // terminating zero
                if (bytes.Length == 0)
                {
                    continue;
                }

                var s = new UTF8String(bytes);
                if (!cachedDict.ContainsKey(s))
                {
                    cachedDict[s] = offset;
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Reads the signature
        /// </summary>
        /// <returns>A new <see cref="CallingConventionSig"/> instance or <c>null</c> if invalid signature</returns>
        CallingConventionSig ReadSig()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            CallingConventionSig result;
            var callingConvention = (CallingConvention)reader.ReadByte();

            switch (callingConvention & CallingConvention.Mask)
            {
            case CallingConvention.Default:
            case CallingConvention.C:
            case CallingConvention.StdCall:
            case CallingConvention.ThisCall:
            case CallingConvention.FastCall:
            case CallingConvention.VarArg:
                result = ReadMethod(callingConvention);
                break;

            case CallingConvention.Field:
                result = ReadField(callingConvention);
                break;

            case CallingConvention.LocalSig:
                result = ReadLocalSig(callingConvention);
                break;

            case CallingConvention.Property:
                result = ReadProperty(callingConvention);
                break;

            case CallingConvention.GenericInst:
                result = ReadGenericInstMethod(callingConvention);
                break;

            case CallingConvention.Unmanaged:
            case CallingConvention.NativeVarArg:
            default:
                result = null;
                break;
            }

            recursionCounter.Decrement();
            return(result);
        }
 public int ReadByte()
 {
     if (stream != null)
     {
         return(stream.ReadByte());
     }
     return(-1);
 }
Beispiel #11
0
        void ReadFiles(PdbReader reader, Dictionary <long, DbiDocument> documents, IImageStream stream, long end)
        {
            var begin = stream.Position;

            while (stream.Position < end)
            {
                var id = stream.Position - begin;

                var nameId = stream.ReadUInt32();
                var len    = stream.ReadByte();
                /*var type = */ stream.ReadByte();
                var doc = reader.GetDocument(nameId);
                documents.Add(id, doc);

                stream.Position += len;
                stream.Position  = (stream.Position + 3) & (~3);
            }
        }
Beispiel #12
0
 static bool ReadAndCompareBytes(IImageStream stream, long end, byte[] bytes)
 {
     if (stream.Position + bytes.Length > end)
     {
         return(false);
     }
     for (int i = 0; i < bytes.Length; i++)
     {
         if (stream.ReadByte() != bytes[i])
         {
             return(false);
         }
     }
     return(true);
 }
		static string ReadString(IImageStream reader, int maxLen, bool verify) {
			var origPos = reader.Position;
			var sb = new StringBuilder(maxLen);
			int i;
			for (i = 0; i < maxLen; i++) {
				byte b = reader.ReadByte();
				if (b == 0)
					break;
				sb.Append((char)b);
			}
			if (verify && i == maxLen)
				throw new BadImageFormatException("Invalid stream name string");
			if (i != maxLen)
				reader.Position = origPos + ((i + 1 + 3) & ~3);
			return sb.ToString();
		}
		void Populate(IImageStream reader) {
			reader.Position = 1;
			while (reader.Position < reader.Length) {
				uint offset = (uint)reader.Position;
				var bytes = reader.ReadBytesUntilByte(0);
				if (bytes == null)
					break;

				reader.ReadByte();	// terminating zero
				if (bytes.Length == 0)
					continue;

				var s = new UTF8String(bytes);
				if (!cachedDict.ContainsKey(s))
					cachedDict[s] = offset;
			}
		}
Beispiel #15
0
        public string ReadInstrution(Instruction instr)
        {
            if (stream == null)
            {
                return(string.Empty);
            }
            int instructionSize = instr.GetSize();

            stream.Position = instr.Offset;
            var sb = new StringBuilder();

            for (int i = 0; i < instructionSize; i++)
            {
                sb.AppendFormat("{0:X2}", stream.ReadByte());
            }
            return(sb.ToString());
        }
Beispiel #16
0
        void Populate(IImageStream reader)
        {
            var chars = new char[0x200];

            reader.Position = 1;
            while (reader.Position < reader.Length)
            {
                uint offset = (uint)reader.Position;
                uint len;
                if (!reader.ReadCompressedUInt32(out len))
                {
                    if (offset == reader.Position)
                    {
                        reader.Position++;
                    }
                    continue;
                }
                if (len == 0 || reader.Position + len > reader.Length)
                {
                    continue;
                }

                int stringLen = (int)len / 2;
                if (stringLen > chars.Length)
                {
                    Array.Resize(ref chars, stringLen);
                }
                for (int i = 0; i < stringLen; i++)
                {
                    chars[i] = (char)reader.ReadUInt16();
                }
                if ((len & 1) != 0)
                {
                    reader.ReadByte();
                }
                var s = new string(chars, 0, stringLen);

                if (!cachedDict.ContainsKey(s))
                {
                    cachedDict[s] = offset;
                }
            }
        }
Beispiel #17
0
        static string ReadString(IImageStream reader, uint maxLength)
        {
            long endPos = reader.Position + maxLength;

            if (endPos < reader.Position || endPos > reader.Length)
            {
                throw new BadImageFormatException("Invalid MD version string");
            }
            byte[] utf8Bytes = new byte[maxLength];
            uint   i;

            for (i = 0; i < maxLength; i++)
            {
                byte b = reader.ReadByte();
                if (b == 0)
                {
                    break;
                }
                utf8Bytes[i] = b;
            }
            reader.Position = endPos;
            return(Encoding.UTF8.GetString(utf8Bytes, 0, (int)i));
        }
Beispiel #18
0
        bool ReadCore(out TypeSig type, out object value)
        {
            if (!recursionCounter.Increment())
            {
                type  = null;
                value = null;
                return(false);
            }

            bool          res;
            ITypeDefOrRef tdr;
            UTF8String    ns, name;
            var           et = (ElementType)reader.ReadByte();

            switch (et)
            {
            case ElementType.Boolean:
                type  = module.CorLibTypes.Boolean;
                value = reader.ReadBoolean();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.Char:
                type  = module.CorLibTypes.Char;
                value = (char)reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I1:
                type  = module.CorLibTypes.SByte;
                value = reader.ReadSByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U1:
                type  = module.CorLibTypes.Byte;
                value = reader.ReadByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I2:
                type  = module.CorLibTypes.Int16;
                value = reader.ReadInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U2:
                type  = module.CorLibTypes.UInt16;
                value = reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I4:
                type  = module.CorLibTypes.Int32;
                value = reader.ReadInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U4:
                type  = module.CorLibTypes.UInt32;
                value = reader.ReadUInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I8:
                type  = module.CorLibTypes.Int64;
                value = reader.ReadInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U8:
                type  = module.CorLibTypes.UInt64;
                value = reader.ReadUInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.R4:
                type  = module.CorLibTypes.Single;
                value = reader.ReadSingle();
                res   = true;
                break;

            case ElementType.R8:
                type  = module.CorLibTypes.Double;
                value = reader.ReadDouble();
                res   = true;
                break;

            case ElementType.String:
                type  = module.CorLibTypes.String;
                value = ReadString();
                res   = true;
                break;

            case ElementType.Ptr:
                res = Read(out type, out value);
                if (res)
                {
                    type = new PtrSig(type);
                }
                break;

            case ElementType.ByRef:
                res = Read(out type, out value);
                if (res)
                {
                    type = new ByRefSig(type);
                }
                break;

            case ElementType.Object:
                type  = module.CorLibTypes.Object;
                value = null;
                res   = true;
                break;

            case ElementType.ValueType:
                tdr   = ReadTypeDefOrRef();
                type  = tdr.ToTypeSig();
                value = null;
                if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib())
                {
                    if (name == stringDecimal)
                    {
                        if (reader.Length - reader.Position != 13)
                        {
                            goto default;
                        }
                        try {
                            byte b = reader.ReadByte();
                            value = new Decimal(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), (b & 0x80) != 0, (byte)(b & 0x7F));
                        }
                        catch {
                            goto default;
                        }
                    }
                    else if (name == stringDateTime)
                    {
                        if (reader.Length - reader.Position != 8)
                        {
                            goto default;
                        }
                        try {
                            value = new DateTime(reader.ReadInt64());
                        }
                        catch {
                            goto default;
                        }
                    }
                }
                if (value == null && reader.Position != reader.Length)
                {
                    value = reader.ReadRemainingBytes();
                }
                res = true;
                break;

            case ElementType.Class:
                type  = new ClassSig(ReadTypeDefOrRef());
                value = reader.Position == reader.Length ? null : reader.ReadRemainingBytes();
                res   = true;
                break;

            case ElementType.CModReqd:
                tdr = ReadTypeDefOrRef();
                res = Read(out type, out value);
                if (res)
                {
                    type = new CModReqdSig(tdr, type);
                }
                break;

            case ElementType.CModOpt:
                tdr = ReadTypeDefOrRef();
                res = Read(out type, out value);
                if (res)
                {
                    type = new CModOptSig(tdr, type);
                }
                break;

            case ElementType.Var:
            case ElementType.Array:
            case ElementType.GenericInst:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.FnPtr:
            case ElementType.SZArray:
            case ElementType.MVar:
            case ElementType.End:
            case ElementType.Void:
            case ElementType.ValueArray:
            case ElementType.R:
            case ElementType.Internal:
            case ElementType.Module:
            case ElementType.Sentinel:
            case ElementType.Pinned:
            default:
                Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString());
                res   = false;
                type  = null;
                value = null;
                break;
            }

            recursionCounter.Decrement();
            return(res);
        }
Beispiel #19
0
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="reader">PE file reader pointing to the start of this section</param>
		/// <param name="totalSize">Total size of this optional header (from the file header)</param>
		/// <param name="verify">Verify section</param>
		/// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
		public ImageOptionalHeader32(IImageStream reader, uint totalSize, bool verify) {
			if (totalSize < 0x60)
				throw new BadImageFormatException("Invalid optional header size");
			if (verify && reader.Position + totalSize > reader.Length)
				throw new BadImageFormatException("Invalid optional header size");
			SetStartOffset(reader);
			this.magic = reader.ReadUInt16();
			this.majorLinkerVersion = reader.ReadByte();
			this.minorLinkerVersion = reader.ReadByte();
			this.sizeOfCode = reader.ReadUInt32();
			this.sizeOfInitializedData = reader.ReadUInt32();
			this.sizeOfUninitializedData = reader.ReadUInt32();
			this.addressOfEntryPoint = (RVA)reader.ReadUInt32();
			this.baseOfCode = (RVA)reader.ReadUInt32();
			this.baseOfData = (RVA)reader.ReadUInt32();
			this.imageBase = reader.ReadUInt32();
			this.sectionAlignment = reader.ReadUInt32();
			this.fileAlignment = reader.ReadUInt32();
			this.majorOperatingSystemVersion = reader.ReadUInt16();
			this.minorOperatingSystemVersion = reader.ReadUInt16();
			this.majorImageVersion = reader.ReadUInt16();
			this.minorImageVersion = reader.ReadUInt16();
			this.majorSubsystemVersion = reader.ReadUInt16();
			this.minorSubsystemVersion = reader.ReadUInt16();
			this.win32VersionValue = reader.ReadUInt32();
			this.sizeOfImage = reader.ReadUInt32();
			this.sizeOfHeaders = reader.ReadUInt32();
			this.checkSum = reader.ReadUInt32();
			this.subsystem = (Subsystem)reader.ReadUInt16();
			this.dllCharacteristics = (DllCharacteristics)reader.ReadUInt16();
			this.sizeOfStackReserve = reader.ReadUInt32();
			this.sizeOfStackCommit = reader.ReadUInt32();
			this.sizeOfHeapReserve = reader.ReadUInt32();
			this.sizeOfHeapCommit = reader.ReadUInt32();
			this.loaderFlags = reader.ReadUInt32();
			this.numberOfRvaAndSizes = reader.ReadUInt32();
			for (int i = 0; i < dataDirectories.Length; i++) {
				uint len = (uint)(reader.Position - startOffset);
				if (len + 8 <= totalSize)
					dataDirectories[i] = new ImageDataDirectory(reader, verify);
				else
					dataDirectories[i] = new ImageDataDirectory();
			}
			reader.Position = (long)startOffset + totalSize;
			SetEndoffset(reader);
		}
Beispiel #20
0
 public int ReadByte()
 {
     return(stream.ReadByte());
 }
Beispiel #21
0
 public byte OffsetReadByte(uint offset)
 {
     peStream.Position = offset;
     return(peStream.ReadByte());
 }
Beispiel #22
0
        object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgType)
        {
            if (!recursionCounter.Increment())
            {
                throw new CABlobParserException("Too much recursion");
            }

            object result;

            switch (etype)
            {
            case SerializationType.Boolean:
                realArgType = module.CorLibTypes.Boolean;
                result      = reader.ReadByte() != 0;
                break;

            case SerializationType.Char:
                realArgType = module.CorLibTypes.Char;
                result      = (char)reader.ReadUInt16();
                break;

            case SerializationType.I1:
                realArgType = module.CorLibTypes.SByte;
                result      = reader.ReadSByte();
                break;

            case SerializationType.U1:
                realArgType = module.CorLibTypes.Byte;
                result      = reader.ReadByte();
                break;

            case SerializationType.I2:
                realArgType = module.CorLibTypes.Int16;
                result      = reader.ReadInt16();
                break;

            case SerializationType.U2:
                realArgType = module.CorLibTypes.UInt16;
                result      = reader.ReadUInt16();
                break;

            case SerializationType.I4:
                realArgType = module.CorLibTypes.Int32;
                result      = reader.ReadInt32();
                break;

            case SerializationType.U4:
                realArgType = module.CorLibTypes.UInt32;
                result      = reader.ReadUInt32();
                break;

            case SerializationType.I8:
                realArgType = module.CorLibTypes.Int64;
                result      = reader.ReadInt64();
                break;

            case SerializationType.U8:
                realArgType = module.CorLibTypes.UInt64;
                result      = reader.ReadUInt64();
                break;

            case SerializationType.R4:
                realArgType = module.CorLibTypes.Single;
                result      = reader.ReadSingle();
                break;

            case SerializationType.R8:
                realArgType = module.CorLibTypes.Double;
                result      = reader.ReadDouble();
                break;

            case SerializationType.String:
                realArgType = module.CorLibTypes.String;
                result      = ReadUTF8String();
                break;

            // It's ET.ValueType if it's eg. a ctor enum arg type
            case (SerializationType)ElementType.ValueType:
                if (argType == null)
                {
                    throw new CABlobParserException("Invalid element type");
                }
                realArgType = argType;
                result      = ReadEnumValue(GetEnumUnderlyingType(argType));
                break;

            // It's ET.Object if it's a ctor object arg type
            case (SerializationType)ElementType.Object:
            case SerializationType.TaggedObject:
                realArgType = ReadFieldOrPropType();
                var arraySig = realArgType as SZArraySig;
                if (arraySig != null)
                {
                    result = ReadArrayArgument(arraySig);
                }
                else
                {
                    TypeSig tmpType;
                    result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out tmpType);
                }
                break;

            // It's ET.Class if it's eg. a ctor System.Type arg type
            case (SerializationType)ElementType.Class:
                var tdr = argType as TypeDefOrRefSig;
                if (tdr != null && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System")
                {
                    if (tdr.TypeName == "Type")
                    {
                        result = ReadValue(SerializationType.Type, tdr, out realArgType);
                        break;
                    }
                    if (tdr.TypeName == "String")
                    {
                        result = ReadValue(SerializationType.String, tdr, out realArgType);
                        break;
                    }
                    if (tdr.TypeName == "Object")
                    {
                        result = ReadValue(SerializationType.TaggedObject, tdr, out realArgType);
                        break;
                    }
                }

                // Assume it's an enum that couldn't be resolved
                realArgType = argType;
                return(ReadEnumValue(null));

            case SerializationType.Type:
                realArgType = argType;
                result      = ReadType();
                break;

            case SerializationType.Enum:
                realArgType = ReadType();
                result      = ReadEnumValue(GetEnumUnderlyingType(realArgType));
                break;

            default:
                throw new CABlobParserException("Invalid element type");
            }

            recursionCounter.Decrement();
            return(result);
        }
Beispiel #23
0
        void ReadFiles(PdbReader reader, Dictionary<long, DbiDocument> documents, IImageStream stream, long end)
        {
            var begin = stream.Position;
            while (stream.Position < end) {
                var id = stream.Position - begin;

                var nameId = stream.ReadUInt32();
                var len = stream.ReadByte();
                /*var type = */stream.ReadByte();
                var doc = reader.GetDocument(nameId);
                documents.Add(id, doc);

                stream.Position += len;
                stream.Position = (stream.Position + 3) & (~3);
            }
        }
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="reader">PE file reader pointing to the start of this section</param>
		/// <param name="verify">Verify section</param>
		/// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
		public MetaDataHeader(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.signature = reader.ReadUInt32();
			if (verify && this.signature != 0x424A5342)
				throw new BadImageFormatException("Invalid MetaData header signature");
			this.majorVersion = reader.ReadUInt16();
			this.minorVersion = reader.ReadUInt16();
			if (verify && !((majorVersion == 1 && minorVersion == 1) || (majorVersion == 0 && minorVersion >= 19)))
				throw new BadImageFormatException(string.Format("Unknown MetaData header version: {0}.{1}", majorVersion, minorVersion));
			this.reserved1 = reader.ReadUInt32();
			this.stringLength = reader.ReadUInt32();
			this.versionString = ReadString(reader, stringLength);
			this.offset2ndPart = (uint)(reader.Position - startOffset);
			this.flags = (StorageFlags)reader.ReadByte();
			if (verify && this.flags != 0)
				throw new BadImageFormatException(string.Format("Storage flags != 0 ({0})", this.flags));
			this.reserved2 = reader.ReadByte();
			this.streams = reader.ReadUInt16();
			this.streamHeaders = new StreamHeader[streams];
			for (int i = 0; i < streamHeaders.Count; i++)
				streamHeaders[i] = new StreamHeader(reader, verify);
			SetEndoffset(reader);
		}
		static string ReadString(IImageStream reader, uint maxLength) {
			long endPos = reader.Position + maxLength;
			if (endPos < reader.Position || endPos > reader.Length)
				throw new BadImageFormatException("Invalid MD version string");
			byte[] utf8Bytes = new byte[maxLength];
			uint i;
			for (i = 0; i < maxLength; i++) {
				byte b = reader.ReadByte();
				if (b == 0)
					break;
				utf8Bytes[i] = b;
			}
			reader.Position = endPos;
			return Encoding.UTF8.GetString(utf8Bytes, 0, (int)i);
		}