예제 #1
0
        /// <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);
        }
예제 #3
0
 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];
 }
예제 #4
0
        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();
                }
            }
        }
예제 #5
0
        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}");
        }
예제 #6
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);
        }
예제 #7
0
 /// <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);
 }
예제 #8
0
        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")}:");
예제 #9
0
        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
        }
예제 #10
0
        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)");
        }
예제 #11
0
 public ElfWriterDirect(ElfObjectFile elfObjectFile, Stream stream) : base(elfObjectFile, stream)
 {
 }
예제 #12
0
 protected ElfWriter(ElfObjectFile objectFile, Stream stream) : base(objectFile, stream)
 {
     _encoder = new TEncoder();
 }
예제 #13
0
 protected ElfReader(ElfObjectFile objectFile, Stream stream, ElfReaderOptions options) : base(objectFile, stream, options)
 {
     _decoder = new TDecoder();
 }
예제 #14
0
 public ElfReaderDirect(ElfObjectFile elfObjectFile, Stream stream, ElfReaderOptions options) : base(elfObjectFile, stream, options)
 {
 }
예제 #15
0
 private protected ElfWriter(ElfObjectFile objectFile, Stream stream) : base(stream)
 {
     ObjectFile = objectFile ?? throw new ArgumentNullException(nameof(objectFile));
 }
예제 #16
0
 private protected ElfReader(ElfObjectFile objectFile, Stream stream, ElfReaderOptions readerOptions) : base(stream)
 {
     ObjectFile = objectFile ?? throw new ArgumentNullException(nameof(objectFile));
     Options    = readerOptions;
 }
예제 #17
0
        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));
        }
예제 #18
0
 public ElfWriterSwap(ElfObjectFile elfObjectFile, Stream stream) : base(elfObjectFile, stream)
 {
 }