Пример #1
0
        private unsafe void WriteSectionHeader64()
        {
            var hdr = new Elf64_Ehdr();

            ObjectFile.CopyIdentTo(new Span <byte>(hdr.e_ident, EI_NIDENT));

            _encoder.Encode(out hdr.e_type, (ushort)ObjectFile.FileType);
            _encoder.Encode(out hdr.e_machine, ObjectFile.Arch.Value);
            _encoder.Encode(out hdr.e_version, EV_CURRENT);
            _encoder.Encode(out hdr.e_entry, ObjectFile.EntryPointAddress);
            _encoder.Encode(out hdr.e_ehsize, Layout.SizeOfElfHeader);
            _encoder.Encode(out hdr.e_flags, (uint)ObjectFile.Flags);

            // program headers
            _encoder.Encode(out hdr.e_phoff, Layout.OffsetOfProgramHeaderTable);
            _encoder.Encode(out hdr.e_phentsize, Layout.SizeOfProgramHeaderEntry);
            _encoder.Encode(out hdr.e_phnum, (ushort)ObjectFile.Segments.Count);

            // entries for sections
            _encoder.Encode(out hdr.e_shoff, Layout.OffsetOfSectionHeaderTable);
            _encoder.Encode(out hdr.e_shentsize, (ushort)sizeof(Elf64_Shdr));
            _encoder.Encode(out hdr.e_shnum, (ushort)ObjectFile.VisibleSectionCount);
            _encoder.Encode(out hdr.e_shstrndx, (ushort)(ObjectFile.SectionHeaderStringTable?.SectionIndex ?? (ushort)0));

            Write(hdr);
        }
Пример #2
0
 protected ELF64()
 {
     Header        = new Elf64_Ehdr();
     SectionHeader = null;
     SectionName   = null;
     NameMaxLength = 0;
 }
Пример #3
0
        public ELF64(string filename, bool readSectionHeaders)
            : this()
        {
            FileStream fs = File.Open(filename, FileMode.Open);

            byte[] ehdrBytes = new byte[64];
            fs.Read(ehdrBytes, 0, ehdrBytes.Length);
            fs.Close();

            if (!(ehdrBytes[(byte)EI.MagicNumber0] == 0x7F &&
                  ehdrBytes[(byte)EI.MagicNumber1] == 'E' &&
                  ehdrBytes[(byte)EI.MagicNumber2] == 'L' &&
                  ehdrBytes[(byte)EI.MagicNumber3] == 'F'))
            {
                throw new FormatException("It is not an ELF file.");
            }

            else if (ehdrBytes[(byte)EI.FileClass] == (byte)EC.ELF32)
            {
                throw new FormatException("It is an ELF32 file.");
            }
            else if (ehdrBytes[(byte)EI.FileClass] != (byte)EC.ELF64)
            {
                throw new FormatException("It is an invalid ELF class.");
            }

            ValueRead read = new ValueRead(ehdrBytes[(byte)EI.DataEncoding]);

            Header = new Elf64_Ehdr(ehdrBytes, read);

            SectionHeader = new Elf64_Shdr[Header.e_shnum];
            SectionName   = new string[Header.e_shnum];

            if (readSectionHeaders && SectionHeader.Length != 0)
            {
                fs = File.Open(filename, FileMode.Open);
                byte[] shdrBytes = new byte[Header.e_shnum * Header.e_shentsize];
                fs.Position = (long)Header.e_shoff;
                fs.Read(shdrBytes, 0, shdrBytes.Length);
                fs.Close();

                SectionHeader = new Elf64_Shdr[Header.e_shnum];
                for (int i = 0; i < Header.e_shnum; i++)
                {
                    SectionHeader[i] = new Elf64_Shdr(shdrBytes, (uint)(Header.e_shentsize * i), read);
                    SectionName[i]   = "";
                }
            }
        }
Пример #4
0
        private static void GetEmbeddedModule64(ModuleReader reader, byte[] ident)
        {
            // Read the endiannes.
            bool big = ident[(int)ElfIdent.EI_DATA] == (int)ElfData.ELFDATA2MSB;

            // Read the header.
            Elf64_Ehdr header = new Elf64_Ehdr();

            header.Read(reader, big);

            // Reject files without section names.
            if (header.e_shstrndex == (int)ElfSectionNumber.SHN_UNDEF)
            {
                throw new ModuleException("Unsupported elfs without section names");
            }

            // Read the "section names" section.
            reader.SetPosition(header.e_shoff + (ulong)header.e_shstrndex * header.e_shentsize);
            Elf64_Shdr namesHeader = new Elf64_Shdr();

            namesHeader.Read(reader, big);

            // Reject files without real section names.
            if (namesHeader.sh_size == 0)
            {
                throw new ModuleException("This elf doesn't have section names.");
            }

            // Read the name table.
            byte[] nameTable;
            reader.SetPosition(namesHeader.sh_offset);
            reader.Read(out nameTable, (int)namesHeader.sh_size);

            // Move to the section header table.
            reader.SetPosition(header.e_shoff);

            // Read the section until hit '.cbm'.
            Elf64_Shdr    sectionHeader = new Elf64_Shdr();
            bool          found         = false;
            StringBuilder builder       = new StringBuilder();

            for (int i = 0; i < header.e_shnum; ++i)
            {
                // Read the section header.
                sectionHeader.Read(reader, big);

                // Check the section name.
                if (sectionHeader.sh_name >= nameTable.Length)
                {
                    throw new ModuleException("Invalid section name.");
                }

                // Build the section name.
                builder.Length = 0;
                int pos = (int)sectionHeader.sh_name;
                while (nameTable[pos] != 0)
                {
                    builder.Append((char)nameTable[pos++]);
                }
                string sectionName = builder.ToString();

                // Compare the section name.
                if (sectionName == ".cbm")
                {
                    found = true;
                    break;
                }

                // Skip the extra data.
                reader.Skip(header.e_shentsize - Elf64_Shdr.Size);
            }

            // Make sure the section was found.
            if (!found)
            {
                throw new ModuleException("The elf doesn't have a chela module.");
            }

            // Make sure the section type is PROGBITS.
            if (sectionHeader.sh_type != (int)ElfSectionType.SHT_PROGBITS)
            {
                throw new ModuleException("The elf section that can have the module is not supported.");
            }

            // Move to the section offset.
            reader.SetPosition(sectionHeader.sh_offset);
        }
Пример #5
0
        private static void GetEmbeddedModule64(ModuleReader reader, byte[] ident)
        {
            // Read the endiannes.
            bool big = ident[(int)ElfIdent.EI_DATA] == (int)ElfData.ELFDATA2MSB;

            // Read the header.
            Elf64_Ehdr header = new Elf64_Ehdr();
            header.Read(reader, big);

            // Reject files without section names.
            if(header.e_shstrndex == (int)ElfSectionNumber.SHN_UNDEF)
                throw new ModuleException("Unsupported elfs without section names");

            // Read the "section names" section.
            reader.SetPosition(header.e_shoff + (ulong)header.e_shstrndex*header.e_shentsize);
            Elf64_Shdr namesHeader = new Elf64_Shdr();
            namesHeader.Read(reader, big);

            // Reject files without real section names.
            if(namesHeader.sh_size == 0)
                throw new ModuleException("This elf doesn't have section names.");

            // Read the name table.
            byte[] nameTable;
            reader.SetPosition(namesHeader.sh_offset);
            reader.Read(out nameTable, (int)namesHeader.sh_size);

            // Move to the section header table.
            reader.SetPosition(header.e_shoff);

            // Read the section until hit '.cbm'.
            Elf64_Shdr sectionHeader = new Elf64_Shdr();
            bool found = false;
            StringBuilder builder = new StringBuilder();
            for(int i = 0; i < header.e_shnum; ++i)
            {
                // Read the section header.
                sectionHeader.Read(reader, big);

                // Check the section name.
                if(sectionHeader.sh_name >= nameTable.Length)
                    throw new ModuleException("Invalid section name.");

                // Build the section name.
                builder.Length = 0;
                int pos = (int)sectionHeader.sh_name;
                while(nameTable[pos] != 0)
                    builder.Append((char)nameTable[pos++]);
                string sectionName = builder.ToString();

                // Compare the section name.
                if(sectionName == ".cbm")
                {
                    found = true;
                    break;
                }

                // Skip the extra data.
                reader.Skip(header.e_shentsize - Elf64_Shdr.Size);
            }

            // Make sure the section was found.
            if(!found)
                throw new ModuleException("The elf doesn't have a chela module.");

            // Make sure the section type is PROGBITS.
            if(sectionHeader.sh_type != (int)ElfSectionType.SHT_PROGBITS)
                throw new ModuleException("The elf section that can have the module is not supported.");

            // Move to the section offset.
            reader.SetPosition(sectionHeader.sh_offset);
        }