private void Parse(Stream stream) { rawData = new byte[stream.Length]; stream.Read(rawData, 0, (int)stream.Length); stream.Seek(0, SeekOrigin.Begin); BinaryReader reader = new BinaryReader(stream); fileHeader = PEUtility.FromBinaryReader <IMAGE_FILE_HEADER>(reader); // Read the sections sections = new List <PESection>(); for (int i = 0; i < fileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER header; header = PEUtility.FromBinaryReader <IMAGE_SECTION_HEADER>(reader); PESection section = new PESection(this, header); section.Parse(ref rawData); sections.Add(section); } // Read the symbol table from fileHeader.PointerToSymbolTable symbolTable = new SymbolTable(fileHeader.NumberOfSymbols); stream.Seek(fileHeader.PointerToSymbolTable, SeekOrigin.Begin); for (int i = 0; i < fileHeader.NumberOfSymbols; i++) { IMAGE_SYMBOL symbol; symbol = PEUtility.FromBinaryReader <IMAGE_SYMBOL>(reader); symbolTable.AddSymbol(symbol, i); } uint pointerToStringTable = fileHeader.PointerToSymbolTable + (uint)(fileHeader.NumberOfSymbols * Marshal.SizeOf(typeof(IMAGE_SYMBOL))); stream.Seek(pointerToStringTable, SeekOrigin.Begin); uint stringTableSize = PEUtility.FromBinaryReader <UInt32>(reader); for (ushort i = (ushort)Marshal.SizeOf(typeof(UInt32)); i < stringTableSize;) { String stringEntry = PEUtility.StringFromBinaryReader(reader); symbolTable.AddString(stringEntry, i); i += (ushort)(stringEntry.Length + 1); // include NULL terminator } Console.WriteLine("Object File: {0}", sourceFile); Console.WriteLine(symbolTable.ToString()); Console.WriteLine("Sections:"); foreach (PESection s in sections) { Console.WriteLine(s.ToString()); } Console.WriteLine(); }
/// <summary> /// Retrieve the contents of the specified section. /// </summary> /// <param name="name">Name of section whose contents should be retrieved</param> /// <returns>Byte array of section contents</returns> public byte[] GetSectionData(string name) { PESection section = sections.Find(s => s.Name == name); if (section == null) { return(null); } else { return(section.Data); } }
/// <summary> /// Write the contents of the provided byte array into the section specified. /// </summary> /// <param name="name">Name of section</param> /// <param name="data">Byte array of section data</param> /// <returns></returns> public uint WriteSectionData(string name, byte[] data) { PESection section = sections.Find(s => s.Name == name); if (section == null) { return(0); } section.Data = new byte[data.Length]; Array.Copy(data, 0, section.Data, 0, data.Length); return((uint)data.Length); }
/// <summary> /// Parse a PE. /// </summary> /// <param name="stream">A stream of the PE contents.</param> private static PEFile FromStream(Stream stream) { var pe = new PEFile(); using (var br = new BinaryReader(stream)) { pe.dosHeader = br.ReadStruct <IMAGE_DOS_HEADER>(); int stubSize = (int)pe.dosHeader.e_lfanew - Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)); pe.dosStub = br.ReadBytes(stubSize); // Add 4 bytes to the offset stream.Seek(pe.dosHeader.e_lfanew, SeekOrigin.Begin); pe.ntSignature = br.ReadStruct <IMAGE_NT_HEADERS>(); if (!pe.ntSignature.IsValid) { throw new FileLoadException(); } pe.fileHeader = br.ReadStruct <IMAGE_FILE_HEADER>(); pe.optionalStandard = br.ReadStruct <IMAGE_OPTIONAL_HEADER_STANDARD>(); switch (pe.optionalStandard.Magic) { case IMAGE_OPTIONAL_HEADER_STANDARD.MAGIC_PE32: pe.optionalHeader32 = br.ReadStruct <IMAGE_OPTIONAL_HEADER_32>(); break; case IMAGE_OPTIONAL_HEADER_STANDARD.MAGIC_ROM: throw new NotSupportedException(); case IMAGE_OPTIONAL_HEADER_STANDARD.MAGIC_PE32PLUS: pe.optionalHeader32plus = br.ReadStruct <IMAGE_OPTIONAL_HEADER_32PLUS>(); break; default: throw new FileLoadException(); } pe.dataDirectories = br.ReadStruct <IMAGE_DATA_DIRECTORIES>(); pe.sections = new List <PESection>(pe.fileHeader.NumberOfSections); for (int i = 0; i < pe.fileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER header = br.ReadStruct <IMAGE_SECTION_HEADER>(); PESection section = new PESection(header); section.Parse(stream); pe.sections.Add(section); } } return(pe); }
public List <PESection> MergeSections() { List <PESection> mergedSections = new List <PESection>(); IDictionaryEnumerator group = sectionDict.GetEnumerator(); String str = String.Empty; while (group.MoveNext()) { PESection s = MergeSectionGroup((ArrayList)group.Value); s.Name = (String)group.Key; mergedSections.Add(s); } return(mergedSections); }
private void Parse(Stream stream) { using (var reader = new BinaryReader(stream, Encoding.ASCII, true)) { fileHeader = reader.ReadStruct <IMAGE_FILE_HEADER>(); // Read the sections Sections = new List <PESection>(); for (int i = 0; i < fileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER header; header = reader.ReadStruct <IMAGE_SECTION_HEADER>(); PESection section = new PESection(this, header); section.Parse(stream); Sections.Add(section); } // Read the symbol table from fileHeader.PointerToSymbolTable SymbolTable = new SymbolTable(fileHeader.NumberOfSymbols); stream.Seek(fileHeader.PointerToSymbolTable, SeekOrigin.Begin); for (int i = 0; i < fileHeader.NumberOfSymbols; i++) { IMAGE_SYMBOL symbol; symbol = reader.ReadStruct <IMAGE_SYMBOL>(); SymbolTable.AddSymbol(symbol, i); } uint pointerToStringTable = fileHeader.PointerToSymbolTable + (uint)(fileHeader.NumberOfSymbols * Marshal.SizeOf(typeof(IMAGE_SYMBOL))); stream.Seek(pointerToStringTable, SeekOrigin.Begin); uint stringTableSize = reader.ReadStruct <uint>(); for (ushort i = (ushort)Marshal.SizeOf(typeof(uint)); i < stringTableSize;) { string stringEntry = reader.ReadCString(); SymbolTable.AddString(stringEntry, i); i += (ushort)(stringEntry.Length + 1); // include NULL terminator } } }
public static int Compare(PESection x, PESection y) { if (!x.Name.Contains("$") && !y.Name.Contains("$")) { // COFF file ordinal is used as tie-breaker return(COFFTool.Compare(x.SourceCoff, y.SourceCoff)); } // Always give preference to sections with no $ else if (!x.Name.Contains("$") && y.Name.Contains("$")) { return(-1); } else if (x.Name.Contains("$") && !y.Name.Contains("$")) { return(1); } // If both have a $ grouping, order by $ suffix. else // (x.Name.Contains("$") && y.Name.Contains("$")) { string xdollar = x.Name.Substring(x.Name.IndexOf('$') + 1); string ydollar = y.Name.Substring(x.Name.IndexOf('$') + 1); int cmp = String.Compare(xdollar, ydollar); // COFF file ordinal is used as tie-breaker if (cmp == 0) { return(COFFTool.Compare(x.SourceCoff, y.SourceCoff)); } else { return(cmp); } } }
public bool TryGetSection(string name, out PESection section) { return((section = FindSection(name)) != null); }
public void InsertSection(int index, PESection section) { sections.Insert(index, section); fileHeader.NumberOfSections++; }
public void AddSection(PESection section) { sections.Add(section); fileHeader.NumberOfSections++; }