/// <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); }
bool StringsStreamNameEquals(IImageStream stringsStream, uint offset, byte[] nameData) { if (offset == 0) { return(nameData.Length == 0); } stringsStream.Position = offset; long pos = offset; var end = stringsStream.Length; for (int i = 0; i < nameData.Length; i++) { if (pos >= end) { return(false); } if (stringsStream.ReadByte() != nameData[i]) { return(false); } } if (pos >= end) { return(false); } return(stringsStream.ReadByte() == 0); }
/// <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); }
/// <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); }
char[] ReadSeparatorChar(IImageStream stream, out int charLength) { if (prevSepCharBytesCount != 0 && prevSepCharBytesCount <= stream.Length) { var pos = stream.Position; bool ok = true; for (int i = 0; i < prevSepCharBytesCount; i++) { if (i >= prevSepCharBytes.Length || stream.ReadByte() != prevSepCharBytes[i]) { ok = false; break; } } if (ok) { charLength = prevSepCharsLength; return(prevSepChars); } stream.Position = pos; } var decoder = Encoding.UTF8.GetDecoder(); var bytes = new byte[1]; prevSepCharBytesCount = 0; for (int i = 0; ; i++) { byte b = stream.ReadByte(); prevSepCharBytesCount++; if (i == 0 && b == 0) { break; } if (i < prevSepCharBytes.Length) { prevSepCharBytes[i] = b; } bytes[0] = b; bool isLastByte = stream.Position + 1 == stream.Length; int bytesUsed; bool completed; decoder.Convert(bytes, 0, 1, prevSepChars, 0, prevSepChars.Length, isLastByte, out bytesUsed, out prevSepCharsLength, out completed); if (prevSepCharsLength > 0) { break; } } charLength = prevSepCharsLength; return(prevSepChars); }
static string ReadString(IImageStream reader, int maxLen, bool verify) { var origPos = reader.Position; var sb = new StringBuilder(maxLen); int i; for (i = 0; i < maxLen; i++) { byte b = reader.ReadByte(); if (b == 0) { break; } sb.Append((char)b); } if (verify && i == maxLen) { throw new BadImageFormatException("Invalid stream name string"); } if (i != maxLen) { reader.Position = origPos + ((i + 1 + 3) & ~3); } return(sb.ToString()); }
void Populate(IImageStream reader) { var chars = new char[0x200]; reader.Position = 1; while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; uint len; if (!reader.ReadCompressedUInt32(out len)) { if (offset == reader.Position) reader.Position++; continue; } if (len == 0 || reader.Position + len > reader.Length) continue; int stringLen = (int)len / 2; if (stringLen > chars.Length) Array.Resize(ref chars, stringLen); for (int i = 0; i < stringLen; i++) chars[i] = (char)reader.ReadUInt16(); if ((len & 1) != 0) reader.ReadByte(); var s = new string(chars, 0, stringLen); if (!cachedDict.ContainsKey(s)) cachedDict[s] = offset; } }
void Populate(IImageStream reader) { reader.Position = 1; while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; var bytes = reader.ReadBytesUntilByte(0); if (bytes == null) { break; } reader.ReadByte(); // terminating zero if (bytes.Length == 0) { continue; } var s = new UTF8String(bytes); if (!cachedDict.ContainsKey(s)) { cachedDict[s] = offset; } } }
/// <summary> /// Reads the signature /// </summary> /// <returns>A new <see cref="CallingConventionSig"/> instance or <c>null</c> if invalid signature</returns> CallingConventionSig ReadSig() { if (!recursionCounter.Increment()) { return(null); } CallingConventionSig result; var callingConvention = (CallingConvention)reader.ReadByte(); switch (callingConvention & CallingConvention.Mask) { case CallingConvention.Default: case CallingConvention.C: case CallingConvention.StdCall: case CallingConvention.ThisCall: case CallingConvention.FastCall: case CallingConvention.VarArg: result = ReadMethod(callingConvention); break; case CallingConvention.Field: result = ReadField(callingConvention); break; case CallingConvention.LocalSig: result = ReadLocalSig(callingConvention); break; case CallingConvention.Property: result = ReadProperty(callingConvention); break; case CallingConvention.GenericInst: result = ReadGenericInstMethod(callingConvention); break; case CallingConvention.Unmanaged: case CallingConvention.NativeVarArg: default: result = null; break; } recursionCounter.Decrement(); return(result); }
public int ReadByte() { if (stream != null) { return(stream.ReadByte()); } return(-1); }
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); } }
static bool ReadAndCompareBytes(IImageStream stream, long end, byte[] bytes) { if (stream.Position + bytes.Length > end) { return(false); } for (int i = 0; i < bytes.Length; i++) { if (stream.ReadByte() != bytes[i]) { return(false); } } return(true); }
static string ReadString(IImageStream reader, int maxLen, bool verify) { var origPos = reader.Position; var sb = new StringBuilder(maxLen); int i; for (i = 0; i < maxLen; i++) { byte b = reader.ReadByte(); if (b == 0) break; sb.Append((char)b); } if (verify && i == maxLen) throw new BadImageFormatException("Invalid stream name string"); if (i != maxLen) reader.Position = origPos + ((i + 1 + 3) & ~3); return sb.ToString(); }
void Populate(IImageStream reader) { reader.Position = 1; while (reader.Position < reader.Length) { uint offset = (uint)reader.Position; var bytes = reader.ReadBytesUntilByte(0); if (bytes == null) break; reader.ReadByte(); // terminating zero if (bytes.Length == 0) continue; var s = new UTF8String(bytes); if (!cachedDict.ContainsKey(s)) cachedDict[s] = offset; } }
public string ReadInstrution(Instruction instr) { if (stream == null) { return(string.Empty); } int instructionSize = instr.GetSize(); stream.Position = instr.Offset; var sb = new StringBuilder(); for (int i = 0; i < instructionSize; i++) { sb.AppendFormat("{0:X2}", stream.ReadByte()); } return(sb.ToString()); }
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 ReadString(IImageStream reader, uint maxLength) { long endPos = reader.Position + maxLength; if (endPos < reader.Position || endPos > reader.Length) { throw new BadImageFormatException("Invalid MD version string"); } byte[] utf8Bytes = new byte[maxLength]; uint i; for (i = 0; i < maxLength; i++) { byte b = reader.ReadByte(); if (b == 0) { break; } utf8Bytes[i] = b; } reader.Position = endPos; return(Encoding.UTF8.GetString(utf8Bytes, 0, (int)i)); }
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); }
/// <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 int ReadByte() { return(stream.ReadByte()); }
public byte OffsetReadByte(uint offset) { peStream.Position = offset; return(peStream.ReadByte()); }
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); }
void ReadFiles(PdbReader reader, Dictionary<long, DbiDocument> documents, IImageStream stream, long end) { var begin = stream.Position; while (stream.Position < end) { var id = stream.Position - begin; var nameId = stream.ReadUInt32(); var len = stream.ReadByte(); /*var type = */stream.ReadByte(); var doc = reader.GetDocument(nameId); documents.Add(id, doc); stream.Position += len; stream.Position = (stream.Position + 3) & (~3); } }
/// <summary> /// Constructor /// </summary> /// <param name="reader">PE file reader pointing to the start of this section</param> /// <param name="verify">Verify section</param> /// <exception cref="BadImageFormatException">Thrown if verification fails</exception> public MetaDataHeader(IImageStream reader, bool verify) { SetStartOffset(reader); this.signature = reader.ReadUInt32(); if (verify && this.signature != 0x424A5342) throw new BadImageFormatException("Invalid MetaData header signature"); this.majorVersion = reader.ReadUInt16(); this.minorVersion = reader.ReadUInt16(); if (verify && !((majorVersion == 1 && minorVersion == 1) || (majorVersion == 0 && minorVersion >= 19))) throw new BadImageFormatException(string.Format("Unknown MetaData header version: {0}.{1}", majorVersion, minorVersion)); this.reserved1 = reader.ReadUInt32(); this.stringLength = reader.ReadUInt32(); this.versionString = ReadString(reader, stringLength); this.offset2ndPart = (uint)(reader.Position - startOffset); this.flags = (StorageFlags)reader.ReadByte(); if (verify && this.flags != 0) throw new BadImageFormatException(string.Format("Storage flags != 0 ({0})", this.flags)); this.reserved2 = reader.ReadByte(); this.streams = reader.ReadUInt16(); this.streamHeaders = new StreamHeader[streams]; for (int i = 0; i < streamHeaders.Count; i++) streamHeaders[i] = new StreamHeader(reader, verify); SetEndoffset(reader); }
static string ReadString(IImageStream reader, uint maxLength) { long endPos = reader.Position + maxLength; if (endPos < reader.Position || endPos > reader.Length) throw new BadImageFormatException("Invalid MD version string"); byte[] utf8Bytes = new byte[maxLength]; uint i; for (i = 0; i < maxLength; i++) { byte b = reader.ReadByte(); if (b == 0) break; utf8Bytes[i] = b; } reader.Position = endPos; return Encoding.UTF8.GetString(utf8Bytes, 0, (int)i); }