예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ElfFile"/> class.
        /// </summary>
        ///
        /// <param name="header">
        /// The ELF file header.
        /// </param>
        ///
        /// <param name="segments">
        /// The program header table.
        /// </param>
        ///
        /// <param name="sections">
        /// The section header table.
        /// </param>
        internal ElfFile(ElfHeader header, ElfProgramHeaderTable segments, ElfSectionHeaderTable sections)
        {
            Header = header;

            Segments = segments;
            Sections = sections;
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ElfProgramHeaderTable"/> class by examining an ELF header.
        /// </summary>
        ///
        /// <param name="reader">
        /// The reader used to extract the data needed to parse the ELF file.
        /// </param>
        ///
        /// <param name="header">
        /// The ELF header used to extract the metadata about this program header table.
        /// </param>
        ///
        /// <param name="sections">
        /// The list of sections which will be parsed to extract the sections corresponding to this segment.
        /// </param>
        internal ElfProgramHeaderTable(BinaryReader reader, ElfHeader header, ElfSectionHeaderTable sections)
        {
            // Initialize all segments
            for (var i = 0; i < header.ProgramHeaderEntryCount; i++)
            {
                ElfSegment segment;

                switch (header.Class)
                {
                case ElfClass.Elf32:
                {
                    segment = new Bit32.ElfSegment(reader, (long)(header.ProgramHeaderOffset + (ulong)(i * header.ProgramHeaderSize)));
                    break;
                }

                case ElfClass.Elf64:
                {
                    segment = new Bit64.ElfSegment(reader, (long)(header.ProgramHeaderOffset + (ulong)(i * header.ProgramHeaderSize)));
                    break;
                }

                default:
                {
                    throw new InvalidOperationException("Unreachable case reached");
                }
                }

                segment.Sections = sections.Where(s => s.Address >= segment.VirtualAddress && s.Address < segment.VirtualAddress + segment.MemorySize).ToList().AsReadOnly();

                segments.Add(segment);
            }
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ElfSectionHeaderTable"/> class by examining an ELF header.
        /// </summary>
        ///
        /// <param name="reader">
        /// The reader used to extract the data needed to parse the ELF file.
        /// </param>
        ///
        /// <param name="header">
        /// The ELF header used to extract the metadata about this section header table.
        /// </param>
        internal ElfSectionHeaderTable(BinaryReader reader, ElfHeader header)
        {
            // Initialize all segments
            for (var i = 0; i < header.SectionHeaderEntryCount; ++i)
            {
                ElfSection section;

                switch (header.Class)
                {
                case ElfClass.Elf32:
                {
                    section = new Bit32.ElfSection(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));

                    switch (section.Type)
                    {
                    case ElfSectionType.Dynamic:
                    {
                        section = new Bit32.ElfDynamicSection(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }

                    case ElfSectionType.DynSym:
                    case ElfSectionType.SymTab:
                    {
                        section = new Bit32.ElfSymbolTable(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }

                    case ElfSectionType.Rel:
                    case ElfSectionType.RelA:
                    {
                        section = new Bit32.ElfRelocationSection(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }

                    case ElfSectionType.StrTab:
                    {
                        section = new Bit32.ElfStringTable(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }
                    }

                    break;
                }

                case ElfClass.Elf64:
                {
                    section = new Bit64.ElfSection(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));

                    switch (section.Type)
                    {
                    case ElfSectionType.Dynamic:
                    {
                        section = new Bit64.ElfDynamicSection(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }

                    case ElfSectionType.DynSym:
                    case ElfSectionType.SymTab:
                    {
                        section = new Bit64.ElfSymbolTable(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }

                    case ElfSectionType.Rel:
                    case ElfSectionType.RelA:
                    {
                        section = new Bit64.ElfRelocationSection(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }

                    case ElfSectionType.StrTab:
                    {
                        section = new Bit64.ElfStringTable(reader, (long)(header.SectionHeaderOffset + (ulong)(i * header.SectionHeaderSize)));
                        break;
                    }
                    }

                    break;
                }

                default:
                {
                    throw new InvalidOperationException("Unreachable case reached");
                }
                }

                sections.Add(section);
            }

            ushort shStrIndex = header.StringSectionIndex;

            if (shStrIndex != (ushort)ElfSectionType.Null)
            {
                // Initialize section names
                for (var i = 0; i < header.SectionHeaderEntryCount; i++)
                {
                    sections[i].Name = reader.ReadELFString(this[shStrIndex], this[i].NameOffset);
                }
            }

            // Parse all dynamic entries names now that we have all sections initalized
            foreach (ElfDynamicSection dynamicSection in sections.OfType <ElfDynamicSection>())
            {
                ElfDynamicEntry strTab = dynamicSection.FirstOrDefault(e => e.Tag == ElfDynamicArrayTag.StrTab);

                if (strTab != null)
                {
                    ElfSection dynSymSection = sections.First(s => s.Address == strTab.Value);

                    foreach (ElfDynamicEntry entry in dynamicSection)
                    {
                        switch (entry.Tag)
                        {
                        case ElfDynamicArrayTag.Needed:
                        case ElfDynamicArrayTag.SOName:
                        case ElfDynamicArrayTag.RPath:
                        case ElfDynamicArrayTag.RunPath:
                        {
                            entry.Name = reader.ReadELFString(dynSymSection, entry.Value);
                            break;
                        }
                        }
                    }
                }
            }

            var symTab = sections.OfType <ElfSymbolTable>().FirstOrDefault();

            if (symTab != null)
            {
                var strTab = sections[(int)symTab.Link];

                if (strTab is ElfStringTable)
                {
                    // Parse all relocation entries symbols now that we have all sections initalized
                    foreach (ElfSymbolTableEntry entry in symTab)
                    {
                        entry.Name = reader.ReadELFString(strTab, entry.NameIndex);
                    }

                    // Parse all relocation entries symbols now that we have all sections initalized
                    foreach (ElfRelocationSection relocationSection in sections.OfType <ElfRelocationSection>())
                    {
                        foreach (ElfRelocationEntry entry in relocationSection)
                        {
                            entry.Symbol      = symTab[entry.SymbolIndex].Name;
                            entry.SymbolValue = symTab[entry.SymbolIndex].Value;
                        }
                    }
                }
            }
        }