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); }
protected ELF64() { Header = new Elf64_Ehdr(); SectionHeader = null; SectionName = null; NameMaxLength = 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] = ""; } } }
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); }
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); }