public byte[] GetStreamBytes(BinaryReader reader, StreamHeader streamHeader, uint metadataDirectoryAddress, IEnumerable <Section> sections) { var rva = metadataDirectoryAddress + streamHeader.Offset; var fileOffset = BinUtil.RVAToOffset(rva, sections); reader.BaseStream.Seek((long)fileOffset, SeekOrigin.Begin); return(reader.ReadBytes((int)streamHeader.Size)); }
private static byte[] ReadStrongNameHash(BinaryReader reader, uint rva, uint size, IEnumerable <Section> sections) { if (rva == 0) { return(new byte[0]); } var fileOffset = BinUtil.RVAToOffset(rva, sections); reader.BaseStream.Seek((long)fileOffset, SeekOrigin.Begin); return(reader.ReadBytes((int)size)); }
private void Init(byte[] data) { #region Parse PE Header RawFile = new BinaryReader(new MemoryStream(data)); BinaryReader r = new BinaryReader(new MemoryStream(data)); DosHeader = ReadDOSHeader(r); PeHeader = ReadPEHeader(DosHeader.COFFHeaderAddress, r); //Read all of the data PeHeader.Directories = ReadDirectoriesList(PeHeader.DirectoryLength, r); PeHeader.Sections = ReadSectionsList(PeHeader.NumberOfSections, r); #endregion #region Parse Clr header & Strong name hash try { ClrHeader = ReadCLRHeader(r, PeHeader); } catch { Console.WriteLine("No clr header!"); ContainsMetadata = false; return; } //Read the strong name hash ClrStrongNameHash = ReadStrongNameHash(r, ClrHeader.StrongNameSignatureAddress, ClrHeader.StrongNameSignatureSize, PeHeader.Sections); #endregion #region Parse Metadata header //Skip past all of the IL Code, and get tto the metadata header long pos = (long)BinUtil.RVAToOffset(ClrHeader.MetaDataDirectoryAddress, PeHeader.Sections); r.BaseStream.Position = pos; ClrMetaDataHeader = new MetadataHeader(); ClrMetaDataHeader.Signature = r.ReadUInt32(); ClrMetaDataHeader.MajorVersion = r.ReadUInt16(); ClrMetaDataHeader.MinorVersion = r.ReadUInt16(); ClrMetaDataHeader.Reserved1 = r.ReadUInt32(); ClrMetaDataHeader.VersionStringLength = r.ReadUInt32(); ClrMetaDataHeader.VersionString = r.ReadNullTermString((int)ClrMetaDataHeader.VersionStringLength); ClrMetaDataHeader.Flags = r.ReadUInt16(); //reserved ClrMetaDataHeader.NumberOfStreams = r.ReadUInt16(); //Simple checks //Debug.Assert(ClrMetaDataHeader.Signature == 0x424A5342); //Debug.Assert(ClrMetaDataHeader.Reserved1 == 0); //Debug.Assert(ClrMetaDataHeader.Flags == 0); #endregion #region Parse Streams //Parse the StreamHeader(s) for (int i = 0; i < ClrMetaDataHeader.NumberOfStreams; i++) { var hdr = new StreamHeader(); hdr.Offset = r.ReadUInt32(); hdr.Size = r.ReadUInt32(); hdr.Name = r.ReadNullTermFourByteAlignedString(); Streams.Add(hdr); } //Parse the #String stream var bytes = GetStreamBytes("#Strings", r); ClrStringsStream = new StringsStream(bytes); //Parse the #US Stream var bytes2 = GetStreamBytes("#US", r); //File.WriteAllBytes("strings", bytes2); ClrUsStream = new USStreamReader(bytes2).Read(); #endregion #region Parse #~ Stream aka Tabels stream //Parse the #~ stream BinaryReader TableStreamR = new BinaryReader(new MemoryStream(GetStreamBytes("#~", r))); ClrMetaDataStreamHeader = ReadHeader(TableStreamR); //Parse the tabels data var numberOfTables = GetTableCount(ClrMetaDataStreamHeader.TablesFlags); ClrMetaDataStreamHeader.TableSizes = new uint[numberOfTables]; for (var i = 0; i < numberOfTables; i++) { ClrMetaDataStreamHeader.TableSizes[i] = TableStreamR.ReadUInt32(); } MetadataReader = new MetadataReader(TableStreamR.BaseStream); BlobStream = GetStreamBytes("#Blob", r); //Parse the tabels Tabels = new Tabels(this); #endregion }