/// <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 StreamHeader(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.offset = reader.ReadUInt32();
			this.streamSize = reader.ReadUInt32();
			this.name = ReadString(reader, 32, verify);
			SetEndoffset(reader);
			if (verify && offset + size < offset)
				throw new BadImageFormatException("Invalid stream header");
		}
		/// <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 ImageFileHeader(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.machine = (Machine)reader.ReadUInt16();
			this.numberOfSections = reader.ReadUInt16();
			this.timeDateStamp = reader.ReadUInt32();
			this.pointerToSymbolTable = reader.ReadUInt32();
			this.numberOfSymbols = reader.ReadUInt32();
			this.sizeOfOptionalHeader = reader.ReadUInt16();
			this.characteristics = (Characteristics)reader.ReadUInt16();
			SetEndoffset(reader);
			if (verify && this.sizeOfOptionalHeader == 0)
				throw new BadImageFormatException("Invalid SizeOfOptionalHeader");
		}
Beispiel #3
0
		public void Read(IImageStream stream, long recEnd) {
			stream.Position += 4;
			var end = stream.ReadUInt32();
			stream.Position += 4;
			var len = stream.ReadUInt32();
			stream.Position += 8;
			Token = stream.ReadUInt32();
			Address = PdbAddress.ReadAddress(stream);
			stream.Position += 1 + 2;
			Name = PdbReader.ReadCString(stream);

			stream.Position = recEnd;
			Root = new DbiScope("", Address.Offset, len);
			Root.Read(new RecursionCounter(), stream, end);
			FixOffsets(new RecursionCounter(), Root);
		}
		/// <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 ImageNTHeaders(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.signature = reader.ReadUInt32();
			if (verify && this.signature != 0x4550)
				throw new BadImageFormatException("Invalid NT headers signature");
			this.imageFileHeader = new ImageFileHeader(reader, verify);
			this.imageOptionalHeader = CreateImageOptionalHeader(reader, verify);
			SetEndoffset(reader);
		}
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="reader">PE file reader</param>
		/// <param name="verify">Verify section</param>
		/// <exception cref="BadImageFormatException">Thrown if verification fails</exception>
		public ImageDosHeader(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			ushort sig = reader.ReadUInt16();
			if (verify && sig != 0x5A4D)
				throw new BadImageFormatException("Invalid DOS signature");
			reader.Position = (long)startOffset + 0x3C;
			this.ntHeadersOffset = reader.ReadUInt32();
			SetEndoffset(reader);
		}
Beispiel #6
0
		public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd) {
			if (!counter.Increment())
				throw new PdbException("Scopes too deep");

			while (stream.Position < scopeEnd) {
				var size = stream.ReadUInt16();
				var begin = stream.Position;
				var end = begin + size;

				var type = (SymbolType)stream.ReadUInt16();
				DbiScope child = null;
				uint? childEnd = null;
				switch (type) {
					case SymbolType.S_BLOCK32: {
						stream.Position += 4;
						childEnd = stream.ReadUInt32();
						var len = stream.ReadUInt32();
						var addr = PdbAddress.ReadAddress(stream);
						var name = PdbReader.ReadCString(stream);
						child = new DbiScope(name, addr.Offset, len);
						break;
					}
					case SymbolType.S_UNAMESPACE:
						Namespaces.Add(new DbiNamespace(PdbReader.ReadCString(stream)));
						break;
					case SymbolType.S_MANSLOT: {
						var variable = new DbiVariable();
						variable.Read(stream);
						Variables.Add(variable);
						break;
					}
				}

				stream.Position = end;
				if (child != null) {
					child.Read(counter, stream, childEnd.Value);
					Children.Add(child);
					child = null;
				}
			}
			counter.Decrement();
			if (stream.Position != scopeEnd)
				Debugger.Break();
		}
Beispiel #7
0
		public void Read(IImageStream stream) {
			stream.Position += 34;
			StreamId = stream.ReadUInt16();
			cbSyms = stream.ReadUInt32();
			cbOldLines = stream.ReadUInt32();
			cbLines = stream.ReadUInt32();
			stream.Position += 16;

			if ((int)cbSyms < 0)
				cbSyms = 0;
			if ((int)cbOldLines < 0)
				cbOldLines = 0;
			if ((int)cbLines < 0)
				cbLines = 0;

			ModuleName = PdbReader.ReadCString(stream);
			ObjectName = PdbReader.ReadCString(stream);

			stream.Position = (stream.Position + 3) & (~3);
		}
Beispiel #8
0
		public void Read(IImageStream stream) {
			stream.Position = 0;
			Language = new Guid(stream.ReadBytes(0x10));
			LanguageVendor = new Guid(stream.ReadBytes(0x10));
			DocumentType = new Guid(stream.ReadBytes(0x10));
			CheckSumAlgorithmId = new Guid(stream.ReadBytes(0x10));

			var len = stream.ReadInt32();
			if (stream.ReadUInt32() != 0)
				throw new PdbException("Unexpected value");

			CheckSum = stream.ReadBytes(len);
		}
Beispiel #9
0
		void ReadFunctions(IImageStream stream) {
			if (stream.ReadUInt32() != 4)
				throw new PdbException("Invalid signature");

			while (stream.Position < stream.Length) {
				var size = stream.ReadUInt16();
				var begin = stream.Position;
				var end = begin + size;

				var type = (SymbolType)stream.ReadUInt16();
				switch (type) {
					case SymbolType.S_GMANPROC:
					case SymbolType.S_LMANPROC:
						var func = new DbiFunction();
						func.Read(stream, end);
						Functions.Add(func);
						break;
					default:
						stream.Position = end;
						break;
				}
			}
		}
Beispiel #10
0
 ulong ReadPtr(long pos)
 {
     reader.Position = pos;
     return(is32bit ? reader.ReadUInt32() : reader.ReadUInt64());
 }
Beispiel #11
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 #12
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 ImageOptionalHeader64(IImageStream reader, uint totalSize, bool verify)
 {
     if (totalSize < 0x70)
     {
         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.imageBase                   = reader.ReadUInt64();
     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.ReadUInt64();
     this.sizeOfStackCommit   = reader.ReadUInt64();
     this.sizeOfHeapReserve   = reader.ReadUInt64();
     this.sizeOfHeapCommit    = reader.ReadUInt64();
     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 #13
0
        public static bool TryReadNumeric(IImageStream stream, long end, out object value)
        {
            value = null;
            if (stream.Position + 2 > end)
            {
                return(false);
            }
            var numLeaf = (NumericLeaf)stream.ReadUInt16();

            if (numLeaf < NumericLeaf.LF_NUMERIC)
            {
                value = (short)numLeaf;
                return(true);
            }

            switch (numLeaf)
            {
            case NumericLeaf.LF_CHAR:
                if (stream.Position > end)
                {
                    return(false);
                }
                value = stream.ReadSByte();
                return(true);

            case NumericLeaf.LF_SHORT:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                value = stream.ReadInt16();
                return(true);

            case NumericLeaf.LF_USHORT:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt16();
                return(true);

            case NumericLeaf.LF_LONG:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadInt32();
                return(true);

            case NumericLeaf.LF_ULONG:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt32();
                return(true);

            case NumericLeaf.LF_REAL32:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadSingle();
                return(true);

            case NumericLeaf.LF_REAL64:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadDouble();
                return(true);

            case NumericLeaf.LF_QUADWORD:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadInt64();
                return(true);

            case NumericLeaf.LF_UQUADWORD:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt64();
                return(true);

            case NumericLeaf.LF_VARSTRING:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                int varStrLen = stream.ReadUInt16();
                if (stream.Position + varStrLen > end)
                {
                    return(false);
                }
                value = Encoding.UTF8.GetString(stream.ReadBytes(varStrLen));
                return(true);

            case NumericLeaf.LF_VARIANT:
                if (stream.Position + 0x10 > end)
                {
                    return(false);
                }
                int  v0    = stream.ReadInt32();
                int  v1    = stream.ReadInt32();
                int  v2    = stream.ReadInt32();
                int  v3    = stream.ReadInt32();
                byte scale = (byte)(v0 >> 16);
                if (scale <= 28)
                {
                    value = new decimal(v2, v3, v1, v0 < 0, scale);
                }
                else
                {
                    value = null;
                }
                return(true);

            default:
                return(false);
            }
        }
Beispiel #14
0
		void ReadGlobalSymbols(IImageStream stream) {
			stream.Position = 0;
			while (stream.Position < stream.Length) {
				var size = stream.ReadUInt16();
				var begin = stream.Position;
				var end = begin + size;

				if ((SymbolType)stream.ReadUInt16() == SymbolType.S_PUB32) {
					stream.Position += 4;
					var offset = stream.ReadUInt32();
					stream.Position += 2;
					var name = ReadCString(stream);

					if (name == "COM+_Entry_Point")
						entryPt = offset;
				}

				stream.Position = end;
			}
		}
Beispiel #15
0
        void ReadLines(DbiFunction[] funcs, Dictionary<long, DbiDocument> documents, IImageStream stream, long end)
        {
            var address = PdbAddress.ReadAddress(stream);

            int first = 0;
            int last = funcs.Length - 1;
            int found = -1;
            while (first <= last) {
                var index = first + ((last - first) >> 1);
                var addr = funcs[index].Address;
                if (addr < address) {
                    first = index + 1;
                }
                else if (addr > address) {
                    last = index - 1;
                }
                else {
                    found = index;
                    break;
                }
            }
            if (found == -1)
                return;

            var flags = stream.ReadUInt16();
            stream.Position += 4;

            if (funcs[found].Lines == null) {
                while (found > 0) {
                    var prevFunc = funcs[found - 1];
                    if (prevFunc != null || prevFunc.Address != address)
                        break;
                    found--;
                }
            }
            else {
                while (found < funcs.Length - 1 && funcs[found] != null) {
                    var nextFunc = funcs[found + 1];
                    if (nextFunc.Address != address)
                        break;
                    found++;
                }
            }
            var func = funcs[found];
            if (func.Lines != null)
                return;
            func.Lines = new List<DbiSourceLine>();

            while (stream.Position < end) {
                var document = documents[stream.ReadUInt32()];
                var count = stream.ReadUInt32();
                stream.Position += 4;

                const int LINE_ENTRY_SIZE = 8;
                const int COL_ENTRY_SIZE = 4;
                var lineTablePos = stream.Position;
                var colTablePos = stream.Position + count * LINE_ENTRY_SIZE;

                for (uint i = 0; i < count; i++) {
                    stream.Position = lineTablePos + i * LINE_ENTRY_SIZE;

                    var line = new DbiSourceLine {
                        Document = document
                    };
                    line.Offset = stream.ReadUInt32();
                    var lineFlags = stream.ReadUInt32();

                    line.LineBegin = lineFlags & 0x00ffffff;
                    line.LineEnd = line.LineBegin + ((lineFlags >> 24) & 0x7F);
                    if ((flags & 1) != 0) {
                        stream.Position = colTablePos + i * COL_ENTRY_SIZE;
                        line.ColumnBegin = stream.ReadUInt16();
                        line.ColumnEnd = stream.ReadUInt16();
                    }

                    func.Lines.Add(line);
                }
            }
        }
Beispiel #16
0
		public void Read(IImageStream stream) {
			Addr1 = stream.ReadUInt32();
			stream.Position += 10;
			Flags = stream.ReadUInt16();
			Name = PdbReader.ReadCString(stream);
		}
Beispiel #17
0
 /// <inheritdoc/>
 protected override void ReadHotHeapDirectory(IImageStream reader, long dirBaseOffs, out HeapType heapType, out long hotHeapOffs)
 {
     heapType = (HeapType)reader.ReadUInt32();
     // All bits are used
     hotHeapOffs = dirBaseOffs - reader.ReadUInt32();
 }
Beispiel #18
0
        void ReadInternal(IImageStream stream)
        {
            stream.Position = 0;
            string sig = Encoding.ASCII.GetString(stream.ReadBytes(30));

            if (sig != "Microsoft C/C++ MSF 7.00\r\n\u001ADS\0")
            {
                throw new PdbException("Invalid signature");
            }
            stream.Position += 2;

            uint pageSize = stream.ReadUInt32();

            /*uint fpm = */ stream.ReadUInt32();
            uint pageCount = stream.ReadUInt32();
            uint rootSize  = stream.ReadUInt32();

            stream.ReadUInt32();
            var numOfRootPages = RoundUpDiv(rootSize, pageSize);
            var numOfPtrPages  = RoundUpDiv(numOfRootPages * 4, pageSize);

            if (pageCount * pageSize != stream.Length)
            {
                throw new PdbException("File size mismatch");
            }

            var pages = new IImageStream[pageCount];

            try {
                FileOffset offset = 0;
                for (uint i = 0; i < pageCount; i++)
                {
                    pages[i] = stream.Create(offset, pageSize);
                    offset  += pageSize;
                }

                var rootPages = new IImageStream[numOfRootPages];
                int pageIndex = 0;
                for (int i = 0; i < numOfPtrPages && pageIndex < numOfRootPages; i++)
                {
                    var ptrPage = pages[stream.ReadUInt32()];
                    ptrPage.Position = 0;
                    for (; ptrPage.Position < ptrPage.Length && pageIndex < numOfRootPages; pageIndex++)
                    {
                        rootPages[pageIndex] = pages[ptrPage.ReadUInt32()];
                    }
                }

                ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize);
            }
            finally {
                foreach (var page in pages)
                {
                    if (page != null)
                    {
                        page.Dispose();
                    }
                }
            }

            ReadNames();
            ReadStringTable();
            var tokenMapStream = ReadModules();

            documents = new Dictionary <string, DbiDocument>(StringComparer.OrdinalIgnoreCase);
            foreach (var module in modules)
            {
                if (IsValidStreamIndex(module.StreamId))
                {
                    module.LoadFunctions(this, streams[module.StreamId].Content);
                }
            }

            if (IsValidStreamIndex(tokenMapStream ?? STREAM_INVALID_INDEX))
            {
                ApplyRidMap(streams[tokenMapStream.Value].Content);
            }

            functions = new Dictionary <uint, DbiFunction>();
            foreach (var module in modules)
            {
                foreach (var func in module.Functions)
                {
                    functions.Add(func.Token, func);
                }
            }
        }
Beispiel #19
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 #20
0
        public void Read(RecursionCounter counter, IImageStream stream, uint scopeEnd)
        {
            if (!counter.Increment())
            {
                throw new PdbException("Scopes too deep");
            }

            while (stream.Position < scopeEnd)
            {
                var size  = stream.ReadUInt16();
                var begin = stream.Position;
                var end   = begin + size;

                var      type     = (SymbolType)stream.ReadUInt16();
                DbiScope child    = null;
                uint?    childEnd = null;
                string   name;
                switch (type)
                {
                case SymbolType.S_BLOCK32: {
                    stream.Position += 4;
                    childEnd         = stream.ReadUInt32();
                    var len  = stream.ReadUInt32();
                    var addr = PdbAddress.ReadAddress(stream);
                    name  = PdbReader.ReadCString(stream);
                    child = new DbiScope(method, this, name, addr.Offset, len);
                    break;
                }

                case SymbolType.S_UNAMESPACE:
                    namespacesList.Add(new DbiNamespace(PdbReader.ReadCString(stream)));
                    break;

                case SymbolType.S_MANSLOT: {
                    var variable = new DbiVariable();
                    variable.Read(stream);
                    localsList.Add(variable);
                    break;
                }

                case SymbolType.S_OEM:
                    if (stream.Position + 20 > end)
                    {
                        break;
                    }
                    if (!ReadAndCompareBytes(stream, end, dotNetOemGuid))
                    {
                        Debug.Fail("Unknown OEM record GUID, not .NET GUID");
                        break;
                    }
                    stream.Position += 4;                            // typeIndex or 0
                    name             = ReadUnicodeString(stream, end);
                    Debug.Assert(name != null);
                    if (name == null)
                    {
                        break;
                    }
                    var data = stream.ReadBytes((int)(end - stream.Position));
                    if (oemInfos == null)
                    {
                        oemInfos = new List <OemInfo>(1);
                    }
                    oemInfos.Add(new OemInfo(name, data));
                    break;

                case SymbolType.S_MANCONSTANT:
                    uint   signatureToken = stream.ReadUInt32();
                    object value;
                    if (!NumericReader.TryReadNumeric(stream, end, out value))
                    {
                        break;
                    }
                    name = PdbReader.ReadCString(stream);
                    if (constants == null)
                    {
                        constants = new List <ConstantInfo>();
                    }
                    constants.Add(new ConstantInfo(name, signatureToken, value));
                    break;

                case SymbolType.S_END:
                    break;

                default:
                    break;
                }

                stream.Position = end;
                if (child != null)
                {
                    child.Read(counter, stream, childEnd.Value);
                    childrenList.Add(child);
                    child = null;
                }
            }
            counter.Decrement();
            if (stream.Position != scopeEnd)
            {
                Debugger.Break();
            }
        }
Beispiel #21
0
		void ReadInternal(IImageStream stream) {
			stream.Position = 0;
			string sig = Encoding.ASCII.GetString(stream.ReadBytes(30));
			if (sig != "Microsoft C/C++ MSF 7.00\r\n\u001ADS\0")
				throw new PdbException("Invalid signature");
			stream.Position += 2;

			uint pageSize = stream.ReadUInt32();
			uint fpm = stream.ReadUInt32();
			uint pageCount = stream.ReadUInt32();
			uint rootSize = stream.ReadUInt32();
			stream.ReadUInt32();
			var numOfRootPages = RoundUpDiv(rootSize, pageSize);
			var numOfPtrPages = RoundUpDiv(numOfRootPages * 4, pageSize);
			if (pageCount * pageSize != stream.Length)
				throw new PdbException("File size mismatch");

			var pages = new IImageStream[pageCount];
			try {
				FileOffset offset = 0;
				for (uint i = 0; i < pageCount; i++) {
					pages[i] = stream.Create(offset, pageSize);
					offset += pageSize;
				}

				var rootPages = new IImageStream[numOfRootPages];
				int pageIndex = 0;
				for (int i = 0; i < numOfPtrPages && pageIndex < numOfRootPages; i++) {
					var ptrPage = pages[stream.ReadUInt32()];
					ptrPage.Position = 0;
					for (; ptrPage.Position < ptrPage.Length && pageIndex < numOfRootPages; pageIndex++)
						rootPages[pageIndex] = pages[ptrPage.ReadUInt32()];
				}

				ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize);
			}
			finally {
				foreach (var page in pages) {
					if (page != null)
						page.Dispose();
				}
			}

			ReadNames();
			ReadStringTable();
			var tokenMapStream = ReadModules();

			documents = new Dictionary<string, DbiDocument>(StringComparer.OrdinalIgnoreCase);
			foreach (var module in modules)
				if (IsValidStreamIndex(module.StreamId))
					module.LoadFunctions(this, streams[module.StreamId].Content);

			if (IsValidStreamIndex(tokenMapStream ?? STREAM_INVALID_INDEX))
				ApplyRidMap(streams[tokenMapStream.Value].Content);

			functions = new Dictionary<uint, DbiFunction>();
			foreach (var module in modules)
				foreach (var func in module.Functions) {
					functions.Add(func.Token, func);
				}
		}
Beispiel #22
0
		void ApplyRidMap(IImageStream stream) {
			stream.Position = 0;
			var map = new uint[stream.Length / 4];
			for (int i = 0; i < map.Length; i++)
				map[i] = stream.ReadUInt32();

			foreach (var module in modules)
				foreach (var func in module.Functions) {
					var rid = func.Token & 0x00ffffff;
					rid = map[rid];
					func.Token = (func.Token & 0xff000000) | rid;
				}

			if (entryPt != 0) {
				var rid = entryPt & 0x00ffffff;
				rid = map[rid];
				entryPt = (entryPt & 0xff000000) | rid;
			}
		}
Beispiel #23
0
 public uint OffsetReadUInt32(uint offset)
 {
     peStream.Position = offset;
     return(peStream.ReadUInt32());
 }
Beispiel #24
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 #25
0
 /// <inheritdoc/>
 protected override void ReadHotHeapDirectory(IImageStream reader, long dirBaseOffs, out HeapType heapType, out long hotHeapOffs)
 {
     heapType = (HeapType)reader.ReadUInt32();
     // Lower 2 bits are ignored
     hotHeapOffs = dirBaseOffs - (reader.ReadUInt32() & ~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);
		}
Beispiel #27
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 ImageDataDirectory(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.virtualAddress = (RVA)reader.ReadUInt32();
			this.dataSize = reader.ReadUInt32();
			SetEndoffset(reader);
		}
Beispiel #28
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);
            }
        }
		/// <inheritdoc/>
		protected override void ReadHotHeapDirectory(IImageStream reader, long dirBaseOffs, out HeapType heapType, out long hotHeapOffs) {
			heapType = (HeapType)reader.ReadUInt32();
			// All bits are used
			hotHeapOffs = dirBaseOffs - reader.ReadUInt32();
		}
Beispiel #30
0
        void ReadLines(DbiFunction[] funcs, Dictionary <long, DbiDocument> documents, IImageStream stream, long end)
        {
            var address = PdbAddress.ReadAddress(stream);

            int first = 0;
            int last  = funcs.Length - 1;
            int found = -1;

            while (first <= last)
            {
                var index = first + ((last - first) >> 1);
                var addr  = funcs[index].Address;
                if (addr < address)
                {
                    first = index + 1;
                }
                else if (addr > address)
                {
                    last = index - 1;
                }
                else
                {
                    found = index;
                    break;
                }
            }
            if (found == -1)
            {
                return;
            }

            var flags = stream.ReadUInt16();

            stream.Position += 4;

            if (funcs[found].Lines == null)
            {
                while (found > 0)
                {
                    var prevFunc = funcs[found - 1];
                    if (prevFunc != null || prevFunc.Address != address)
                    {
                        break;
                    }
                    found--;
                }
            }
            else
            {
                while (found < funcs.Length - 1 && funcs[found] != null)
                {
                    var nextFunc = funcs[found + 1];
                    if (nextFunc.Address != address)
                    {
                        break;
                    }
                    found++;
                }
            }
            var func = funcs[found];

            if (func.Lines != null)
            {
                return;
            }
            func.Lines = new List <DbiSourceLine>();

            while (stream.Position < end)
            {
                var document = documents[stream.ReadUInt32()];
                var count    = stream.ReadUInt32();
                stream.Position += 4;

                const int LINE_ENTRY_SIZE = 8;
                const int COL_ENTRY_SIZE  = 4;
                var       lineTablePos    = stream.Position;
                var       colTablePos     = stream.Position + count * LINE_ENTRY_SIZE;

                for (uint i = 0; i < count; i++)
                {
                    stream.Position = lineTablePos + i * LINE_ENTRY_SIZE;

                    var line = new DbiSourceLine {
                        Document = document
                    };
                    line.Offset = stream.ReadUInt32();
                    var lineFlags = stream.ReadUInt32();

                    line.LineBegin = lineFlags & 0x00ffffff;
                    line.LineEnd   = line.LineBegin + ((lineFlags >> 24) & 0x7F);
                    if ((flags & 1) != 0)
                    {
                        stream.Position  = colTablePos + i * COL_ENTRY_SIZE;
                        line.ColumnBegin = stream.ReadUInt16();
                        line.ColumnEnd   = stream.ReadUInt16();
                    }

                    func.Lines.Add(line);
                }
            }
        }
		/// <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 ImageCor20Header(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.cb = reader.ReadUInt32();
			if (verify && this.cb < 0x48)
				throw new BadImageFormatException("Invalid IMAGE_COR20_HEADER.cb value");
			this.majorRuntimeVersion = reader.ReadUInt16();
			this.minorRuntimeVersion = reader.ReadUInt16();
			this.metaData = new ImageDataDirectory(reader, verify);
			this.flags = (ComImageFlags)reader.ReadUInt32();
			this.entryPointToken_or_RVA = reader.ReadUInt32();
			this.resources = new ImageDataDirectory(reader, verify);
			this.strongNameSignature = new ImageDataDirectory(reader, verify);
			this.codeManagerTable = new ImageDataDirectory(reader, verify);
			this.vtableFixups = new ImageDataDirectory(reader, verify);
			this.exportAddressTableJumps = new ImageDataDirectory(reader, verify);
			this.managedNativeHeader = new ImageDataDirectory(reader, verify);
			SetEndoffset(reader);
		}
Beispiel #32
0
        void ReadLines(PdbReader reader, IImageStream stream)
        {
            var docs = new Dictionary<long, DbiDocument>();

            stream.Position = 0;
            while (stream.Position < stream.Length) {
                var sig = (ModuleStreamType)stream.ReadUInt32();
                var size = stream.ReadUInt32();
                var begin = stream.Position;
                var end = (begin + size + 3) & ~3;

                if (sig == ModuleStreamType.FileInfo)
                    ReadFiles(reader, docs, stream, end);

                stream.Position = end;
            }

            var sortedFuncs = new DbiFunction[Functions.Count];
            Functions.CopyTo(sortedFuncs, 0);
            Array.Sort(sortedFuncs, (a, b) => a.Address.CompareTo(b.Address));

            stream.Position = 0;
            while (stream.Position < stream.Length) {
                var sig = (ModuleStreamType)stream.ReadUInt32();
                var size = stream.ReadUInt32();
                var begin = stream.Position;
                var end = begin + size;

                if (sig == ModuleStreamType.Lines)
                    ReadLines(sortedFuncs, docs, stream, end);

                stream.Position = end;
            }
        }
		/// <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 ImageSectionHeader(IImageStream reader, bool verify) {
			SetStartOffset(reader);
			this.name = reader.ReadBytes(8);
			this.virtualSize = reader.ReadUInt32();
			this.virtualAddress = (RVA)reader.ReadUInt32();
			this.sizeOfRawData = reader.ReadUInt32();
			this.pointerToRawData = reader.ReadUInt32();
			this.pointerToRelocations = reader.ReadUInt32();
			this.pointerToLinenumbers = reader.ReadUInt32();
			this.numberOfRelocations = reader.ReadUInt16();
			this.numberOfLinenumbers = reader.ReadUInt16();
			this.characteristics = reader.ReadUInt32();
			SetEndoffset(reader);
			displayName = ToString(name);
		}
		/// <inheritdoc/>
		protected override void ReadHotHeapDirectory(IImageStream reader, long dirBaseOffs, out HeapType heapType, out long hotHeapOffs) {
			heapType = (HeapType)reader.ReadUInt32();
			// Lower 2 bits are ignored
			hotHeapOffs = dirBaseOffs - (reader.ReadUInt32() & ~3);
		}