/// <summary> /// Copy to an array buffer the ident array as found in ELF header <see cref="Elf32_Ehdr.e_ident"/> /// or <see cref="Elf64_Ehdr.e_ident"/>. /// </summary> /// <param name="objectFile">The object file to copy the ident from.</param> /// <param name="ident">A span receiving the ident. Must be >= 16 bytes length</param> public static void CopyIdentTo(this ElfObjectFile objectFile, Span <byte> ident) { if (objectFile == null) { throw new ArgumentNullException(nameof(objectFile)); } if (ident.Length < EI_NIDENT) { throw new ArgumentException($"Expecting span length to be >= {EI_NIDENT}"); } // Clear ident for (int i = 0; i < EI_NIDENT; i++) { ident[i] = 0; } ident[EI_MAG0] = ELFMAG0; ident[EI_MAG1] = ELFMAG1; ident[EI_MAG2] = ELFMAG2; ident[EI_MAG3] = ELFMAG3; ident[EI_CLASS] = (byte)objectFile.FileClass; ident[EI_DATA] = (byte)objectFile.Encoding; ident[EI_VERSION] = (byte)objectFile.Version; ident[EI_OSABI] = (byte)objectFile.OSABI.Value; ident[EI_ABIVERSION] = objectFile.AbiVersion; }
/// <summary> /// Tries to copy from an ident array as found in ELF header <see cref="Elf32_Ehdr.e_ident"/> to this ELF object file instance. /// or <see cref="Elf64_Ehdr.e_ident"/>. /// </summary> /// <param name="objectFile">The object file to receive the ident from.</param> /// <param name="ident">A span to read from. Must be >= 16 bytes length</param> /// <param name="diagnostics">The diagnostics</param> /// <returns><c>true</c> if copying the ident was successful. <c>false</c> otherwise</returns> public static bool TryCopyIdentFrom(this ElfObjectFile objectFile, ReadOnlySpan <byte> ident, DiagnosticBag diagnostics) { if (objectFile == null) { throw new ArgumentNullException(nameof(objectFile)); } if (ident.Length < EI_NIDENT) { diagnostics.Error(DiagnosticId.ELF_ERR_InvalidHeaderIdentLength, $"Invalid ELF Ident length found. Must be >= {EI_NIDENT}"); return(false); } if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 || ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) { diagnostics.Error(DiagnosticId.ELF_ERR_InvalidHeaderMagic, "Invalid ELF Magic found"); return(false); } objectFile.FileClass = (ElfFileClass)ident[EI_CLASS]; objectFile.Encoding = (ElfEncoding)ident[EI_DATA]; objectFile.Version = ident[EI_VERSION]; objectFile.OSABI = new ElfOSABI(ident[EI_OSABI]); objectFile.AbiVersion = ident[EI_ABIVERSION]; return(true); }
internal static void CopyIndentFrom(this ElfObjectFile objectFile, ReadOnlySpan <byte> ident) { objectFile.FileClass = (ElfFileClass)ident[EI_CLASS]; objectFile.Encoding = (ElfEncoding)ident[EI_DATA]; objectFile.Version = ident[EI_VERSION]; objectFile.OSABI = new ElfOSABIEx(ident[EI_OSABI]); objectFile.AbiVersion = ident[EI_ABIVERSION]; }
public static void PrintProgramHeaders(ElfObjectFile elf, TextWriter writer) { if (elf == null) { throw new ArgumentNullException(nameof(elf)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } writer.WriteLine(); if (elf.Segments.Count == 0) { writer.WriteLine("There are no program headers in this file."); return; } writer.WriteLine(elf.Segments.Count > 1 ? "Program Headers:" : "Program Header:"); writer.WriteLine(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"); for (int i = 0; i < elf.Segments.Count; i++) { var phdr = elf.Segments[i]; writer.WriteLine($" {GetElfSegmentType(phdr.Type),-14} 0x{phdr.Offset:x6} 0x{phdr.VirtualAddress:x16} 0x{phdr.PhysicalAddress:x16} 0x{phdr.Size:x6} 0x{phdr.SizeInMemory:x6} {GetElfSegmentFlags(phdr.Flags),3} 0x{phdr.Alignment:x}"); } if (elf.Segments.Count > 0 && elf.VisibleSectionCount > 0 && elf.SectionHeaderStringTable != null) { writer.WriteLine(); writer.WriteLine(" Section to Segment mapping:"); writer.WriteLine(" Segment Sections..."); for (int i = 0; i < elf.Segments.Count; i++) { var segment = elf.Segments[i]; writer.Write($" {i:00} "); foreach (var section in elf.Sections) { if (IsSectionInSegment(section, segment, true, true)) { writer.Write($"{GetElfSectionName(section)} "); } } writer.WriteLine(); } } }
public static void PrintElfHeader(ElfObjectFile elf, TextWriter writer) { if (elf == null) { throw new ArgumentNullException(nameof(elf)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } Span <byte> ident = stackalloc byte[ElfObjectFile.IdentSizeInBytes]; elf.CopyIdentTo(ident); writer.WriteLine("ELF Header:"); writer.Write(" Magic: "); foreach (var b in ident) { writer.Write($"{b:x2} "); } writer.WriteLine(); writer.WriteLine($" Class: {GetElfFileClass(elf.FileClass)}"); writer.WriteLine($" Data: {GetElfEncoding(elf.Encoding)}"); writer.WriteLine($" Version: {GetElfVersion((byte)elf.Version)}"); writer.WriteLine($" OS/ABI: {GetElfOsAbi(elf.OSABI)}"); writer.WriteLine($" ABI Version: {elf.AbiVersion}"); writer.WriteLine($" Type: {GetElfFileType(elf.FileType)}"); writer.WriteLine($" Machine: {GetElfArch(elf.Arch)}"); writer.WriteLine($" Version: 0x{elf.Version:x}"); writer.WriteLine($" Entry point address: 0x{elf.EntryPointAddress:x}"); writer.WriteLine($" Start of program headers: {elf.Layout.OffsetOfProgramHeaderTable} (bytes into file)"); writer.WriteLine($" Start of section headers: {elf.Layout.OffsetOfSectionHeaderTable} (bytes into file)"); writer.WriteLine($" Flags: {elf.Flags}"); writer.WriteLine($" Size of this header: {elf.Layout.SizeOfElfHeader} (bytes)"); writer.WriteLine($" Size of program headers: {elf.Layout.SizeOfProgramHeaderEntry} (bytes)"); writer.WriteLine($" Number of program headers: {elf.Segments.Count}"); writer.WriteLine($" Size of section headers: {elf.Layout.SizeOfSectionHeaderEntry} (bytes)"); writer.WriteLine($" Number of section headers: {elf.VisibleSectionCount}"); writer.WriteLine($" Section header string table index: {elf.SectionHeaderStringTable?.SectionIndex ?? 0}"); }
/// <summary> /// Tries to copy from an ident array as found in ELF header <see cref="Elf32_Ehdr.e_ident"/> to this ELF object file instance. /// or <see cref="Elf64_Ehdr.e_ident"/>. /// </summary> /// <param name="objectFile">The object file to receive the ident from.</param> /// <param name="ident">A span to read from. Must be >= 16 bytes length</param> /// <param name="diagnostics">The diagnostics</param> /// <returns><c>true</c> if copying the ident was successful. <c>false</c> otherwise</returns> public static bool TryCopyIdentFrom(this ElfObjectFile objectFile, ReadOnlySpan <byte> ident, DiagnosticBag diagnostics) { if (objectFile == null) { throw new ArgumentNullException(nameof(objectFile)); } if (ident.Length < EI_NIDENT) { diagnostics.Error(DiagnosticId.ELF_ERR_InvalidHeaderIdentLength, $"Invalid ELF Ident length found. Must be >= {EI_NIDENT}"); return(false); } if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 || ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) { diagnostics.Error(DiagnosticId.ELF_ERR_InvalidHeaderMagic, "Invalid ELF Magic found"); return(false); } CopyIndentFrom(objectFile, ident); return(true); }
/// <summary> /// Prints an <see cref="ElfObjectFile"/> to the specified writer. /// </summary> /// <param name="elf">The object file to print.</param> /// <param name="writer">The destination text writer.</param> public static void Print(this ElfObjectFile elf, TextWriter writer) { if (elf == null) { throw new ArgumentNullException(nameof(elf)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } PrintElfHeader(elf, writer); PrintSectionHeaders(elf, writer); PrintSectionGroups(elf, writer); PrintProgramHeaders(elf, writer); PrintDynamicSections(elf, writer); PrintRelocations(elf, writer); PrintUnwind(elf, writer); PrintSymbolTables(elf, writer); PrintVersionInformation(elf, writer); PrintNotes(elf, writer); }
public static void PrintRelocations(ElfObjectFile elf, TextWriter writer) { if (elf == null) { throw new ArgumentNullException(nameof(elf)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } bool hasRelocations = false; foreach (var section in elf.Sections) { if (section.Type == ElfSectionType.Relocation || section.Type == ElfSectionType.RelocationAddends) { hasRelocations = true; var relocTable = (ElfRelocationTable)section; writer.WriteLine(); writer.WriteLine($"Relocation section {(elf.SectionHeaderStringTable == null ? "0" : $"'{section.Name}'")} at offset 0x{section.Offset:x} contains {relocTable.Entries.Count} {(relocTable.Entries.Count > 1 ? "entries" : "entry")}:");
public static void PrintSectionGroups(ElfObjectFile elf, TextWriter writer) { if (elf == null) { throw new ArgumentNullException(nameof(elf)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (elf.Sections.Count == 0) { writer.WriteLine(); writer.WriteLine("There are no sections to group in this file."); return; } writer.WriteLine(); writer.WriteLine("There are no section groups in this file."); // TODO }
public static void PrintSectionHeaders(ElfObjectFile elf, TextWriter writer) { if (elf == null) { throw new ArgumentNullException(nameof(elf)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } writer.WriteLine(); if (elf.VisibleSectionCount == 0) { writer.WriteLine("There are no sections in this file."); return; } writer.WriteLine(elf.VisibleSectionCount > 1 ? "Section Headers:" : "Section Header:"); writer.WriteLine(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al"); for (int i = 0; i < elf.Sections.Count; i++) { var section = elf.Sections[i]; if (section.IsShadow) { continue; } writer.WriteLine($" [{section.SectionIndex,2:#0}] {GetElfSectionName(section),-17} {GetElfSectionType(section.Type),-15} {section.VirtualAddress:x16} {section.Offset:x6} {section.Size:x6} {section.TableEntrySize:x2} {GetElfSectionFlags(section.Flags),3} {section.Link.GetIndex(),2} {section.Info.GetIndex(),3} {section.Alignment,2}"); } writer.WriteLine(@"Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), l (large), p (processor specific)"); }
public ElfWriterDirect(ElfObjectFile elfObjectFile, Stream stream) : base(elfObjectFile, stream) { }
protected ElfWriter(ElfObjectFile objectFile, Stream stream) : base(objectFile, stream) { _encoder = new TEncoder(); }
protected ElfReader(ElfObjectFile objectFile, Stream stream, ElfReaderOptions options) : base(objectFile, stream, options) { _decoder = new TDecoder(); }
public ElfReaderDirect(ElfObjectFile elfObjectFile, Stream stream, ElfReaderOptions options) : base(elfObjectFile, stream, options) { }
private protected ElfWriter(ElfObjectFile objectFile, Stream stream) : base(stream) { ObjectFile = objectFile ?? throw new ArgumentNullException(nameof(objectFile)); }
private protected ElfReader(ElfObjectFile objectFile, Stream stream, ElfReaderOptions readerOptions) : base(stream) { ObjectFile = objectFile ?? throw new ArgumentNullException(nameof(objectFile)); Options = readerOptions; }
internal static ElfReader Create(ElfObjectFile objectFile, Stream stream, ElfReaderOptions options) { var thisComputerEncoding = BitConverter.IsLittleEndian ? ElfEncoding.Lsb : ElfEncoding.Msb; return(objectFile.Encoding == thisComputerEncoding ? (ElfReader) new ElfReaderDirect(objectFile, stream, options) : new ElfReaderSwap(objectFile, stream, options)); }
public ElfWriterSwap(ElfObjectFile elfObjectFile, Stream stream) : base(elfObjectFile, stream) { }