/// <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); }
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; } } }
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; } }
/// <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); }
CustomAttribute Read() { var methodSig = ctor == null ? null : ((IMethodDefOrRef)ctor).MethodSig; if (methodSig == null) { throw new CABlobParserException("ctor is null or not a method"); } var mrCtor = ctor as MemberRef; if (mrCtor != null) { var owner = mrCtor.Class as TypeSpec; if (owner != null) { var gis = owner.TypeSig as GenericInstSig; if (gis != null) { genericArguments = new GenericArguments(); genericArguments.PushTypeArgs(gis.GenericArguments); } } } bool isEmpty = methodSig.Params.Count == 0 && reader.Position == reader.Length; if (!isEmpty && reader.ReadUInt16() != 1) { throw new CABlobParserException("Invalid CA blob prolog"); } var ctorArgs = new List <CAArgument>(methodSig.Params.Count); foreach (var arg in methodSig.Params.GetSafeEnumerable()) { ctorArgs.Add(ReadFixedArg(FixTypeSig(arg))); } // Some tools don't write the next ushort if there are no named arguments. int numNamedArgs = reader.Position == reader.Length ? 0 : reader.ReadUInt16(); var namedArgs = new List <CANamedArgument>(numNamedArgs); for (int i = 0; i < numNamedArgs; i++) { namedArgs.Add(ReadNamedArgument()); } // verifyReadAllBytes will be set when we guess the underlying type of an enum. // To make sure we guessed right, verify that we read all bytes. if (verifyReadAllBytes && reader.Position != reader.Length) { throw new CABlobParserException("Not all CA blob bytes were read"); } return(new CustomAttribute(ctor, ctorArgs, namedArgs)); }
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(); } }
/// <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"); }
/// <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 ImageDebugDirectory(IImageStream reader, bool verify) { SetStartOffset(reader); characteristics = reader.ReadUInt32(); timeDateStamp = reader.ReadUInt32(); majorVersion = reader.ReadUInt16(); minorVersion = reader.ReadUInt16(); type = (ImageDebugType)reader.ReadUInt32(); sizeOfData = reader.ReadUInt32(); addressOfRawData = reader.ReadUInt32(); pointerToRawData = reader.ReadUInt32(); 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 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); }
public void Read(IImageStream stream) { index = stream.ReadInt32(); stream.Position += 10; attributes = GetAttributes(stream.ReadUInt16()); name = PdbReader.ReadCString(stream); }
/// <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"); } }
static bool ParseIVTBlob(IImageStream stream, long end, out string publicKeyString) { publicKeyString = null; if (stream.Position + 2 > end) { return(false); } if (stream.ReadUInt16() != 1) { return(false); } if (!stream.ReadCompressedUInt32(out uint len) || stream.Position + len >= end) { return(false); } var bytes = stream.ReadBytes((int)len); var s = Encoding.UTF8.GetString(bytes); const string PublicKeyPattern = "PublicKey="; int index = s.IndexOf(PublicKeyPattern, StringComparison.OrdinalIgnoreCase); if (index >= 0) { publicKeyString = s.Substring(index + PublicKeyPattern.Length).Trim(); } return(true); }
public void Read(IImageStream stream) { Addr1 = stream.ReadUInt32(); stream.Position += 10; Flags = stream.ReadUInt16(); Name = PdbReader.ReadCString(stream); }
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); }
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; } }
/// <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); }
/// <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); }
/// <summary> /// Creates an IImageOptionalHeader /// </summary> /// <param name="reader">PE file reader pointing to the start of the optional header</param> /// <param name="verify">Verify section</param> /// <returns>The created IImageOptionalHeader</returns> /// <exception cref="BadImageFormatException">Thrown if verification fails</exception> IImageOptionalHeader CreateImageOptionalHeader(IImageStream reader, bool verify) { ushort magic = reader.ReadUInt16(); reader.Position -= 2; switch (magic) { case 0x010B: return new ImageOptionalHeader32(reader, imageFileHeader.SizeOfOptionalHeader, verify); case 0x020B: return new ImageOptionalHeader64(reader, imageFileHeader.SizeOfOptionalHeader, verify); default: throw new BadImageFormatException("Invalid optional header magic"); } }
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(); }
/// <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); CB = reader.ReadUInt32(); if (verify && CB < 0x48) { throw new BadImageFormatException("Invalid IMAGE_COR20_HEADER.cb value"); } MajorRuntimeVersion = reader.ReadUInt16(); MinorRuntimeVersion = reader.ReadUInt16(); MetaData = new ImageDataDirectory(reader, verify); Flags = (ComImageFlags)reader.ReadUInt32(); EntryPointToken_or_RVA = reader.ReadUInt32(); Resources = new ImageDataDirectory(reader, verify); StrongNameSignature = new ImageDataDirectory(reader, verify); CodeManagerTable = new ImageDataDirectory(reader, verify); VTableFixups = new ImageDataDirectory(reader, verify); ExportAddressTableJumps = new ImageDataDirectory(reader, verify); ManagedNativeHeader = new ImageDataDirectory(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); }
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; } } }
/// <summary> /// Creates an IImageOptionalHeader /// </summary> /// <param name="reader">PE file reader pointing to the start of the optional header</param> /// <param name="verify">Verify section</param> /// <returns>The created IImageOptionalHeader</returns> /// <exception cref="BadImageFormatException">Thrown if verification fails</exception> IImageOptionalHeader CreateImageOptionalHeader(IImageStream reader, bool verify) { ushort magic = reader.ReadUInt16(); reader.Position -= 2; switch (magic) { case 0x010B: return(new ImageOptionalHeader32(reader, imageFileHeader.SizeOfOptionalHeader, verify)); case 0x020B: return(new ImageOptionalHeader64(reader, imageFileHeader.SizeOfOptionalHeader, verify)); default: throw new BadImageFormatException("Invalid optional header magic"); } }
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; } } }
static string ReadUnicodeString(IImageStream stream, long end) { var sb = new StringBuilder(); for (;;) { if (stream.Position + 2 > end) { return(null); } var c = (char)stream.ReadUInt16(); if (c == 0) { break; } sb.Append(c); } return(sb.ToString()); }
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); }
static NameAndIndex[] ReadNames(IImageStream reader, IPEImage peImage, int numNames, long offsetOfNames, long offsetOfNameIndexes) { var names = new NameAndIndex[numNames]; reader.Position = offsetOfNameIndexes; for (int i = 0; i < names.Length; i++) { names[i].Index = reader.ReadUInt16(); } var currentOffset = offsetOfNames; for (int i = 0; i < names.Length; i++, currentOffset += 4) { reader.Position = currentOffset; long offsetOfName = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32()); names[i].Name = ReadMethodNameASCIIZ(reader, offsetOfName); } return(names); }
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); } }
/// <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); }
public ushort OffsetReadUInt16(uint offset) { peStream.Position = offset; return(peStream.ReadUInt16()); }
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); } } }
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(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; } 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: Debug.Write("Unknown symbol type: " + type); 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(); } }
/// <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 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; } }
/// <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); }
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 <SymbolSequencePoint>(); 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 SymbolSequencePoint { Document = document }; line.Offset = stream.ReadInt32(); var lineFlags = stream.ReadUInt32(); line.Line = (int)(lineFlags & 0x00ffffff); line.EndLine = line.Line + (int)((lineFlags >> 24) & 0x7F); if ((flags & 1) != 0) { stream.Position = colTablePos + i * COL_ENTRY_SIZE; line.Column = stream.ReadUInt16(); line.EndColumn = stream.ReadUInt16(); } func.Lines.Add(line); } } }