/// <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)); }
/// <summary> /// Processes the parsed note. /// </summary> /// <param name="name">The note name.</param> /// <param name="content">The note content.</param> /// <param name="type">The note type.</param> public void ProcessNote(string name, byte[] content, elf_note_type type) { if (type == elf_note_type.Prstatus) { DwarfMemoryReader data = new DwarfMemoryReader(content); elf_prstatus prstatus = data.ReadStructure <elf_prstatus>(); threads.Add(prstatus); } else if (type == elf_note_type.Prpsinfo) { // TODO: Use when needed //DwarfMemoryReader data = new DwarfMemoryReader(content); //elf_prpsinfo prpsinfo = data.ReadStructure<elf_prpsinfo>(); //Console.WriteLine($" Filename: {prpsinfo.Filename}"); //Console.WriteLine($" ArgList: {prpsinfo.ArgList}"); } }
/// <summary> /// Parses the specified data. /// </summary> /// <param name="data">The PE image data.</param> private void ParseData(byte[] data) { using (DwarfMemoryReader reader = new DwarfMemoryReader(data)) { dosHeader = reader.ReadStructure <IMAGE_DOS_HEADER>(); if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) { throw new ArgumentException($"Invalid IMAGE_DOS_HEADER magic constant. Expected: 0x{IMAGE_DOS_SIGNATURE:X}, Got: 0x{dosHeader.e_magic:X}"); } reader.Position = (int)dosHeader.e_lfanew; ntHeaders32 = reader.ReadStructure <IMAGE_NT_HEADERS32>(); if (ntHeaders32.Signature != IMAGE_NT_SIGNATURE) { throw new ArgumentException($"Invalid optional header signature. Expected: 0x{IMAGE_NT_SIGNATURE:X}, Got: 0x{ntHeaders32.Signature:X}"); } if (ntHeaders32.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || ntHeaders32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) { reader.Position = (int)dosHeader.e_lfanew; ntHeaders64 = reader.ReadStructure <IMAGE_NT_HEADERS64>(); Is64bit = true; fileHeader = ntHeaders64.FileHeader; reader.Position += ntHeaders64.FileHeader.SizeOfOptionalHeader - Marshal.SizeOf <IMAGE_OPTIONAL_HEADER64>(); CodeSegmentOffset = ntHeaders64.OptionalHeader.ImageBase; } else { Is64bit = false; fileHeader = ntHeaders32.FileHeader; reader.Position += ntHeaders32.FileHeader.SizeOfOptionalHeader - Marshal.SizeOf <IMAGE_OPTIONAL_HEADER32>(); CodeSegmentOffset = ntHeaders32.OptionalHeader.ImageBase; } // Load image section headers uint stringTablePosition = fileHeader.PointerToSymbolTable + fileHeader.NumberOfSymbols * IMAGE_SIZEOF_SYMBOL; imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections]; for (int section = 0; section < imageSectionHeaders.Length; section++) { IMAGE_SECTION_HEADER imageSectionHeader = reader.ReadStructure <IMAGE_SECTION_HEADER>(); imageSectionHeaders[section] = imageSectionHeader; string name = imageSectionHeader.Section; if (imageSectionHeader.Name[0] == '/') { uint position = stringTablePosition + uint.Parse(imageSectionHeader.Section.Substring(1)); name = reader.ReadString((int)position); } switch (name) { case ".debug_info": DebugData = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_abbrev": DebugDataDescription = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_line": DebugLine = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_frame": DebugFrame = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".debug_str": DebugDataStrings = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); break; case ".eh_frame": EhFrame = reader.ReadBlock(imageSectionHeader.SizeInImage, (int)imageSectionHeader.PointerToRawData); EhFrameAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset; break; case ".data": DataSectionAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset; break; case ".text": TextSectionAddress = imageSectionHeader.PointerToRawData + CodeSegmentOffset; break; } } // Load image symbols List <PublicSymbol> publicSymbols = new List <PublicSymbol>(); byte toSkip = 0; reader.Position = (int)fileHeader.PointerToSymbolTable; for (uint i = 0; i < fileHeader.NumberOfSymbols; i++) { int position = reader.Position; IMAGE_SYMBOL symbol = reader.ReadStructure <IMAGE_SYMBOL>(); if (toSkip == 0) { string name = symbol.SymbolName; if (string.IsNullOrEmpty(name)) { int stringPosition = (int)reader.ReadUint(position); stringPosition = (int)reader.ReadUint(position + 4); name = reader.ReadString((int)stringTablePosition + stringPosition); } if (symbol.SectionNumber > 0 && symbol.SectionNumber <= imageSectionHeaders.Length) { uint sectionAddress = imageSectionHeaders[symbol.SectionNumber - 1].VirtualAddress; sectionAddress += symbol.Value; publicSymbols.Add(new PublicSymbol(name, sectionAddress)); } toSkip = symbol.NumberOfAuxSymbols; } else { toSkip--; } } PublicSymbols = publicSymbols; } }