Example #1
0
        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();
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
        }
Example #6
0
        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
                }
            }
        }
Example #7
0
        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);
                }
            }
        }
Example #8
0
 public bool TryGetSection(string name, out PESection section)
 {
     return((section = FindSection(name)) != null);
 }
Example #9
0
 public void InsertSection(int index, PESection section)
 {
     sections.Insert(index, section);
     fileHeader.NumberOfSections++;
 }
Example #10
0
 public void AddSection(PESection section)
 {
     sections.Add(section);
     fileHeader.NumberOfSections++;
 }