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 }
private void Init(byte[] data) { #region Parse PE & Strong name hash 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); try { ClrHeader = ReadCLRHeader(r, PeHeader); } catch (Exception ex) { throw new Exception("Error: Invaild metadata: " + ex.Message); } //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)RelativeVirtualAddressToFileOffset(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 //Read all of the tabels List <StreamHeader> Streams = new List <StreamHeader>(); //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.ReadNullTermString(); //#~ Stream if (hdr.Name.Length == 2) { r.BaseStream.Position += 1; //Skip past the 4 zeros } //#Strings stream else if (hdr.Name.Length == 8) { r.BaseStream.Position += 3; } //#US Stream else if (hdr.Name.Length == 3) { } //#GUID Stream else if (hdr.Name.Length == 5) { r.BaseStream.Position += 2; } Console.WriteLine("Stream: " + hdr.Name + " Size: " + hdr.Size + " Offset: " + hdr.Offset); Streams.Add(hdr); } //Parse the #String stream var bytes = GetStreamBytes(r, Streams[1], ClrHeader.MetaDataDirectoryAddress, PeHeader.Sections); ClrStringsStream = new StringsStreamReader(bytes).Read(); //Parse the #US Stream var bytes2 = GetStreamBytes(r, Streams[2], ClrHeader.MetaDataDirectoryAddress, PeHeader.Sections); ClrUsStream = new USStreamReader(bytes2).Read(); #endregion #region Parse #~ Stream //Parse the #~ stream BinaryReader TableStreamR = new BinaryReader(new MemoryStream( GetStreamBytes(r, Streams[0], ClrHeader.MetaDataDirectoryAddress, PeHeader.Sections))); 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); //Parse the tabels tabels = new Tabels(this); #endregion }