/// <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"); }
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); }
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(); }
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); }
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); }
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; } } }
ulong ReadPtr(long pos) { reader.Position = pos; return(is32bit ? reader.ReadUInt32() : reader.ReadUInt64()); }
/// <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); }
/// <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); }
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); } }
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; } }
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); } } }
public void Read(IImageStream stream) { Addr1 = stream.ReadUInt32(); stream.Position += 10; Flags = stream.ReadUInt16(); Name = PdbReader.ReadCString(stream); }
/// <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(); }
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); } } }
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); }
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(); } }
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); } }
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; } }
public uint OffsetReadUInt32(uint offset) { peStream.Position = offset; return(peStream.ReadUInt32()); }
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); }
/// <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); }
/// <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); }
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); } }
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); }
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); }