12 - ELF Coredump ----------------- This tutorial introduces the API to analyze and manipulate ELF coredump Files and scripts used in this tutorial are available on the `tutorials repository `_ ------ Introduction ~~~~~~~~~~~~ ELF core [1]_ files provide information about the CPU state and the memory state of a program when the coredump has been generated. The memory state embeds a *snapshot* of all segments mapped in the memory space of the program. The CPU state contains register values when the core dump has been generated. Coredump files use a subset of the ELF structures to store this information. **Segments** are used for the memory state of the process while ELF notes (:class:`lief.ELF.Note`) are used for process metadata (pid, signal, ...) Especially, the CPU state is stored in a note with a special type. Here is an overview of coredump layout : .. figure:: ../_static/tutorial/12/elf_notes.png :align: center For more details about coredump internal structure, one can look at the following blog post: `Anatomy of an ELF core file `_ Coredump Analysis ~~~~~~~~~~~~~~~~~ As core files are effectively ELF, we can open these files using the :func:`lief.parse` function: .. code-block:: python import lief core = lief.parse("ELF64_AArch64_core_hello.core") We can iterate over the :class:`~lief.ELF.Segment` objects to inspect the memory state of the program: .. code-block:: python segments = core.segments print("Number of segments {}".format(len(segments))) for segment in segments: print(hex(segment.virtual_address)) To resolve the relationship between libraries and segments, we can look at the special note :class:`lief.ELF.CoreFile`: .. code-block:: python nt_core_file = core.get(lief.ELF.Note.TYPE.CORE.FILE) ELF notes are represented through the main :class:`lief.ELF.Note` interface. Some notes like (:class:`lief.ELF.CoreFile`) can expose additional API by extending the original :class:`lief.ELF.Note`. .. lief-inheritance:: lief._lief.ELF.Note :top-classes: lief._lief.ELF.Note :depth: 1 :parts: 1 .. note:: All note details inherit from the base class :class:`lief.ELF.Note` (or :cpp:class:`LIEF::ELF::Note`) Especially, in C++ we must downcast according to the `classof` function: .. code-block:: cpp for (const Note& note : binary->notes()) { if (CoreFile::classof(¬e)) { const auto& nt_core_file = static_cast`_ API: - `AArch64Cpu::setConcreteRegisterValue() `_ - `AArch64Cpu::setConcreteMemoryAreaValue() `_ to map the coredump in Triton and then use its engines: Taint analysis, symbolic execution. .. rubric:: References .. [1] https://www.gabriel.urdhr.fr/2015/05/29/core-file/ .. rubric:: API * :func:`lief.parse` * :class:`lief.ELF.Note` * :class:`lief.ELF.CorePrPsInfo` * :class:`lief.ELF.CorePrStatus` * :class:`lief.ELF.CoreFile` * :class:`lief.ELF.CoreFileEntry` * :class:`lief.ELF.CoreSigInfo` * :class:`lief.ELF.CoreAuxv`