Example #1
0
            /// <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)
                {
                    using (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
                    //using (DwarfMemoryReader data = new DwarfMemoryReader(content))
                    //{
                    //    elf_prpsinfo prpsinfo = data.ReadStructure<elf_prpsinfo>();
                    //    Console.WriteLine($"  Filename: {prpsinfo.Filename}");
                    //    Console.WriteLine($"  ArgList: {prpsinfo.ArgList}");
                    //}
                }
            }
Example #2
0
        /// <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;
            }
        }
Example #3
0
        /// <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)
                {
                    using (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)
                            {
                                using (DwarfMemoryReader data = new DwarfMemoryReader(content))
                                {
                                    files = elf_note_file.Parse(data, Is64bit);
                                }
                            }
                            else if (note.n_type == elf_note_type.Auxv)
                            {
                                using (DwarfMemoryReader data = new DwarfMemoryReader(content))
                                {
                                    uint addressSize = elf.Class == Class.Bit32 ? 4U : 8U;

                                    while (!data.IsEnd)
                                    {
                                        AuxvEntry entry = new AuxvEntry
                                        {
                                            Type  = (AuxvEntryType)data.ReadUlong(addressSize),
                                            Value = data.ReadUlong(addressSize)
                                        };

                                        if (entry.Type == AuxvEntryType.Null)
                                        {
                                            break;
                                        }

                                        if (entry.Type == AuxvEntryType.Ignore)
                                        {
                                            continue;
                                        }

                                        auxVector.Add(entry);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            DumpFileMemoryReader = new CoreDumpReader(coreDumpPath, elf.Segments.Where(s => s.Type == SegmentType.Load));
        }