/// <summary> /// Gets the module load offset. /// </summary> /// <param name="baseAddress">The module base address.</param> public ulong GetModuleLoadOffset(ulong baseAddress) { // Check if we are looking for load offset of main module if (baseAddress == files[0].start) { // Find file with symbols for main module string mainModulePath = files[0].name; if (!string.IsNullOrEmpty(mainModulePath)) { mainModulePath = ElfCoreDumpDebuggingEngine.GetModuleMappedImage(this, mainModulePath); } // Find offset for main module ulong offset = 0; if (!string.IsNullOrEmpty(mainModulePath)) { var elf = ELFReader.Load <ulong>(mainModulePath); foreach (AuxvEntry entry in auxVector) { if (entry.Type == AuxvEntryType.Entry) { offset = entry.Value - elf.EntryPoint; break; } } } return(offset); } return(0); }
/// <summary> /// Initializes a new instance of the <see cref="ElfImage"/> class. /// </summary> /// <param name="path">The image path.</param> /// <param name="loadOffset">Offset from where image was loaded.</param> public ElfImage(string path, ulong loadOffset = 0) { elf = ELFReader.Load <ulong>(path); LoadOffset = loadOffset; foreach (var segment in elf.Segments) { if (segment.Type == ELFSharp.ELF.Segments.SegmentType.ProgramHeader) { CodeSegmentOffset = segment.Address - (ulong)segment.Offset; break; } } List <PublicSymbol> publicSymbols = new List <PublicSymbol>(); SymbolTable <ulong> symbols = elf.Sections.FirstOrDefault(s => s.Type == SectionType.SymbolTable) as SymbolTable <ulong>; if (symbols == null || !symbols.Entries.Any()) { symbols = elf.Sections.FirstOrDefault(s => s.Type == SectionType.DynamicSymbolTable) as SymbolTable <ulong>; } if (symbols != null) { foreach (SymbolEntry <ulong> symbol in symbols.Entries) { publicSymbols.Add(new PublicSymbol(symbol.Name, symbol.Value - CodeSegmentOffset)); } } PublicSymbols = publicSymbols; }
public void GithubIssueNo24() { var elf = ELFReader.Load(Utilities.GetBinaryLocation("issue24.elf")); var dynamicSymbolSection = (SymbolTable <uint>)elf.GetSection(".dynsym"); dynamicSymbolSection.Entries.Any(x => x.Name == "<corrupt>"); }
public void ShouldFindAllSymbols32() { var elf = ELFReader.Load(Utilities.GetBinaryLocation("hello32le")); var symtab = (ISymbolTable)elf.GetSection(".symtab"); Assert.AreEqual(64, symtab.Entries.Count()); }
public void ShouldFindAllStrings64() { using var elf = ELFReader.Load(Utilities.GetBinaryStream("hello64le"), true); Assert.IsTrue(elf.HasSectionsStringTable, "Sections string table was not found in 64 bit ELF."); Assert.AreEqual(30, elf.SectionsStringTable.Strings.Count()); }
public void ShouldFindProperEntrySize32() { var elf = ELFReader.Load <uint>(Utilities.GetBinaryLocation("hello32le")); var header = elf.Sections.First(x => x.Name == ".dynsym"); Assert.AreEqual(0x10, header.EntrySize); }
public void ShouldFindAllNotes32() { using var elf = ELFReader.Load(Utilities.GetBinaryStream("hello32le"), true); var notes = elf.GetSections <INoteSection>(); Assert.AreEqual(2, notes.Count()); }
public void ShouldFindProperAlignment64() { var elf = ELFReader.Load <long>(Utilities.GetBinary("hello64le")); var header = elf.Sections.First(x => x.Name == ".text"); Assert.AreEqual(16, header.Alignment); }
public void ShouldFindProperAlignment32() { var elf = ELFReader.Load <uint>(Utilities.GetBinary("hello32le")); var segment = elf.Segments.First(x => x.Address == 0x08048000); Assert.AreEqual(0x1000, segment.Alignment); }
public void ShouldFindProperAlignment64() { var elf = ELFReader.Load <ulong>(Utilities.GetBinary("hello64le")); var segment = elf.Segments.First(x => x.Address == 0x6006c8); Assert.AreEqual(8, segment.Alignment); }
public static void Extract(string inputMbnFilePath, string outputDirectory, bool noExtraData, Logger logger) { try { var elf = ELFReader.Load(inputMbnFilePath); var segments = elf.Segments.ToArray(); if (segments.Length < 3) { throw new MbnExtractorException(Strings.MbnExtractorInvalidFormatElfDataNotExist); } var segment = segments[2]; var contents = segment.GetFileContents(); using (var stream = new MemoryStream(contents)) { ParseImage(stream, outputDirectory, noExtraData, logger); } } catch (MbnExtractorException e) { throw e; } catch (Exception e) { throw new MbnExtractorException(e.Message); } }
private void loadElfBytes(byte[] rawFile) { using (var dataStream = new MemoryStream(rawFile)) { using (var elf = ELFReader.Load(dataStream, false)) { // Sections that are relevant: // Section 1, 2, 3, 4 // TODO: Remove hardcode for (int i = 1; i < 5; i++) { int offset = elfData.Length; var data = elf.Sections[i].GetContents(); Array.Resize(ref elfData, elfData.Length + data.Length); data.CopyTo(elfData, offset); } float num = (float)elfData.Length / 64; double frac = num - Math.Floor(num); int padding = (int)((1.0f - frac) * 64); Array.Resize(ref elfData, elfData.Length + padding); StatusWrite("ELF file loaded!"); isElfLoaded = true; SetFlashButtonStatus(isElfLoaded && (SelectedDevice != null)); } } }
public void ShouldFindAllSymbols64() { using var elf = ELFReader.Load(Utilities.GetBinaryStream("hello64le"), true); var symtab = (ISymbolTable)elf.GetSection(".symtab"); Assert.AreEqual(64, symtab.Entries.Count()); }
public void ShouldFindProperAlignment32() { var elf = ELFReader.Load <uint>(Utilities.GetBinary("hello32le")); var header = elf.Sections.First(x => x.Name == ".init"); Assert.AreEqual(4, header.Alignment); }
public bool TryProcessElfFile(string filePath, out string soName, out IList <string> depends) { try { if (ELFReader.TryLoad(filePath, out var elf)) { if (elf.Class == Class.Bit32) { (soName, depends) = Process32BitElfFile((ELF <uint>)elf); return(true); } else if (elf.Class == Class.Bit64) { (soName, depends) = Process64BitElfFile((ELF <ulong>)elf); return(true); } } } catch (Exception e) { Logger.Error(e, $"Failed to process ELF file: {filePath}"); } soName = null; depends = null; return(false); }
public void ShouldOpenEmptyStringTableElf() { using var elf = ELFReader.Load(Utilities.GetBinaryStream("libcoreclr"), true); var section = elf.GetSection(".dynstr"); Assert.AreEqual(SectionType.NoBits, section.Type); }
public void ShouldGetLoadAddress32() { var elf = ELFReader.Load <uint>(Utilities.GetBinaryStream("hello32le"), true); var sectionsToLoad = elf.GetSections <ProgBitsSection <uint> >().Where(x => x.LoadAddress != 0); Assert.AreEqual(13, sectionsToLoad.Count()); }
public void ShouldGetLoadAddress64() { var elf = ELFReader.Load <long>(Utilities.GetBinary("hello64le")); var sectionsToLoad = elf.GetSections <ProgBitsSection <long> >().Where(x => x.LoadAddress != 0); Assert.AreEqual(12, sectionsToLoad.Count()); }
public void GetNamesOfFunctionSymbols() { var elf = ELFReader.Load(Utilities.GetBinaryLocation("hello64le")); var output = new List <string>(); var functions = ((ISymbolTable)elf.GetSection(".symtab")).Entries.Where(x => x.Type == SymbolType.Function); foreach (var f in functions) { output.Add(f.Name); } var expectedOutput = @"deregister_tm_clones register_tm_clones __do_global_dtors_aux frame_dummy __libc_csu_fini puts@@GLIBC_2.2.5 _fini __libc_start_main@@GLIBC_2.2.5 __libc_csu_init _start main _init"; var expectedOutputAsLines = expectedOutput.Split(new [] { "\n", "\r\n" }, StringSplitOptions.None); CollectionAssert.AreEqual(expectedOutputAsLines, output); }
public void ShouldFindProperEntrySize64() { var elf = ELFReader.Load <long>(Utilities.GetBinary("hello64le")); var header = elf.Sections.First(x => x.Name == ".dynsym"); Assert.AreEqual(0x18, header.EntrySize); }
public void ShouldFindAllNotes64() { var elf = ELFReader.Load(Utilities.GetBinary("hello64le")); var notes = elf.GetSections <INoteSection>(); Assert.AreEqual(2, notes.Count()); }
public void ShouldReadNoteName64() { var elf = ELFReader.Load(Utilities.GetBinary("hello64le")); var noteSection = (INoteSection)elf.GetSection(".note.ABI-tag"); Assert.AreEqual("GNU", noteSection.NoteName); }
public void ShouldProperlyParseEndianess() { using var elfLittleEndian = ELFReader.Load(Utilities.GetBinaryStream("hello32le"), true); Assert.AreEqual(Endianess.LittleEndian, elfLittleEndian.Endianess); using var elfBigEndian = ELFReader.Load(Utilities.GetBinaryStream("vmlinuxOpenRisc"), true); Assert.AreEqual(Endianess.BigEndian, elfBigEndian.Endianess); }
public void ShouldReadNoteType64() { var elf = ELFReader.Load <ulong>(Utilities.GetBinary("hello64le")); var noteSection = (NoteSection <ulong>)elf.GetSection(".note.ABI-tag"); Assert.AreEqual(1, noteSection.NoteType); }
public void ShouldFindProperOffset() { var elf = ELFReader.Load <ulong>(Utilities.GetBinary("hello64le")); var section = elf.Sections.First(x => x.Name == ".strtab"); Assert.AreEqual(0x17A0, section.Offset); }
public void ShouldHandleCorruptedNamesInDynSym() { using var elf = ELFReader.Load(Utilities.GetBinaryStream("issue24.elf"), true); var dynamicSymbolSection = (SymbolTable <uint>)elf.GetSection(".dynsym"); dynamicSymbolSection.Entries.Any(x => x.Name == "<corrupt>"); }
public void ShouldGetMemoryContents() { var elf = ELFReader.Load <int>(Utilities.GetBinary("hello32le")); var segment = elf.Segments.Single(x => x.Address == 0x8049F14 && x.Type == SegmentType.Load); Assert.AreEqual(264, segment.GetMemoryContents().Length); }
// TODO: IAsyncEnumerable when ELF library supports it private IEnumerable <(string debugId, string file)> GetFiles(IEnumerable <string> files) { foreach (var file in files) { _logger.LogInformation("Processing file: {file}.", file); IELF? elf = null; string?buildIdHex; try { // TODO: find an async API if (!ELFReader.TryLoad(file, out elf)) { _logger.LogWarning("Couldn't load': {file} with ELF reader.", file); continue; } var hasBuildId = elf.TryGetSection(".note.gnu.build-id", out var buildId); if (!hasBuildId) { _logger.LogWarning("No Debug Id in {file}", file); continue; } var hasUnwindingInfo = elf.TryGetSection(".eh_frame", out _); var hasDwarfDebugInfo = elf.TryGetSection(".debug_frame", out _); if (!hasUnwindingInfo && !hasDwarfDebugInfo) { _logger.LogWarning("No unwind nor DWARF debug info in {file}", file); continue; } _logger.LogInformation("Contains unwinding info: {hasUnwindingInfo}", hasUnwindingInfo); _logger.LogInformation("Contains DWARF debug info: {hasDwarfDebugInfo}", hasDwarfDebugInfo); var builder = new StringBuilder(); var bytes = buildId.GetContents().Skip(16); foreach (var @byte in bytes) { builder.Append(@byte.ToString("x2")); } buildIdHex = builder.ToString(); } catch (Exception e) { // You would expect TryLoad doesn't throw but that's not the case _logger.LogError(e, "Failed processing file {file}.", file); continue; } finally { elf?.Dispose(); } yield return(buildIdHex, file); } }
/// <summary> /// Initializes a new instance of the <see cref="ElfCoreDump"/> class. /// </summary> /// <param name="coreDumpPath">The core dump path.</param> public ElfCoreDump(string coreDumpPath) { elf = ELFReader.Load <ulong>(coreDumpPath); if (elf.Type != FileType.Core) { throw new Exception($"Expected core dump, but got: {elf.Type}"); } switch (elf.Machine) { case Machine.Intel386: instance = new Intel386Instance(elf); break; case Machine.AMD64: instance = new AMD64Instance(elf); break; default: throw new Exception($"Unsupported machine type: {elf.Machine}"); } Path = coreDumpPath; foreach (var segment in elf.Segments) { if (segment.Type == SegmentType.Note) { DwarfMemoryReader reader = new DwarfMemoryReader(ReadSegment(segment)); int noteStructSize = Marshal.SizeOf <elf_32note>(); while (reader.Position + noteStructSize < reader.Data.Length) { // Read note elf_32note note = reader.ReadStructure <elf_32note>(); int nameEnd = reader.Position + (int)note.NameSize; // Check if note is available to be read if (nameEnd + note.n_descsz > reader.Data.Length) { break; } // Read name and content string name = reader.ReadString(); reader.Position = nameEnd; byte[] content = reader.ReadBlock(note.n_descsz); instance.ProcessNote(name, content, note.n_type); if (note.n_type == elf_note_type.File) { DwarfMemoryReader data = new DwarfMemoryReader(content); files = elf_note_file.Parse(data, Is64bit); } } } } DumpFileMemoryReader = new CoreDumpReader(coreDumpPath, elf.Segments.Where(s => s.Type == SegmentType.Load)); }
public void ShouldProperlyParseEndianess() { var elf = ELFReader.Load(Utilities.GetBinary("hello32le")); Assert.AreEqual(Endianess.LittleEndian, elf.Endianess); elf = ELFReader.Load(Utilities.GetBinary("vmlinuxOpenRisc")); Assert.AreEqual(Endianess.BigEndian, elf.Endianess); }
public TestSimulator() { e = new ELFReader(); mem = new Memory(32768); comp = new Computer(); reg = new Register[16]; resultHash = ""; hash = ""; }
private static void ProcessPath(string path) { var elfReader = new ELFReader<DefProcessor_IV, Disassembler_IV>(path); elfReader.Read(); //Console.Write(elfReader.Text); string OUTPUT = @"C:\DIS.ASM"; using (var file = new FileStream(OUTPUT, FileMode.Create, FileAccess.Write)) { using (var writer = new StreamWriter(file)) { writer.Write(elfReader.Text); } } }
public static void RunTests(StreamWriter log) { log.WriteLine("Test: Starting ArmSim unit tests"); ELFReader e = new ELFReader(); log.WriteLine("Test: Testing Hash of test1.exe"); byte[] elfArray = File.ReadAllBytes("test1.exe"); e.ReadHeader(elfArray); ramSim ram = new ramSim(32768); armsim.writeElfToRam(e, elfArray, ref ram); string resultHash = ram.getHash(); string hash = "3500a8bef72dfed358b25b61b7602cf1"; Debug.Assert(hash.ToUpper() == resultHash); ram.CLEAR(); log.WriteLine("Test: Testing Hash of test2.exe"); elfArray = File.ReadAllBytes("test2.exe"); e.ReadHeader(elfArray); armsim.writeElfToRam(e, elfArray, ref ram); resultHash = ram.getHash(); hash = "0a81d8b63d44a192e5f9f52980f2792e"; Debug.Assert(hash.ToUpper() == resultHash); ram.CLEAR(); log.WriteLine("Test: Testing Hash of test3.exe"); elfArray = File.ReadAllBytes("test3.exe"); e.ReadHeader(elfArray); armsim.writeElfToRam(e, elfArray, ref ram); resultHash = ram.getHash(); hash = "977159b662ac4e450ed62063fba27029"; Debug.Assert(hash.ToUpper() == resultHash); log.WriteLine("Test: All Hashes correct\n"); }
/* * * Unused might be good in the future public static byte[] stringToByteArray(string input){ byte[] bA = new byte[input.Length * sizeof(char)]; char[] inputArray = input.ToCharArray (); System.Buffer.BlockCopy(inputArray, 0, bA, 0, bA.Length); return bA; } */ public static int run(OptionParser options) { try { log = new StreamWriter("log.txt"); log.WriteLine("Log: Start"); if (options.getTest()) { TestRam.RunTests(log); TestArmSim.RunTests(log); } log.WriteLine("Log: MemSize " + options.getMemSize()); log.WriteLine("Log: File " + options.getFile()); log.WriteLine("Log: Little Endian " + BitConverter.IsLittleEndian); ELFReader e = new ELFReader(); byte[] elfArray = File.ReadAllBytes(options.getFile()); e.ReadHeader(elfArray); log.WriteLine("ELF: Header Position " + e.elfHeader.e_phoff); log.WriteLine("ELF: Header Size " + e.elfHeader.e_ehsize); log.WriteLine("ELF: Entry Position " + e.elfHeader.e_entry.ToString("X4")); log.WriteLine("ELF: Number of program headers " + e.elfHeader.e_phnum); for (int i = 1; i <= e.elfHeader.e_phnum; i++) { log.WriteLine("ELF: Program Header {0}, Offset = {1}, Size = {2}", i, e.elfHeader.e_phoff, e.elfHeader.e_phentsize); } //ignore the entry point for a loader //its for (executing)going into the ram after it's loaded ramSim ram = new ramSim(options.getMemSize()); writeElfToRam(e, elfArray, ref ram); log.WriteLine("Log: Ram Hash " + ram.getHash()); printArray(ram.getArray()); } catch { log.WriteLine("Log: Something went wrong"); log.Close(); return -1; } //all is good in the world,the sky is blue, the tank is clean...THE TANK IS CLEAN!! log.WriteLine("Log: Program Finished"); log.WriteLine("-----------------------------"); log.Close(); return 0; }
public static void writeElfToRam(ELFReader e, byte[] elfArray, ref ramSim ram) { log.WriteLine("RAM: Size {0}", ram.getSize()); for (int prog = 0; prog < e.elfHeader.e_phnum; prog++) { int ramAddress = e.elfphs[prog].p_vaddr; log.WriteLine("RAM: Writing to {0} ", ramAddress); int elfOffSet = (int)e.elfphs[prog].p_offset; log.WriteLine("ELF: Reading from {0}", e.elfphs[prog].p_offset); log.WriteLine("ELF: Size of Segment {0}", e.elfphs[prog].p_filesz); int ii = ramAddress; int j = elfOffSet; for (; j < elfArray.Length && ii < e.elfphs[prog].p_filesz + ramAddress; ii++, j++) { ram.WriteByte(ii, elfArray[j]); } } }
//writes the ELF file to the RAM array public void writeElfToRam(ELFReader e, byte[] elfArray) { for (int prog = 0; prog < e.elfHeader.e_phnum; prog++) { uint ramAddress = (uint)e.elfphs[prog].p_vaddr; //Logger.Instance.writeLog("RAM: Writing to {0} ", ramAddress); uint elfOffSet = (uint)e.elfphs[prog].p_offset; //Logger.Instance.writeLog("ELF: Reading from {0}", e.elfphs[prog].p_offset); //Logger.Instance.writeLog("ELF: Size of Segment {0}", e.elfphs[prog].p_filesz); uint RamAddressCounter = ramAddress; uint elfOffSetCounter = elfOffSet; for (; elfOffSetCounter < elfArray.Length && RamAddressCounter < e.elfphs[prog].p_filesz + ramAddress; RamAddressCounter++, elfOffSetCounter++) { RAM.WriteByte(RamAddressCounter, elfArray[elfOffSetCounter]); }//for }//for }//writeElfToRam
//-------End Setters------ //------- ELF code //reads the ELF /* Error codes: * 0 = OK * -1 = General * -2 = File not found * -3 = file to large */ public int readELF(string file, int memSize) { /* RAM.CLEAR(); clearRegisters(); *///opens the log file to append // StreamWriter log = new StreamWriter("log.txt", true); Logger.Instance.writeLog("ELF: Reading ELF file"); int output = -1; try { ELFReader e = new ELFReader(); byte[] elfArray = File.ReadAllBytes(file); if (elfArray.Length <= Option.Instance.memSize) { //introspection!!!Woah!!! e.ReadHeader(elfArray); reg[15].WriteWord(0,e.elfHeader.e_entry); writeElfToRam(e, elfArray); string ramOutput = RAM.getAtAddress((uint)e.elfphs[0].p_vaddr, 8); Logger.Instance.writeLog("File: Loaded"); Logger.Instance.writeLog(ramOutput); //Console.WriteLine(ramOutput); output = 0; } else //file to large { output = -3; Logger.Instance.writeLog("Err: File to Large"); } } catch (System.IO.FileNotFoundException) { output = -2; Logger.Instance.writeLog("Err: File not found"); if(Option.Instance.test) { throw new FileNotFoundException(); } else { System.Environment.Exit(1); } } catch //general exception { output = -1; Logger.Instance.writeLog("Err: Something went wrong"); } reg[13].WriteWord(0, 0x7000); return output; }