docs: migrate Sphinx RST sources to MyST Markdown

This commit is contained in:
lief-agent
2026-08-03 23:21:21 +02:00
parent 5da76859ef
commit b492a5cf34
237 changed files with 16864 additions and 16968 deletions
+1 -2
View File
@@ -1,5 +1,4 @@
Changelog
=========
see doc/sphinx/changelog.rst
see doc/sphinx/changelog.md
+60
View File
@@ -0,0 +1,60 @@
# About
The purpose of this project is to provide a cross platform library that can parse, modify and
abstract ELF, PE and MachO formats.
Main features:
> - **Parsing**: LIEF can parse ELF, PE, MachO, OAT, DEX, VDEX, ART and provides an user-friendly API to access to format internals.
> - **Modify**: LIEF enables to modify some parts of these formats
> - **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.
> - **API**: LIEF can be used in C++, Python and Rust
LIEF Extended:
> - DWARF/PDB Support
> - Objective-C Metadata
> - dyld shared cache
Checkout: <https://lief.re/doc/latest/extended/intro.html> for the details
# Getting Started
```console
$ pip install lief
```
```python
import lief
elf = lief.ELF.parse("/bin/ls")
for section in elf.sections:
print(section.name, len(section.content))
pe = lief.PE.parse("cmd.exe")
for imp in pe.imports:
print(imp.name)
fat = lief.MachO.parse("/bin/dyld")
for macho in fat:
for sym in macho.symbols:
print(sym)
```
# Documentation
- [Main documentation](https://lief.re/doc/latest/index.html)
- [API](https://lief.re/doc/latest/api/python/index.html)
# Contact
- **Mail**: contact at lief.re
- **Discord**: [LIEF](https://discord.gg/jGQtyAYChJ)
# Authors
Romain Thomas [@rh0main](https://x.com/rh0main)
______________________________________________________________________
LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.15.1/LICENSE)
-65
View File
@@ -1,65 +0,0 @@
About
=====
The purpose of this project is to provide a cross platform library that can parse, modify and
abstract ELF, PE and MachO formats.
Main features:
* **Parsing**: LIEF can parse ELF, PE, MachO, OAT, DEX, VDEX, ART and provides an user-friendly API to access to format internals.
* **Modify**: LIEF enables to modify some parts of these formats
* **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them.
* **API**: LIEF can be used in C, C++, Python and Rust
LIEF Extended:
* DWARF/PDB Support
* Objective-C Metadata
* dyld shared cache
Checkout: https://lief.re/doc/latest/extended/intro.html for the details
Getting Started
================
.. code-block:: console
$ pip install lief
.. code-block:: python
import lief
elf = lief.ELF.parse("/bin/ls")
for section in elf.sections:
print(section.name, len(section.content))
pe = lief.PE.parse("cmd.exe")
for imp in pe.imports:
print(imp.name)
fat = lief.MachO.parse("/bin/dyld")
for macho in fat:
for sym in macho.symbols:
print(sym)
Documentation
=============
* `Main documentation <https://lief.re/doc/latest/index.html>`_
* `API <https://lief.re/doc/latest/api/python/index.html>`_
Contact
=======
* **Mail**: contact at lief.re
* **Discord**: `LIEF <https://discord.gg/jGQtyAYChJ>`_
Authors
=======
Romain Thomas `@rh0main <https://x.com/rh0main>`_
----
LIEF is provided under the `Apache 2.0 license <https://github.com/lief-project/LIEF/blob/0.15.1/LICENSE>`_
+3 -3
View File
@@ -9,12 +9,12 @@ from versioning import Versioning
def dynamic_metadata(
settings: Mapping[str, Any],
project: Mapping[str, Any],
_settings: Mapping[str, Any],
_project: Mapping[str, Any],
) -> dict[str, Any]:
version = Versioning().get_version()
rich_print("{green}LIEF Version: {version}", version=version)
return {
"version": version,
"readme": (BINDING_DIR / "README.rst").as_posix(),
"readme": (BINDING_DIR / "README.md").as_posix(),
}
+1
View File
@@ -1,5 +1,6 @@
requests==2.34.2
sphinx==9.1.99
myst-parser==5.1.0
Pygments==2.20.0
breathe==4.36.0
sphinx-tabs==3.5.0
@@ -1,3 +1,4 @@
```{eval-rst}
.. |demangle| lief-api:: LIEF.demangle()
:rust:func:`lief::demangle`
@@ -1674,3 +1675,4 @@
:rust:method:`lief::runtime::android::Module::dlsym [struct]`
:py:meth:`lief.runtime.android.Module.dlsym`
:cpp:func:`LIEF::runtime::android::Module::dlsym`
```
+9
View File
@@ -3,6 +3,15 @@
max-height: 500px;
}
html[data-theme="dark"] .highlight .hll {
margin-inline-start: -0.55rem;
padding-inline-start: 0.55rem;
}
html[data-theme="light"] .docs-content dt.sig .property {
color: #007681;
}
.center {
text-align: center;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

+37
View File
@@ -0,0 +1,37 @@
{% extends "!layout.html" %}
{% block htmltitle %}
{% if seo_title %}
<title>{{ seo_title|e }}</title>
{% else %}
{{ super() }}
{% endif %}
{% endblock %}
{% block extrahead %}
{{ super() }}
{% if seo_noindex %}
<meta name="robots" content="noindex,follow">
{% endif %}
{% if canonical_url and seo_title and seo_description %}
<meta property="og:type" content="website">
<meta property="og:site_name" content="LIEF Documentation">
<meta property="og:locale" content="en_US">
<meta property="og:title" content="{{ seo_title|e }}">
<meta property="og:description" content="{{ seo_description|e }}">
<meta property="og:url" content="{{ canonical_url|e }}">
<meta property="og:image" content="{{ seo_image_url|e }}">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="412">
<meta property="og:image:height" content="415">
<meta property="og:image:alt" content="LIEF documentation logo">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{ seo_title|e }}">
<meta name="twitter:description" content="{{ seo_description|e }}">
<meta name="twitter:image" content="{{ seo_image_url|e }}">
<meta name="twitter:image:alt" content="LIEF documentation logo">
{% endif %}
{% if seo_breadcrumb_json %}
<script type="application/ld+json">{{ seo_breadcrumb_json|safe }}</script>
{% endif %}
{% endblock %}
+55
View File
@@ -0,0 +1,55 @@
# {fa}`regular fa-file-code` C++
## Parser
```{eval-rst}
.. doxygenclass:: LIEF::Parser
```
______________________________________________________________________
## Header
```{eval-rst}
.. doxygenclass:: LIEF::Header
```
______________________________________________________________________
## Binary
```{eval-rst}
.. doxygenclass:: LIEF::Binary
```
______________________________________________________________________
## Section
```{eval-rst}
.. doxygenclass:: LIEF::Section
```
______________________________________________________________________
## Symbol
```{eval-rst}
.. doxygenclass:: LIEF::Symbol
```
______________________________________________________________________
## Relocation
```{eval-rst}
.. doxygenclass:: LIEF::Relocation
```
______________________________________________________________________
## Function
```{eval-rst}
.. doxygenclass:: LIEF::Function
```
-50
View File
@@ -1,50 +0,0 @@
:fa:`regular fa-file-code` C++
--------------------------------
Parser
*******
.. doxygenclass:: LIEF::Parser
----------
Header
******
.. doxygenclass:: LIEF::Header
----------
Binary
******
.. doxygenclass:: LIEF::Binary
----------
Section
*******
.. doxygenclass:: LIEF::Section
----------
Symbol
******
.. doxygenclass:: LIEF::Symbol
----------
Relocation
**********
.. doxygenclass:: LIEF::Relocation
----------
Function
********
.. doxygenclass:: LIEF::Function
@@ -0,0 +1,61 @@
(binary-abstraction)=
# {fa}`brands fa-uncharted` Binary Abstraction
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
```
## Introduction
{ref}`ELF <format-elf>`, {ref}`PE <format-pe>`, {ref}`Mach-O <format-macho>`
binaries share similar characteristics, such as an entry point, imported/exported
functions, etc.
These shared characteristics are represented in an *abstract* layer, which is
defined by an inheritance relationship in C++/Python and by a trait in Rust.
Specifically, {sub-ref}`lief-elf-binary`, {sub-ref}`lief-pe-binary`, and {sub-ref}`lief-macho-binary`
either inherit or implement the trait: {sub-ref}`lief-abstract-binary`.
In Python/C++, one can access an *abstract* binary object by using the generic
{sub-ref}`lief-abstract-parse` function:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/abstract.py", "parse") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/abstract.cpp", "parse") }}
:::
::::
Due to Python's dynamic polymorphism, the return value of
{py:func}`lief.parse` is automatically cast into either:
{class}`lief.ELF.Binary`, {class}`lief.PE.Binary`, or {class}`lief.MachO.Binary`.
To **upcast** this object into a {class}`lief.Binary` object, one can use the
{attr}`lief.Binary.abstract` attribute, which returns a {class}`lief.Binary`
instance:
{{ literalinclude("../../../code/python/abstract.py", "upcast") }}
In C++, a {cpp:class}`LIEF::Binary` instance can be **downcast** to its underlying
type using the `classof` idiom:
{{ literalinclude("../../../code/cpp/abstract.cpp", "downcast") }}
```{eval-rst}
.. seealso::
- :cpp:func:`LIEF::ELF::Binary::classof`
- :cpp:func:`LIEF::PE::Binary::classof`
- :cpp:func:`LIEF::MachO::Binary::classof`
```
{{ cross_api }}
@@ -1,78 +0,0 @@
.. _binary-abstraction:
:fa:`brands fa-uncharted` Binary Abstraction
-----------------------------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
----
Introduction
************
:ref:`ELF <format-elf>`, :ref:`PE <format-pe>`, :ref:`Mach-O <format-macho>`
binaries share similar characteristics, such as an entry point, imported/exported
functions, etc.
These shared characteristics are represented in an *abstract* layer, which is
defined by an inheritance relationship in C++/Python and by a trait in Rust.
Specifically, |lief-elf-binary|, |lief-pe-binary|, and |lief-macho-binary|
either inherit or implement the trait: |lief-abstract-binary|.
In Python/C++, one can access an *abstract* binary object by using the generic
|lief-abstract-parse| function:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/abstract.py
:language: python
:start-after: lief-doc: parse-start
:end-before: lief-doc: parse-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/abstract.cpp
:language: cpp
:start-after: lief-doc: parse-start
:end-before: lief-doc: parse-end
:dedent:
Due to Python's dynamic polymorphism, the return value of
:py:func:`lief.parse` is automatically cast into either:
:class:`lief.ELF.Binary`, :class:`lief.PE.Binary`, or :class:`lief.MachO.Binary`.
To **upcast** this object into a :class:`lief.Binary` object, one can use the
:attr:`lief.Binary.abstract` attribute, which returns a :class:`lief.Binary`
instance:
.. literalinclude:: ../../../code/python/abstract.py
:language: python
:start-after: lief-doc: upcast-start
:end-before: lief-doc: upcast-end
:dedent:
In C++, a :cpp:class:`LIEF::Binary` instance can be **downcast** to its underlying
type using the ``classof`` idiom:
.. literalinclude:: ../../../code/cpp/abstract.cpp
:language: cpp
:start-after: lief-doc: downcast-start
:end-before: lief-doc: downcast-end
:dedent:
.. seealso::
- :cpp:func:`LIEF::ELF::Binary::classof`
- :cpp:func:`LIEF::PE::Binary::classof`
- :cpp:func:`LIEF::MachO::Binary::classof`
.. include:: ../../_cross_api.rst
@@ -0,0 +1,81 @@
# {fa}`brands fa-python` Python
## Parser
```{eval-rst}
.. autofunction:: lief.parse
```
______________________________________________________________________
## Binary
```{eval-rst}
.. lief-inheritance:: lief._lief.Binary
:top-classes: lief._lief.Binary
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.Binary
```
______________________________________________________________________
## Header
```{eval-rst}
.. autoclass:: lief.Header
```
______________________________________________________________________
## Section
```{eval-rst}
.. lief-inheritance:: lief._lief.Section
:top-classes: lief._lief.Section
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.Section
```
______________________________________________________________________
## Symbol
```{eval-rst}
.. lief-inheritance:: lief._lief.Symbol
:top-classes: lief._lief.Symbol
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.Symbol
```
______________________________________________________________________
## Relocation
```{eval-rst}
.. lief-inheritance:: lief._lief.Relocation
:top-classes: lief._lief.Relocation
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.Relocation
```
______________________________________________________________________
## Function
```{eval-rst}
.. autoclass:: lief.Function
```
@@ -1,69 +0,0 @@
:fa:`brands fa-python` Python
------------------------------
Parser
*******
.. autofunction:: lief.parse
----------
Binary
******
.. lief-inheritance:: lief._lief.Binary
:top-classes: lief._lief.Binary
:parts: 2
.. autoclass:: lief.Binary
----------
Header
******
.. autoclass:: lief.Header
----------
Section
*******
.. lief-inheritance:: lief._lief.Section
:top-classes: lief._lief.Section
:parts: 2
.. autoclass:: lief.Section
----------
Symbol
******
.. lief-inheritance:: lief._lief.Symbol
:top-classes: lief._lief.Symbol
:parts: 2
.. autoclass:: lief.Symbol
----------
Relocation
**********
.. lief-inheritance:: lief._lief.Relocation
:top-classes: lief._lief.Relocation
:parts: 2
.. autoclass:: lief.Relocation
----------
Function
********
.. autoclass:: lief.Function
@@ -0,0 +1,6 @@
# {fa}`brands fa-rust` Rust
:::{note}
Please check the module {rust:module}`lief::generic` which contains all the
abstracted traits
:::
@@ -1,7 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
.. note::
Please check the module :rust:module:`lief::generic` which contains all the
abstracted traits
@@ -1,36 +1,52 @@
.. _cpp-api-ref:
(cpp-api-ref)=
:fa:`regular fa-file-code` C++
==============================
# {fa}`regular fa-file-code` C++
.. note::
:::{note}
You can also find the Doxygen documentation [here](../../doxygen/)
:::
You can also find the Doxygen documentation `here <../../doxygen/>`_
Iterators
---------
## Iterators
```{eval-rst}
.. doxygenclass:: LIEF::ref_iterator
```
```{eval-rst}
.. doxygentypedef:: LIEF::const_ref_iterator
```
```{eval-rst}
.. doxygenclass:: LIEF::filter_iterator
```
```{eval-rst}
.. doxygentypedef:: LIEF::const_filter_iterator
```
```{eval-rst}
.. doxygenclass:: LIEF::iterator_range
```
BinaryStream
------------
## BinaryStream
```{eval-rst}
.. doxygenclass:: LIEF::BinaryStream
```
```{eval-rst}
.. doxygenclass:: LIEF::FileStream
```
```{eval-rst}
.. doxygenclass:: LIEF::SpanStream
```
```{eval-rst}
.. doxygenclass:: LIEF::VectorStream
```
```{eval-rst}
.. doxygenclass:: LIEF::MemoryStream
```
+86
View File
@@ -0,0 +1,86 @@
(err_handling)=
# {fa}`solid fa-triangle-exclamation` Error Handling
## Introduction
LIEF manages errors using:
1. Exceptions (deprecated and removed since LIEF 0.13.0)
2. [std::expected (tl::expected)](https://github.com/TartanLlama/expected)
It turns out that using C++ exceptions (and RTTI) was not the best design choice,
as LIEF, as a library, can be used in a `-fno-exceptions` context.
Consequently, we moved to a mechanism based on the `ResultOrError`
idiom. This idiom is similar to those found in LLVM with
[llvm::ErrorOr](https://llvm.org/doxygen/classllvm_1_1ErrorOr.html) and in Rust
with [std::result](https://doc.rust-lang.org/std/result/).
LIEF uses a {title-reference}`std::expected`-like interface to handle errors. Since this
interface is only available in C++23, we rely on
[TartanLlama/expected](https://github.com/TartanLlama/expected), which
provides this interface for C++11/C++17.
Functions using this idiom return a {cpp:type}`LIEF::result`, which wraps either
the successful result or an error.
The user can process this result as follows:
{{ literalinclude("../../../code/cpp/error_handling.cpp", "result-handling") }}
In the case of Python, we leverage the *dynamic* features of the language to
return either the expected value or an error if the function fails.
For instance, in previous versions of {func}`lief.PE.get_type`, the
implementation raised an exception to inform the user:
{{ literalinclude("../../../code/python/error_handling.py", "get-type-exception") }}
With the new implementation that relies on the `ResultOrError` idiom, the
function returns the {class}`lief.PE.PE_TYPE` value if everything is correct,
and returns a {class}`lief.lief_errors` in case of a processing error.
The user can handle this new interface by using the `isinstance()` function or by comparing the value with
a {class}`lief.lief_errors` attribute:
{{ literalinclude("../../../code/python/error_handling.py", "get-type-error") }}
## {fa}`solid fa-code` API
### C++
```{eval-rst}
.. doxygenclass:: LIEF::result
```
```{eval-rst}
.. doxygenfunction:: LIEF::as_lief_err
```
```{eval-rst}
.. doxygenenum:: lief_errors
```
```{eval-rst}
.. doxygenclass:: LIEF::ok_error_t
```
```{eval-rst}
.. doxygenfunction:: LIEF::ok
```
```{eval-rst}
.. doxygenstruct:: LIEF::ok_t
```
### Python
```{eval-rst}
.. autoclass:: lief.lief_errors
```
```{eval-rst}
.. autoclass:: lief.ok_t
```
```{eval-rst}
.. autoclass:: lief.ok_error_t
```
-86
View File
@@ -1,86 +0,0 @@
.. _err_handling:
:fa:`solid fa-triangle-exclamation` Error Handling
--------------------------------------------------
Introduction
~~~~~~~~~~~~~
LIEF manages errors using:
1. Exceptions (deprecated and removed since LIEF 0.13.0)
2. `std::expected (tl::expected) <https://github.com/TartanLlama/expected>`_
It turns out that using C++ exceptions (and RTTI) was not the best design choice,
as LIEF, as a library, can be used in a ``-fno-exceptions`` context.
Consequently, we moved to a mechanism based on the ``ResultOrError``
idiom. This idiom is similar to those found in LLVM with
`llvm::ErrorOr <https://llvm.org/doxygen/classllvm_1_1ErrorOr.html>`_ and in Rust
with `std::result <https://doc.rust-lang.org/std/result/>`_.
LIEF uses a `std::expected`-like interface to handle errors. Since this
interface is only available in C++23, we rely on
`TartanLlama/expected <https://github.com/TartanLlama/expected>`_, which
provides this interface for C++11/C++17.
Functions using this idiom return a :cpp:type:`LIEF::result`, which wraps either
the successful result or an error.
The user can process this result as follows:
.. literalinclude:: ../../../code/cpp/error_handling.cpp
:language: cpp
:start-after: lief-doc: result-handling-start
:end-before: lief-doc: result-handling-end
:dedent:
In the case of Python, we leverage the *dynamic* features of the language to
return either the expected value or an error if the function fails.
For instance, in previous versions of :func:`lief.PE.get_type`, the
implementation raised an exception to inform the user:
.. literalinclude:: ../../../code/python/error_handling.py
:language: python
:start-after: lief-doc: get-type-exception-start
:end-before: lief-doc: get-type-exception-end
:dedent:
With the new implementation that relies on the ``ResultOrError`` idiom, the
function returns the :class:`lief.PE.PE_TYPE` value if everything is correct,
and returns a :class:`lief.lief_errors` in case of a processing error.
The user can handle this new interface by using the ``isinstance()`` function or by comparing the value with
a :class:`lief.lief_errors` attribute:
.. literalinclude:: ../../../code/python/error_handling.py
:language: python
:start-after: lief-doc: get-type-error-start
:end-before: lief-doc: get-type-error-end
:dedent:
:fa:`solid fa-code` API
~~~~~~~~~~~~~~~~~~~~~~~
C++
++++++++
.. doxygenclass:: LIEF::result
.. doxygenfunction:: LIEF::as_lief_err
.. doxygenenum:: lief_errors
.. doxygenclass:: LIEF::ok_error_t
.. doxygenfunction:: LIEF::ok
.. doxygenstruct:: LIEF::ok_t
Python
++++++++
.. autoclass:: lief.lief_errors
.. autoclass:: lief.ok_t
.. autoclass:: lief.ok_error_t
@@ -1,94 +1,108 @@
:fa:`regular fa-rectangle-list` Logging
---------------------------------------
# {fa}`regular fa-rectangle-list` Logging
This section details the API for interacting with LIEF's logging engine.
LIEF uses `spdlog <https://github.com/gabime/spdlog>`_ for its logging
LIEF uses [spdlog](https://github.com/gabime/spdlog) for its logging
mechanism, and this API provides an abstraction over that implementation.
## {fa}`solid fa-code` API
:fa:`solid fa-code` API
~~~~~~~~~~~~~~~~~~~~~~~
C++
++++++++
### C++
```{eval-rst}
.. doxygenfunction:: LIEF::logging::disable
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::enable
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::set_level
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::set_path
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::log(Level level, const std::string &fmt, const Args&... args)
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::log(Level level, const std::string &fmt, const std::vector<std::string> &args)
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::log(Level level, const std::string &msg)
```
```{eval-rst}
.. doxygenfunction:: LIEF::logging::reset
```
```{eval-rst}
.. doxygenenum:: LIEF::logging::Level
```
```{eval-rst}
.. doxygenclass:: LIEF::logging::Scoped
```
Example
~~~~~~~
## Example
.. literalinclude:: ../../../code/cpp/logging.cpp
:language: cpp
:start-after: lief-doc: example-start
:end-before: lief-doc: example-end
:dedent:
{{ literalinclude("../../../code/cpp/logging.cpp", "example") }}
Python
++++++
### Python
```{eval-rst}
.. autofunction:: lief.logging.set_level
```
```{eval-rst}
.. autofunction:: lief.logging.enable
```
```{eval-rst}
.. autofunction:: lief.logging.disable
```
```{eval-rst}
.. autofunction:: lief.logging.set_path
```
```{eval-rst}
.. autofunction:: lief.logging.log
```
```{eval-rst}
.. autofunction:: lief.logging.level_scope
```
```{eval-rst}
.. autoclass:: lief.logging.Scoped
:members:
```
```{eval-rst}
.. autoclass:: lief.logging.Level
```
Example
~~~~~~~
## Example
.. literalinclude:: ../../../code/python/logging.py
:language: python
:start-after: lief-doc: example-start
:end-before: lief-doc: example-end
:dedent:
{{ literalinclude("../../../code/python/logging.py", "example") }}
### Rust
Rust
++++
- {rust:func}`lief::logging::disable`
- {rust:func}`lief::logging::enable`
- {rust:func}`lief::logging::set_level`
- {rust:func}`lief::logging::set_path`
- {rust:func}`lief::logging::log`
- {rust:func}`lief::logging::reset`
- {rust:enum}`lief::logging::Level`
- {rust:struct}`lief::logging::Scoped`
- :rust:func:`lief::logging::disable`
- :rust:func:`lief::logging::enable`
- :rust:func:`lief::logging::set_level`
- :rust:func:`lief::logging::set_path`
- :rust:func:`lief::logging::log`
- :rust:func:`lief::logging::reset`
- :rust:enum:`lief::logging::Level`
- :rust:struct:`lief::logging::Scoped`
## Example
Example
~~~~~~~
.. literalinclude:: ../../../code/rust/src/logging.rs
:language: rust
:start-after: lief-doc: example-start
:end-before: lief-doc: example-end
:dedent:
{{ literalinclude("../../../code/rust/src/logging.rs", "example") }}
+120
View File
@@ -0,0 +1,120 @@
(lief_rust_bindings)=
# {fa}`brands fa-rust` Rust
:::{note}
The API is documented here {sub-ref}`lief-rust-doc` and the nightly doc is
here: {sub-ref}`lief-rust-doc-nightly`.
:::
```toml
[package]
name = "my-awesome-project"
version = "0.0.1"
edition = "2024"
[dependencies]
lief = { git = "https://github.com/lief-project/LIEF", branch = "main" }
```
:::{warning}
LIEF rust bindings are not on `docs.rs` because of network restrictions:
<https://github.com/rust-lang/docs.rs/issues/2563>
:::
## Precompiled FFI Bindings
LIEF's Rust bindings are split into two parts:
1. `lief`: the high-level, idiomatic Rust API.
2. `lief-ffi`: the low-level FFI API based on [cxx](https://cxx.rs/).
Two additional crates support the build process:
- `lief-build`: build-script helper used by `lief-ffi` to fetch the
pre-compiled artifacts and emit the `cargo` link directives.
- `lief-ffigen`: standalone CLI that generates the C++ side of the
`cxx` bridge from the `#[cxx::bridge]` modules declared in
`lief-ffi`.
Building `lief-ffi` requires generating the C++ bridge files with
`lief-ffigen` and then compiling them alongside `libLIEF`. Both steps
can take several minutes.
To save time, LIEF provides pre-compiled versions of these artifacts, which
are downloaded from GitHub (for releases) or an S3 bucket (for nightly
builds).
(lief-rust-precompiled)=
### `LIEF_RUST_PRECOMPILED`
If you need to avoid downloading these pre-compiled files, set
`LIEF_RUST_PRECOMPILED` to point to the directory that contains these files:
```text
/home/romain/out
└── lib
    ├── libLIEF.a
    └── liblief-sys.a
1 directory, 2 files
LIEF_RUST_PRECOMPILED=/home/romain/out cargo build [...]
```
This variable can also be used when building in **offline** mode
(e.g., `cargo --offline`).
As of now, the following targets are supported with pre-compilation:
| Target | Description |
| ----------------------------- | ----------------------------------------------------- |
| `x86_64-unknown-linux-gnu` | Regular Linux x86-64 (Ubuntu 21.10+, Debian 12+, ...) |
| `i686-unknown-linux-gnu` | Regular Linux i686 (Ubuntu 19.10, Debian 10, ...) |
| `x86_64-unknown-linux-musl` | Musl target that allows full static build |
| `i686-unknown-linux-musl` | Linux i686 with Musl |
| `aarch64-unknown-linux-gnu` | Linux aarch64 (Debian 12+) |
| `aarch64-unknown-linux-musl` | Linux aarch64 with Musl |
| `aarch64-linux-android` | Android aarch64 (API 30+) |
| `x86_64-linux-android` | Android x86_64 (API 30+) |
| `x86_64-apple-darwin` | macOS 11+ x86-64 |
| `aarch64-apple-darwin` | macOS 11+ arm64 (Apple Silicon) |
| `aarch64-apple-ios` | iOS 12+ |
| `x86_64-pc-windows-msvc[MT]` | Regular Windows x86-64 (static UCRT runtime) |
| `x86_64-pc-windows-msvc[MD]` | Regular Windows x86-64 (dynamic UCRT runtime `.dll`) |
| `aarch64-pc-windows-msvc[MT]` | Regular Windows arm64 (static UCRT runtime) |
| `aarch64-pc-windows-msvc[MD]` | Regular Windows arm64 (dynamic UCRT runtime `.dll`) |
### Precompilation
The assets of the pre-compiled output are:
1. LIEF static library: `LIEF.{a,lib}`
2. `liefsys.{a,lib}`: bridge between C++ and Rust
The LIEF static library must be compiled as described in the
{ref}`compilation_ref` section using the CMake option: `-DLIEF_RUST_API=ON`.
`liefsys.{a,lib}` is built in two steps. First, generate the C++ bridge
files with `lief-ffigen`:
```console
$ cargo build [--profile release] -p lief-ffigen
$ target/{release,debug}/lief-ffigen \
--output-dir cxx-bridge/ \
--source-dir lief-ffi/
```
Then compile them as a regular CMake-based library:
```console
$ cmake -GNinja \
-S api/rust/cmake-ffi/ \
-B cxx-bridge-build/ \
-DLIEF_DIR=$INSTALL_DIR/lib/cmake/LIEF \
-DLIEF_RUST_FFI_SRC=cxx-bridge/ \
-DCMAKE_INSTALL_PREFIX=cxx-bridge-out/
$ ninja -C cxx-bridge-build/
```
-142
View File
@@ -1,142 +0,0 @@
.. _lief_rust_bindings:
:fa:`brands fa-rust` Rust
======================================
.. note::
The API is documented here |lief-rust-doc| and the nightly doc is
here: |lief-rust-doc-nightly|.
.. code-block:: toml
[package]
name = "my-awesome-project"
version = "0.0.1"
edition = "2024"
[dependencies]
lief = { git = "https://github.com/lief-project/LIEF", branch = "main" }
.. warning::
LIEF rust bindings are not on ``docs.rs`` because of network restrictions:
https://github.com/rust-lang/docs.rs/issues/2563
Precompiled FFI Bindings
~~~~~~~~~~~~~~~~~~~~~~~~
LIEF's Rust bindings are split into two parts:
1. ``lief``: the high-level, idiomatic Rust API.
2. ``lief-ffi``: the low-level FFI API based on `cxx <https://cxx.rs/>`_.
Two additional crates support the build process:
* ``lief-build``: build-script helper used by ``lief-ffi`` to fetch the
pre-compiled artifacts and emit the ``cargo`` link directives.
* ``lief-ffigen``: standalone CLI that generates the C++ side of the
``cxx`` bridge from the ``#[cxx::bridge]`` modules declared in
``lief-ffi``.
Building ``lief-ffi`` requires generating the C++ bridge files with
``lief-ffigen`` and then compiling them alongside ``libLIEF``. Both steps
can take several minutes.
To save time, LIEF provides pre-compiled versions of these artifacts, which
are downloaded from GitHub (for releases) or an S3 bucket (for nightly
builds).
.. _lief-rust-precompiled:
``LIEF_RUST_PRECOMPILED``
--------------------------
If you need to avoid downloading these pre-compiled files, set
``LIEF_RUST_PRECOMPILED`` to point to the directory that contains these files:
.. code-block:: text
/home/romain/out
└── lib
    ├── libLIEF.a
    └── liblief-sys.a
1 directory, 2 files
LIEF_RUST_PRECOMPILED=/home/romain/out cargo build [...]
This variable can also be used when building in **offline** mode
(e.g., ``cargo --offline``).
As of now, the following targets are supported with pre-compilation:
+---------------------------------+--------------------------------------------------------+
| Target | Description |
+=================================+========================================================+
| ``x86_64-unknown-linux-gnu`` | Regular Linux x86-64 (Ubuntu 21.10+, Debian 12+, ...) |
+---------------------------------+--------------------------------------------------------+
| ``i686-unknown-linux-gnu`` | Regular Linux i686 (Ubuntu 19.10, Debian 10, ...) |
+---------------------------------+--------------------------------------------------------+
| ``x86_64-unknown-linux-musl`` | Musl target that allows full static build |
+---------------------------------+--------------------------------------------------------+
| ``i686-unknown-linux-musl`` | Linux i686 with Musl |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-unknown-linux-gnu`` | Linux aarch64 (Debian 12+) |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-unknown-linux-musl`` | Linux aarch64 with Musl |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-linux-android`` | Android aarch64 (API 30+) |
+---------------------------------+--------------------------------------------------------+
| ``x86_64-linux-android`` | Android x86_64 (API 30+) |
+---------------------------------+--------------------------------------------------------+
| ``x86_64-apple-darwin`` | macOS 11+ x86-64 |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-apple-darwin`` | macOS 11+ arm64 (Apple Silicon) |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-apple-ios`` | iOS 12+ |
+---------------------------------+--------------------------------------------------------+
| ``x86_64-pc-windows-msvc[MT]`` | Regular Windows x86-64 (static UCRT runtime) |
+---------------------------------+--------------------------------------------------------+
| ``x86_64-pc-windows-msvc[MD]`` | Regular Windows x86-64 (dynamic UCRT runtime ``.dll``) |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-pc-windows-msvc[MT]`` | Regular Windows arm64 (static UCRT runtime) |
+---------------------------------+--------------------------------------------------------+
| ``aarch64-pc-windows-msvc[MD]`` | Regular Windows arm64 (dynamic UCRT runtime ``.dll``) |
+---------------------------------+--------------------------------------------------------+
Precompilation
--------------
The assets of the pre-compiled output are:
1. LIEF static library: ``LIEF.{a,lib}``
2. ``liefsys.{a,lib}``: bridge between C++ and Rust
The LIEF static library must be compiled as described in the
:ref:`compilation_ref` section using the CMake option: ``-DLIEF_RUST_API=ON``.
``liefsys.{a,lib}`` is built in two steps. First, generate the C++ bridge
files with ``lief-ffigen``:
.. code-block:: console
$ cargo build [--profile release] -p lief-ffigen
$ target/{release,debug}/lief-ffigen \
--output-dir cxx-bridge/ \
--source-dir lief-ffi/
Then compile them as a regular CMake-based library:
.. code-block:: console
$ cmake -GNinja \
-S api/rust/cmake-ffi/ \
-B cxx-bridge-build/ \
-DLIEF_DIR=$INSTALL_DIR/lib/cmake/LIEF \
-DLIEF_RUST_FFI_SRC=cxx-bridge/ \
-DCMAKE_INSTALL_PREFIX=cxx-bridge-out/
$ ninja -C cxx-bridge-build/
+159
View File
@@ -0,0 +1,159 @@
# {fa}`solid fa-hand-holding-hand` Utilities
## Demangling
LIEF exposes a demangling API for the following formats:
::::{tabs}
:::{tab} {fa}`brands fa-windows` MSVC
**Input**
{{ literalinclude("../../../code/python/utilities.py", "demangle-msvc") }}
**Result**
```{code-block} text
void __cdecl h(int)
```
:::
:::{tab} {fa}`brands fa-rust` Rust
**Input**
{{ literalinclude("../../../code/python/utilities.py", "demangle-rust") }}
**Result**
```{code-block} text
foo::example_function
```
:::
:::{tab} {fa}`regular fa-file-code` Itanium C++
**Input**
{{ literalinclude("../../../code/python/utilities.py", "demangle-itanium") }}
**Result**
```{code-block} text
typeinfo name for lld::SpecificAlloc<lld::coff::TpiSource>
```
:::
:::{tab} {fa}`brands fa-swift` Swift/Obj-C
**Input**
{{ literalinclude("../../../code/python/utilities.py", "demangle-swift") }}
**Result**
```{code-block} text
type metadata for Foundation.Data._Representation
```
:::
::::
```{eval-rst}
.. doxygenfunction:: LIEF::demangle
```
```{eval-rst}
.. autofunction:: lief.demangle
```
{fa}`brands fa-rust` {rust:func}`lief::demangle`
## Extended Version
To check if the current build is an {ref}`extended <extended-intro>` version,
you can use:
```{eval-rst}
.. doxygenfunction:: LIEF::is_extended
```
```{eval-rst}
.. autodata:: lief._lief.__extended__
```
{rust:func}`lief::is_extended`
In C++, you can also check if `LIEF_EXTENDED` is defined:
```cpp
#include <LIEF/config.hpp>
#if defined(LIEF_EXTENDED)
// Extended version
#else
// Regular version
#endif
```
To get details about the version of the current extended build:
```{eval-rst}
.. doxygenfunction:: LIEF::extended_version_info
```
## Android Platform
```{eval-rst}
.. autofunction:: lief.Android.code_name
```
```{eval-rst}
.. autofunction:: lief.Android.version_string
```
```{eval-rst}
.. autoclass:: lief.Android.ANDROID_VERSIONS
:members:
:inherited-members:
:undoc-members:
```
```{eval-rst}
.. doxygenfunction:: LIEF::Android::code_name
```
```{eval-rst}
.. doxygenfunction:: LIEF::Android::version_string
```
```{eval-rst}
.. doxygenenum:: LIEF::Android::ANDROID_VERSIONS
```
## Python Leaks
```{eval-rst}
.. autofunction:: lief.disable_leak_warning
```
## Helpers
The `lief.dump()` utility can be used to pretty-print a buffer.
For example:
{{ literalinclude("../../../code/python/utilities.py", "dump") }}
```{eval-rst}
.. autofunction:: lief.dump
```
```{eval-rst}
.. doxygenfunction:: LIEF::dump(const std::vector<uint8_t> &data, const std::string &title = "", const std::string &prefix = "", size_t limit = 0)
```
```{eval-rst}
.. doxygenfunction:: LIEF::dump(const uint8_t *buffer, size_t size, const std::string &title = "", const std::string &prefix = "", size_t limit = 0)
```
```{eval-rst}
.. doxygenfunction:: LIEF::dump(span<const uint8_t> data, const std::string &title = "", const std::string &prefix = "", size_t limit = 0)
```
- {fa}`brands fa-rust` {rust:func}`lief::dump`
- {fa}`brands fa-rust` {rust:func}`lief::dump_with_limit`
{{ cross_api }}
-157
View File
@@ -1,157 +0,0 @@
:fa:`solid fa-hand-holding-hand` Utilities
--------------------------------------------
Demangling
~~~~~~~~~~~
LIEF exposes a demangling API for the following formats:
.. tabs::
.. tab:: :fa:`brands fa-windows` MSVC
**Input**
.. literalinclude:: ../../../code/python/utilities.py
:language: python
:start-after: lief-doc: demangle-msvc-start
:end-before: lief-doc: demangle-msvc-end
:dedent:
**Result**
.. code-block:: text
void __cdecl h(int)
.. tab:: :fa:`brands fa-rust` Rust
**Input**
.. literalinclude:: ../../../code/python/utilities.py
:language: python
:start-after: lief-doc: demangle-rust-start
:end-before: lief-doc: demangle-rust-end
:dedent:
**Result**
.. code-block:: text
foo::example_function
.. tab:: :fa:`regular fa-file-code` Itanium C++
**Input**
.. literalinclude:: ../../../code/python/utilities.py
:language: python
:start-after: lief-doc: demangle-itanium-start
:end-before: lief-doc: demangle-itanium-end
:dedent:
**Result**
.. code-block:: text
typeinfo name for lld::SpecificAlloc<lld::coff::TpiSource>
.. tab:: :fa:`brands fa-swift` Swift/Obj-C
**Input**
.. literalinclude:: ../../../code/python/utilities.py
:language: python
:start-after: lief-doc: demangle-swift-start
:end-before: lief-doc: demangle-swift-end
:dedent:
**Result**
.. code-block:: text
type metadata for Foundation.Data._Representation
.. doxygenfunction:: LIEF::demangle
.. autofunction:: lief.demangle
:fa:`brands fa-rust` :rust:func:`lief::demangle`
Extended Version
~~~~~~~~~~~~~~~~
To check if the current build is an :ref:`extended <extended-intro>` version,
you can use:
.. doxygenfunction:: LIEF::is_extended
.. autodata:: lief._lief.__extended__
:rust:func:`lief::is_extended`
In C++, you can also check if ``LIEF_EXTENDED`` is defined:
.. code-block:: cpp
#include <LIEF/config.hpp>
#if defined(LIEF_EXTENDED)
// Extended version
#else
// Regular version
#endif
To get details about the version of the current extended build:
.. doxygenfunction:: LIEF::extended_version_info
Android Platform
~~~~~~~~~~~~~~~~~
.. autofunction:: lief.Android.code_name
.. autofunction:: lief.Android.version_string
.. autoclass:: lief.Android.ANDROID_VERSIONS
:members:
:inherited-members:
:undoc-members:
.. doxygenfunction:: LIEF::Android::code_name
.. doxygenfunction:: LIEF::Android::version_string
.. doxygenenum:: LIEF::Android::ANDROID_VERSIONS
Python Leaks
~~~~~~~~~~~~~
.. autofunction:: lief.disable_leak_warning
Helpers
~~~~~~~
The ``lief.dump()`` utility can be used to pretty-print a buffer.
For example:
.. literalinclude:: ../../../code/python/utilities.py
:language: python
:start-after: lief-doc: dump-start
:end-before: lief-doc: dump-end
:dedent:
.. autofunction:: lief.dump
.. doxygenfunction:: LIEF::dump(const std::vector<uint8_t> &data, const std::string &title = "", const std::string &prefix = "", size_t limit = 0)
.. doxygenfunction:: LIEF::dump(const uint8_t *buffer, size_t size, const std::string &title = "", const std::string &prefix = "", size_t limit = 0)
.. doxygenfunction:: LIEF::dump(span<const uint8_t> data, const std::string &title = "", const std::string &prefix = "", size_t limit = 0)
- :fa:`brands fa-rust` :rust:func:`lief::dump`
- :fa:`brands fa-rust` :rust:func:`lief::dump_with_limit`
.. include:: ../../_cross_api.rst
@@ -1,18 +1,19 @@
.. _changelog-ref:
(changelog-ref)=
:fa:`solid fa-code-compare` Changelog
=====================================
# {fa}`solid fa-code-compare` Changelog
2.0.0 - Not Released Yet
------------------------
## 2.0.0 - Not Released Yet
.. admonition:: Breaking Changes
:class: warning
:::{admonition} Breaking Changes
:class: warning
- **C++17 Migration**: LIEF public headers, public API, and STL have been bumped from C++11 to **C++17**.
- **C API Removal**: The legacy C API has been completely removed.
- **Logging Level Renaming**: |lief-logging-level| and its enumerators are now
written in ``CamelCase``
- **C++17 Migration**: LIEF public headers, public API, and STL have been bumped from C++11 to **C++17**.
- **C API Removal**: The legacy C API has been completely removed.
- **Logging Level Renaming**: {sub-ref}`lief-logging-level` and its enumerators are now
written in `CamelCase`
:::
```{eval-rst}
:Assembly:
@@ -54,14 +55,17 @@
section = coff.get_section(".debug_rnglists")
section.name # '/18'
section.coff_string.string # '.debug_rnglists'
```
1.0.0 - July 12th, 2026
-----------------------
## 1.0.0 - July 12th, 2026
.. admonition:: Runtime
:class: tip
:::{admonition} Runtime
:class: tip
LIEF now provides runtime features as described here: :ref:`Runtime <runtime-intro>`
LIEF now provides runtime features as described here: {ref}`Runtime <runtime-intro>`
:::
```{eval-rst}
:BinaryNinja:
@@ -253,10 +257,11 @@
with ThreadPoolExecutor() as pool:
pool.map(strip, ["/bin/ls", "/bin/cat", "/bin/echo"])
```
## 0.17.6 - March 18th, 2026
0.17.6 - March 18th, 2026
-------------------------
```{eval-rst}
:ELF:
@@ -267,9 +272,11 @@
:PE:
* Fix IAT parsing issue by :github_user:`itamarga` in PR :pr:`1314`)
```
0.17.5 - March 8th, 2026
------------------------
## 0.17.5 - March 8th, 2026
```{eval-rst}
:ELF:
@@ -280,9 +287,11 @@
:MachO:
* Fix ``DyldInfo::show_bindings`` integer overflow (:issue:`1313`)
```
0.17.4 - February 21st, 2026
----------------------------
## 0.17.4 - February 21st, 2026
```{eval-rst}
:PE:
@@ -314,17 +323,21 @@
* Bumped various Python backend build dependencies in
``api/python/build-requirements.txt`` to support Python ``3.14`` when
compiling from sources (:issue:`1304`).
```
0.17.3 - January 24th, 2026
---------------------------
## 0.17.3 - January 24th, 2026
```{eval-rst}
:PE:
* Fixed bug with resources (:issue:`1281`).
* Fixed VA/RVA confusion in the PE builder (:issue:`1284`).
```
0.17.2 - January 3rd, 2026
---------------------------
## 0.17.2 - January 3rd, 2026
```{eval-rst}
:Mach-O:
@@ -352,9 +365,11 @@
* Fixed major performance issue when parsing certain Mach-O files
(by :github_user:`trevor-e`, fixing :issue:`1262`).
```
0.17.1 - October 25th, 2025
---------------------------
## 0.17.1 - October 25th, 2025
```{eval-rst}
:ELF:
@@ -366,25 +381,29 @@
* Fixed incorrect paging computations that occurred when only a subset
of formats was enabled.
* Fixed include issue with the COFF format.
```
0.17.0 - September 14th, 2025
-----------------------------
## 0.17.0 - September 14th, 2025
.. admonition:: BinaryNinja & Ghidra Plugins
:class: tip
:::{admonition} BinaryNinja & Ghidra Plugins
:class: tip
LIEF-based plugins for Binary Ninja and Ghidra have been bootstrapped here:
LIEF-based plugins for Binary Ninja and Ghidra have been bootstrapped here:
- :ref:`Ghidra plugin <plugins-ghidra>`
- :ref:`BinaryNinja plugin <plugins-binaryninja>`
- {ref}`Ghidra plugin <plugins-ghidra>`
- {ref}`BinaryNinja plugin <plugins-binaryninja>`
:::
.. admonition:: LIEF Tools
:class: tip
:::{admonition} LIEF Tools
:class: tip
I initiated a ``Tools`` section which aims at providing utilities based on LIEF (mostly
CLI):
I initiated a `Tools` section which aims at providing utilities based on LIEF (mostly
CLI):
- :ref:`lief-patchelf <tools-lief-patchelf>`
- {ref}`lief-patchelf <tools-lief-patchelf>`
:::
```{eval-rst}
:Assembler:
@@ -619,9 +638,11 @@
:Utilities:
* Add |lief-dump|
```
0.16.7 - October 5th, 2025
--------------------------
## 0.16.7 - October 5th, 2025
```{eval-rst}
:Python:
@@ -639,10 +660,11 @@
:Other:
* :pr:`1220`
```
## 0.16.6 - May 29th, 2025
0.16.6 - May 29th, 2025
-----------------------
```{eval-rst}
:Compilation:
@@ -663,9 +685,11 @@
* :issue:`1217`
* :pr:`1216`
```
0.16.5 - April 19th, 2025
-------------------------
## 0.16.5 - April 19th, 2025
```{eval-rst}
:ELF:
@@ -688,9 +712,11 @@
* Add Python, Rust, SDK packages for Windows ARM64 (``aarch64-pc-windows-msvc``)
* Add Python, Rust, SDK packages for Linux Musl ARM64 (``aarch64-unknown-linux-musl``)
* Add Python, Rust, SDK packages for Linux Musl i686 (``i686-unknown-linux-musl``)
```
0.16.4 - February 23rd, 2025
----------------------------
## 0.16.4 - February 23rd, 2025
```{eval-rst}
:Python:
@@ -708,9 +734,11 @@
:MachO:
* Fix truncated ``nlist_t.n_type`` when rewriting a Mach-O binary
```
0.16.3 - February 1st, 2025
---------------------------
## 0.16.3 - February 1st, 2025
```{eval-rst}
:ELF:
@@ -725,17 +753,21 @@
:Misc:
* Add support for spdlog compiled with ``SPDLOG_WCHAR_FILENAMES`` (:issue:`1147`)
```
0.16.2 - January 1st, 2025
----------------------------
## 0.16.2 - January 1st, 2025
```{eval-rst}
:Compilation:
* Fix broken ``aarch64`` Python wheel which is related to a toolchain issue
(:issue:`1146`)
```
0.16.1 - December 26th, 2024
----------------------------
## 0.16.1 - December 26th, 2024
```{eval-rst}
:MachO:
@@ -751,10 +783,11 @@
:Compilation:
* Fix missing ``LIEF_API`` visibility (:commit:`e01f92a0`, :pr:`1140`)
```
## 0.16.0 - December 10th, 2024
0.16.0 - December 10th, 2024
----------------------------
```{eval-rst}
:Abstraction:
@@ -966,16 +999,20 @@
* Add cross-api menu directive. For instance, this *link*: |lief-dwarf-debug-info|
toggles a menu to access the documentation of DWARF's debug info for Rust,
Python & C++.
```
0.15.1 - July 23th, 2024
------------------------
## 0.15.1 - July 23th, 2024
```{eval-rst}
:MachO:
* Fix missing commit for ``.hwx`` support
```
0.15.0 - July 21th, 2024
------------------------
## 0.15.0 - July 21th, 2024
```{eval-rst}
:Extended:
@@ -1122,10 +1159,11 @@
* Add icons
* Include inheritance diagram for Python API (e.g. :class:`lief.ELF.Note`)
```
## 0.14.1 - February 11th, 2024
0.14.1 - February 11th, 2024
----------------------------
```{eval-rst}
:ELF:
* Fix regression in Symbol Version Definition processing (:issue:`1014`)
@@ -1139,9 +1177,11 @@
:Python:
* Fix regression in iterator's performances
```
0.14.0 - January 20, 2024
-------------------------
## 0.14.0 - January 20, 2024
```{eval-rst}
:ELF:
* Add support for the GNU note properies (:issue:`975`).
@@ -1284,9 +1324,11 @@
* CI are now more efficient.
* The Python documentation for properties now contains the type of the
property.
```
0.13.2 - June 17, 2023
----------------------
## 0.13.2 - June 17, 2023
```{eval-rst}
:PE:
@@ -1295,9 +1337,11 @@
:ELF:
Fix missing undef (:issue:`929`)
```
0.13.1 - May 28, 2023
----------------------
## 0.13.1 - May 28, 2023
```{eval-rst}
:PE:
@@ -1309,11 +1353,11 @@
* Fix missing include (:issue:`918`)
* Fix C99 comments (:issue:`916`)
* Fix AArch64 docker image (:issue:`904`)
```
## 0.13.0 - April 9, 2023
0.13.0 - April 9, 2023
----------------------
```{eval-rst}
:ELF:
@@ -1436,24 +1480,22 @@
* Move to nlohmann/json 3.11.2
* Move to MbedTLS 3.2.1
* Move to utfcpp 3.2.1
```
0.12.3 - November 1, 2022
-------------------------
## 0.12.3 - November 1, 2022
This release contains several security fixes:
* [CVE-2022-38497] Fix ELF core parsing issue (:issue:`766` found by :github_user:`CCWANG19`)
* [CVE-2022-38306] Fix a heap overflow found by :github_user:`CCWANG19` (:issue:`763`)
* Fix a memory issue (found by :github_user:`bladchan` via :issue:`806`)
* [CVE-2022-40923] Fix parsing issue (:issue:`784` found by :github_user:`bladchan`)
* [CVE-2022-40922] Fix parsing issue (:issue:`781` found by :github_user:`bladchan`)
* [CVE-2022-38307] Fix a segfault when the Mach-O binary does not have segments (found by :github_user:`CCWANG19` via :issue:`764`)
> - [CVE-2022-38497] Fix ELF core parsing issue ({issue}`766` found by {github_user}`CCWANG19`)
> - [CVE-2022-38306] Fix a heap overflow found by {github_user}`CCWANG19` ({issue}`763`)
> - Fix a memory issue (found by {github_user}`bladchan` via {issue}`806`)
> - [CVE-2022-40923] Fix parsing issue ({issue}`784` found by {github_user}`bladchan`)
> - [CVE-2022-40922] Fix parsing issue ({issue}`781` found by {github_user}`bladchan`)
> - [CVE-2022-38307] Fix a segfault when the Mach-O binary does not have segments (found by {github_user}`CCWANG19` via {issue}`764`)
## 0.12.1 - April 08, 2022
0.12.1 - April 08, 2022
------------------------
```{eval-rst}
:ELF:
* Fix section inclusion calculations (:pr:`692`)
@@ -1468,9 +1510,11 @@ This release contains several security fixes:
- https://lief.s3-website.fr-par.scw.cloud/latest/sdk
* Fix `GLIBCXX_USE_CXX11_ABI=1` ABI issue (see: :issue:`683`)
```
0.12.0 - March 25, 2022
-----------------------
## 0.12.0 - March 25, 2022
```{eval-rst}
:ELF:
* :github_user:`ahaensler` added the support to insert and assign a :class:`lief.ELF.SymbolVersionAuxRequirement` (see: :pr:`670`)
@@ -1653,17 +1697,17 @@ This release contains several security fixes:
- :ref:`Error Handling section<err_handling>`
- `List of the functions that changed <https://gist.github.com/romainthomas/37da45b043c5f8b8db6be2767611f625>`_
```
## 0.11.X - Patch Releases
0.11.X - Patch Releases
-----------------------
(release-0115)=
.. _release-0115:
### 0.11.5 - May 22, 2021
0.11.5 - May 22, 2021
*********************
- Remove usage of `not` in public headers ({commit}`b8e825b464418de385146bb3f89ef6126f4de5d4`)
* Remove usage of ``not`` in public headers (:commit:`b8e825b464418de385146bb3f89ef6126f4de5d4`)
```{eval-rst}
:ELF:
* :github_user:`pdreiter` fixed the issue :issue:`418`
@@ -1673,48 +1717,57 @@ This release contains several security fixes:
:MachO:
* Fix error on property :attr:`lief.MachO.BuildVersion.sdk` (see :issue:`533`)
```
.. _release-0114:
(release-0114)=
0.11.4 - March 09, 2021
***********************
### 0.11.4 - March 09, 2021
```{eval-rst}
:PE:
* Fix missing bound check when computing the authentihash
```
.. _release-0113:
(release-0113)=
0.11.3 - March 03, 2021
***********************
### 0.11.3 - March 03, 2021
```{eval-rst}
:PE:
* Add sanity check on the signature's length that could lead to a ``std::bad_alloc`` exception
```
.. _release-0112:
(release-0112)=
### 0.11.2 - February 24, 2021
0.11.2 - February 24, 2021
**************************
```{eval-rst}
:PE:
* Fix regression in the behavior of the PE section's name. One can now access the full
section's name (with trailing bytes) through :attr:`lief.PE.Section.fullname` (see: :issue:`551`)
```
.. _release-0111:
(release-0111)=
0.11.1 - February 22, 2021
**************************
### 0.11.1 - February 22, 2021
```{eval-rst}
:PE:
* :meth:`lief.PE.x509.is_trusted_by` and :meth:`lief.PE.x509.verify` now return
a better :attr:`lief.PE.x509.VERIFICATION_FLAGS` instead of just :attr:`lief.PE.x509.VERIFICATION_FLAGS.BADCERT_NOT_TRUSTED`
(see: :issue:`532`)
* Fix errors in the computation of the Authentihash
```
.. _release-0110:
(release-0110)=
0.11.0 - January 19, 2021
-------------------------
## 0.11.0 - January 19, 2021
```{eval-rst}
:ELF:
* :github_user:`mkomet` updated enums related to Android (see: :commit:`9dd641d380a5defd0a71a9f42dde2fe9c9cb1dbd`)
@@ -1797,18 +1850,16 @@ This release contains several security fixes:
.. note::
The log functions now output on ``stderr`` instead of ``stdout``
```
## 0.10.1 - November 29, 2019
- Fix regression in parsing Python `bytes`
- Add Python API to demangle strings: `lief.demangle`
0.10.1 - November 29, 2019
--------------------------
## 0.10.0 - November 24, 2019
- Fix regression in parsing Python ``bytes``
- Add Python API to demangle strings: ``lief.demangle``
0.10.0 - November 24, 2019
--------------------------
```{eval-rst}
:ELF:
@@ -1873,23 +1924,23 @@ This release contains several security fixes:
* Update Pybind11 dependency to ``v2.4.3``
* Enhance Python install
* Thanks to :github_user:`lkollar`, Linux CI now produces **manylinux1-compliant wheels**
```
Many thanks to the contributors: :github_user:`recvfrom`, :github_user:`pbrunet`,
:github_user:`mackncheesiest`, :github_user:`wisk`, :github_user:`nezetic`,
:github_user:`lkollar`, :github_user:`jbremer`, :github_user:`DaLynX`, :github_user:`1orenz0`,
:github_user:`breadchris`, :github_user:`0xbf00`, :github_user:`unratito`, :github_user:`strazzere`,
:github_user:`aguinetqb`, :github_user:`mingwandroid`, :github_user:`serge-sans-paille-qb`, :github_user:`yrp604`,
:github_user:`majin42`, :github_user:`KOLANICH`
Many thanks to the contributors: {github_user}`recvfrom`, {github_user}`pbrunet`,
{github_user}`mackncheesiest`, {github_user}`wisk`, {github_user}`nezetic`,
{github_user}`lkollar`, {github_user}`jbremer`, {github_user}`DaLynX`, {github_user}`1orenz0`,
{github_user}`breadchris`, {github_user}`0xbf00`, {github_user}`unratito`, {github_user}`strazzere`,
{github_user}`aguinetqb`, {github_user}`mingwandroid`, {github_user}`serge-sans-paille-qb`, {github_user}`yrp604`,
{github_user}`majin42`, {github_user}`KOLANICH`
0.9.0 - June 11, 2018
---------------------
## 0.9.0 - June 11, 2018
LIEF 0.9 comes with new formats related to Android: OAT, DEX, VDEX and ART. It also fixes bugs and thanks to
:github_user:`yd0b0N`, ELF parser now supports big and little endian binaries. We also completed the JSON serialization of LIEF objects.
{github_user}`yd0b0N`, ELF parser now supports big and little endian binaries. We also completed the JSON serialization of LIEF objects.
### Features
Features
********
```{eval-rst}
:MachO:
@@ -1914,55 +1965,46 @@ Features
* Enable to add unlimited number of dynamic entries: :commit:`a40da3e3b4b985b18a6e6026d594f524b7bae963`
* Add support for PPC relocations: :commit:`08b514191f661eeabbdf8ecacd1d7dd35a67ca54`
* Endianness support: :commit:`e794ac1502ee7636755bd441923368f88525a7d0`
```
API
***
### API
* :func:`lief.breakp` and :func:`lief.shell`
* :func:`lief.parse` now support ``io`` streams as input
* Parser now returns a ``std::unique_ptr`` instead of a raw pointer: :commit:`cd1cc457cf3d63cfc5faa945657887200cedb8b3`
> - {func}`lief.breakp` and {func}`lief.shell`
> - {func}`lief.parse` now support `io` streams as input
> - Parser now returns a `std::unique_ptr` instead of a raw pointer: {commit}`cd1cc457cf3d63cfc5faa945657887200cedb8b3`
Misc
****
### Misc
* Use `frozen <https://github.com/serge-sans-paille/frozen>`_ for some internal ``std::map`` (If C++14 is supported by the compiler)
- Use [frozen](https://github.com/serge-sans-paille/frozen) for some internal `std::map` (If C++14 is supported by the compiler)
Acknowledgements
****************
### Acknowledgements
* :github_user:`yd0b0N` for :pr:`162` and :pr:`166` (Endianness support and PPC relocations)
* :github_user:`0xbf00` for :pr:`128` (``LC_RPATH`` command)
* :github_user:`illera88` for :pr:`118`
- {github_user}`yd0b0N` for {pr}`162` and {pr}`166` (Endianness support and PPC relocations)
- {github_user}`0xbf00` for {pr}`128` (`LC_RPATH` command)
- {github_user}`illera88` for {pr}`118`
## 0.8.3
0.8.3
-----
- [Mach-O] Fix typo on comparison operator - {commit}`abbc264833894973f601f700b3abcc109904f722`
* [Mach-O] Fix typo on comparison operator - :commit:`abbc264833894973f601f700b3abcc109904f722`
## 0.8.2
0.8.2
-----
- [ELF] Increase the upper limit of relocation number - {commit}`077bc329bdcc249cb8ed0b8bcb9630e1c9eede94`
* [ELF] Increase the upper limit of relocation number - :commit:`077bc329bdcc249cb8ed0b8bcb9630e1c9eede94`
## 0.8.1 - October 18, 2017
0.8.1 - October 18, 2017
------------------------
- Fix an alignment issue in the ELF builder. See {commit}`8db199c04e9e6bcdbda165ab5c42d88218a0beb6`
- Add assertion on the setuptools version: {commit}`62e5825e27bb637c2f42f4d05690a100213beb03`
* Fix an alignment issue in the ELF builder. See :commit:`8db199c04e9e6bcdbda165ab5c42d88218a0beb6`
* Add assertion on the setuptools version: :commit:`62e5825e27bb637c2f42f4d05690a100213beb03`
## 0.8.0 - October 16, 2017
LIEF 0.8.0 mainly improves the MachO parser and the ELF builder. It comes with [Dockerfiles](https://github.com/lief-project/Dockerlief) for [CentOS](https://github.com/lief-project/Dockerlief/blob/v0.1.0/dockerlief/dockerfiles/centos.docker) and [Android](https://github.com/lief-project/Dockerlief/blob/v0.1.0/dockerlief/dockerfiles/android.docker).
0.8.0 - October 16, 2017
------------------------
[LibFuzzer](https://llvm.org/docs/LibFuzzer.html) has also been integrated in the project to enhance the parsers
LIEF 0.8.0 mainly improves the MachO parser and the ELF builder. It comes with `Dockerfiles <https://github.com/lief-project/Dockerlief>`_ for `CentOS <https://github.com/lief-project/Dockerlief/blob/v0.1.0/dockerlief/dockerfiles/centos.docker>`_ and `Android <https://github.com/lief-project/Dockerlief/blob/v0.1.0/dockerlief/dockerfiles/android.docker>`_.
`LibFuzzer <https://llvm.org/docs/LibFuzzer.html>`_ has also been integrated in the project to enhance the parsers
Features
********
### Features
```{eval-rst}
:Abstract Layer:
@@ -2157,14 +2199,15 @@ Features
* ``LC_SOURCE_VERSION``, ``LC_VERSION_MIN_MACOSX`` and ``LC_VERSION_MIN_IPHONEOS`` are
parsed into :class:`~lief.MachO.SourceVersion` and :class:`~lief.MachO.VersionMin` (:commit:`c359778194db874669884aaccb52a4b05546bc07`, :commit:`0b4bb7d56520cd0ea08bbcb9530e5e0c96ac14ae`, :commit:`5b993117ed391db18ba775cabefa5f3981b2f1cc`, :issue:`45`)
* ``LC_THREAD`` and ``LC_UNIXTHREAD`` are now parsed into :class:`~lief.MachO.ThreadCommand` - :commit:`23257830b291c40a3aed92360040f2b0b11ffa72`
```
### Fixes
Fixes
*****
Fix enums conflicts({issue}`32`) - {commit}`66b4cd4550ecf6cf3adb4900e6ad7ac33f1f7f32`
Fix enums conflicts(:issue:`32`) - :commit:`66b4cd4550ecf6cf3adb4900e6ad7ac33f1f7f32`
Fix most of the memory leaks: {commit}`88dafa8db6e752393f69d73f68d295e91963b8da`, {commit}`d9b1436730b5d33a753e7dfa4301697a0c676066`, {commit}`554fa153af943b97a16fc4a52ab8459a3d0a9bc7`, {commit}`3602643f5d02a1c78c4de609cc47f193f3a8840f`
Fix most of the memory leaks: :commit:`88dafa8db6e752393f69d73f68d295e91963b8da`, :commit:`d9b1436730b5d33a753e7dfa4301697a0c676066`, :commit:`554fa153af943b97a16fc4a52ab8459a3d0a9bc7`, :commit:`3602643f5d02a1c78c4de609cc47f193f3a8840f`
```{eval-rst}
:ELF:
@@ -2180,14 +2223,13 @@ Fix most of the memory leaks: :commit:`88dafa8db6e752393f69d73f68d295e91963b8da`
* Fix :issue:`87`, :issue:`92`
* Fix memory leaks and *some* performance issues: :issue:`94`
```
### API
In the C++ API `get_XXX()` getters have been renamed into `XXX()` (e.g. `get_header()` becomes `header()`) - {commit}`a4c69f7868da1de5d09aa26e977dedb720e36cbd`, {commit}`e805669865b130057413f456958a471d8f0ac0b1`
API
***
In the C++ API ``get_XXX()`` getters have been renamed into ``XXX()`` (e.g. ``get_header()`` becomes ``header()``) - :commit:`a4c69f7868da1de5d09aa26e977dedb720e36cbd`, :commit:`e805669865b130057413f456958a471d8f0ac0b1`
```{eval-rst}
:Abstract:
@@ -2255,38 +2297,36 @@ In the C++ API ``get_XXX()`` getters have been renamed into ``XXX()`` (e.g. ``ge
Logger.set_level(lief.LEVEL.INFO)
See: :class:`lief.Logger`
```
Build system
************
### Build system
* Add `FindLIEF.cmake <https://github.com/lief-project/LIEF/blob/e8ac976c994f6612e8dcca994032403c2d6f580f/scripts/FindLIEF.cmake>`_ - :commit:`6dd8b10325e832a7520bf5ae3a588b9e022d0345`
* Add ASAN, TSAN, USAN, LSAN - :commit:`7f6aeb0d0d74eae886f4b312e12e8f71e1d5da6a`
* Add LibFuzzer - :commit:`7a0dc28ea29a30209e944ebcde27f7c0ab234651`
- Add [FindLIEF.cmake](https://github.com/lief-project/LIEF/blob/e8ac976c994f6612e8dcca994032403c2d6f580f/scripts/FindLIEF.cmake) - {commit}`6dd8b10325e832a7520bf5ae3a588b9e022d0345`
- Add ASAN, TSAN, USAN, LSAN - {commit}`7f6aeb0d0d74eae886f4b312e12e8f71e1d5da6a`
- Add LibFuzzer - {commit}`7a0dc28ea29a30209e944ebcde27f7c0ab234651`
### Documentation
Documentation
*************
```{eval-rst}
:References:
* recomposer, bearparser, IAT_patcher, PEframe, Manalyze, MachOView, elf-dissector
```
### Acknowledgements
Acknowledgements
****************
- {github_user}`alvarofe` for {pr}`47`
- {github_user}`aguinet` for {pr}`55`, {pr}`61`, {pr}`65`, {pr}`77`
- {github_user}`jevinskie` for {pr}`75`
- {github_user}`liumuqing` for {pr}`80`
- {github_user}`Manouchehri` for {pr}`106`
* :github_user:`alvarofe` for :pr:`47`
* :github_user:`aguinet` for :pr:`55`, :pr:`61`, :pr:`65`, :pr:`77`
* :github_user:`jevinskie` for :pr:`75`
* :github_user:`liumuqing` for :pr:`80`
* :github_user:`Manouchehri` for :pr:`106`
## 0.7.0 - July 3, 2017
### Features
0.7.0 - July 3, 2017
---------------------
Features
********
```{eval-rst}
:Abstract Layer:
@@ -2311,9 +2351,11 @@ Features
* Add a *resources manager* to provide an enhanced API over the resources - :commit:`8473c8e126f2a8f14728ad3f8ebb59c45ac55d2d`
* Serialize PE objects into JSON - :commit:`673f5a36f0d339ad9390427292fa6e725b8fd907`, :issue:`18`
* Parse Rich Header - :commit:`0893bd9b08f2248ae8f656ccd81b1be12e8ae57e`, :issue:`15`
```
Bug Fixes
*********
### Bug Fixes
```{eval-rst}
:ELF:
@@ -2330,9 +2372,11 @@ Bug Fixes
:MachO:
* Bug fix when a binary hasn't a ``LC_MAIN`` command - :commit:`957501fe76596e0396c66d08540884876cea049c`
```
API
***
### API
```{eval-rst}
:Abstract Layer:
@@ -2432,10 +2476,11 @@ API
* :attr:`lief.MachO.Binary.has_dylinker`
* :attr:`lief.MachO.Binary.dylinker`
* :class:`lief.MachO.DylinkerCommand`
```
### Documentation
Documentation
*************
```{eval-rst}
:References:
@@ -2448,56 +2493,58 @@ Documentation
:Integration:
* `XCode <installation.html#xcode-integration>`_, `CMake <installation.html#cmake-integration>`_
```
Acknowledgements
****************
### Acknowledgements
* `ek0 <https://github.com/ek0>`_: :pr:`24`
* `ACSC-CyberLab <https://github.com/ACSC-CyberLab>`_: :pr:`33`, :pr:`34`, :pr:`37`, :pr:`39`
* Hyrum Anderson who pointed bugs in the PE parser
* My collegues for the feedbacks and suggestions (Adrien, SebK, Pierrick)
- [ek0](https://github.com/ek0): {pr}`24`
- [ACSC-CyberLab](https://github.com/ACSC-CyberLab): {pr}`33`, {pr}`34`, {pr}`37`, {pr}`39`
- Hyrum Anderson who pointed bugs in the PE parser
- My collegues for the feedbacks and suggestions (Adrien, SebK, Pierrick)
0.6.1 - April 6, 2017
----------------------
## 0.6.1 - April 6, 2017
Bug Fixes
*********
### Bug Fixes
```{eval-rst}
:ELF:
* Don't rely on :attr:`lief.ELF.Section.entry_size` to count symbols - :commit:`004c6769bec37e303bbe7aaceb49f4b05c8eec84`
```
API
***
### API
```{eval-rst}
:PE:
* :attr:`lief.PE.TLS.has_section`
* :attr:`lief.PE.TLS.has_data_directory`
```
### Documentation
Documentation
*************
```{eval-rst}
:Integration:
* `Visual Studio <installation.html#visual-studio-integration>`_
```
Acknowledgements
****************
### Acknowledgements
* `Philippe <https://github.com/doegox>`_ for the proofreading.
- [Philippe](https://github.com/doegox) for the proofreading.
0.6.0 - March 30, 2017
----------------------
## 0.6.0 - March 30, 2017
First public release
```{eval-rst}
.. toctree::
:hidden:
changelog/pe-0-17-0
```
.. include:: ./_cross_api.rst
{{ cross_api }}
+315
View File
@@ -0,0 +1,315 @@
(pe_0170_changelog)=
# PE Changelog for LIEF 0.17.0
Compared to LIEF v0.16.x, version 0.17.0 includes a significant refactoring
of the PE parser and builder. These changes were necessary to align
LIEF's PE functionality with its ELF and Mach-O counterparts.
If your codebase uses LIEF to process PE binaries, you may encounter issues when
upgrading to LIEF 0.17.0. This page provides a comprehensive overview of the
various changes, but it cannot cover every detail. If you encounter an API issue
that is not described here, you can:
1. Join our Discord server and ask your questions: {sub-ref}`lief-discord`
2. Review the git diff of the tests. Most of these changes are covered by tests,
so you should be able to find a relevant example.
3. Email me at: `me[at]romainthomas.fr`
## PE Modifications
To explore the new modification features, you can check the following pages:
```{eval-rst}
.. toctree::
:maxdepth: 1
../formats/pe/modifications/imports
../formats/pe/modifications/resources
../formats/pe/modifications/tls
../formats/pe/modifications/debug
../formats/pe/modifications/exports
```
## COFF String & COFF Symbol
As described in issue {issue}`1043`, if a section name exceeds
8 bytes, the linker may allocate a longer name in the
COFF string pool while setting the section's name with the offset in the COFF
string pool.
You can access this COFF string using {sub-ref}`lief-pe-section-coff_string`, while
the string representing the offset (e.g., `/230`) remains in the
section's name.
Additionally, optional COFF symbols, along with any auxiliary symbols, are now
processed correctly by LIEF:
```python
import lief
pe = lief.PE.parse("libLIEF.dll")
section = pe.sections[10]
print(section.name) # --> '/19'
print(section.coff_string) # --> '.debug_info'
for symbol in pe.symbols:
print(symbol.name)
for aux in symbol.auxiliary_symbols:
print(aux)
```
Although this example is written in Python, the API is also available in C++
and Rust.
## Load Configuration
The `IMAGE_LOAD_CONFIG_DIRECTORY` structures, represented in LIEF by
{sub-ref}`lief-pe-loadconfig`, regularly evolve with new Windows releases.
New Windows versions may introduce attributes for additional
functionality, such as Control Flow Guard. To manage these changes,
{sub-ref}`lief-pe-loadconfig` previously used a form of inheritance. For each new
attribute, a new class, such as `LoadConfigurationV12`, would inherit from
`LoadConfigurationV11`. This approach, though systematic, resulted in numerous
modifications -- especially in Rust -- raising questions about the decision to use
inheritance.
Starting with LIEF v0.17.0, {sub-ref}`lief-pe-loadconfig` has adopted a **flat**
representation. In this new model, version-dependent attributes are represented
with an `option<>`-like container.
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
```{code-block} python
import lief
pe = lief.PE.parse("demo.exe")
offset: Optional[int] = pe.load_configuration.hotpatch_table_offset
```
:::
:::{tab} {fa}`regular fa-file-code` C++
```{code-block} cpp
auto pe = LIEF::PE::Parser::parse("demo.exe");
if (const LoadConfiguration* lconf = pe->load_configuration()) {
LIEF::optional<uint32_t> offset = lconf->hotpatch_table_offset();
}
```
:::
:::{tab} {fa}`brands fa-rust` Rust
```{code-block} rust
if let Some(lief::Binary::PE(pe)) = lief::Binary::parse("demo.exe") {
if let Some(lconf) = pe.load_configuration() {
let offset: Option<u32> = lconf.hotpatch_table_offset();
}
}
```
:::
::::
Additionally, {sub-ref}`lief-pe-loadconfig` now provides an API that allows access to
the internal data associated with this structure:
- {sub-ref}`lief-pe-chpe_metadata`
- {sub-ref}`lief-pe-dynamic-relocation`
- {sub-ref}`lief-pe-enclave-configuration`
- {sub-ref}`lief-pe-volatile-metadata`
Some of these structures are important to correctly support ARM64EC/ARM64X
PE binaries (#teasing).
## Debug Information
LIEF version 0.17.0 supports more types of debug entries and provides a
user-friendly API:
- {sub-ref}`lief-pe-vcfeature`
- {sub-ref}`lief-pe-fpo`
- {sub-ref}`lief-pe-exdllcharacteristics`
- {sub-ref}`lief-pe-pdbchecksum`
As described in the {ref}`Debug Modification <pe_debug_modification>`
section, you can modify debug entries to perform various actions:
```python
pe = lief.PE.parse("some.dll")
# Changing the PDB file path to a URL
pe.codeview_pdb.filename = "https://lief.re/"
pe.write("out.dll")
```
## Resources
Some interfaces exposed by the {sub-ref}`lief-pe-resource-manager` have been redesigned
to make them more consistent with their underlying representation in the PE
format.
For example, `lief.PE.LangCodeItem` has been renamed and refactored into
{sub-ref}`lief-pe-resourcestringtable`.
Resource-related enums have been re-scoped to avoid definition conflicts
between Windows headers and LIEF:
| `lief.PE.EXTENDED_WINDOW_STYLES` | {class}`lief.PE.ResourceDialog.WINDOW_EXTENDED_STYLES` |
| -------------------------------------- | -------------------------------------------------------------------- |
| `lief.PE.WINDOW_STYLES` | {class}`lief.PE.ResourceDialog.WINDOW_STYLES` |
| `lief.PE.DIALOG_BOX_STYLES` | {class}`lief.PE.ResourceDialog.DIALOG_STYLES` |
| `lief.PE.FIXED_VERSION_OS` | {class}`lief.PE.ResourceVersion.fixed_file_info_t.VERSION_OS` |
| `lief.PE.FIXED_VERSION_FILE_FLAGS` | {class}`lief.PE.ResourceVersion.fixed_file_info_t.FILE_FLAGS` |
| `lief.PE.FIXED_VERSION_FILE_SUB_TYPES` | {class}`lief.PE.ResourceVersion.fixed_file_info_t.FILE_TYPE_DETAILS` |
| `lief.PE.ACCELERATOR_FLAGS` | {class}`lief.PE.ResourceAccelerator.FLAGS` |
| `lief.PE.ACCELERATOR_VK_CODES` | {class}`lief.PE.ACCELERATOR_CODES` |
## Exception Info
For x86-64 and ARM64 PE binaries, stack unwinding information is referenced by
the data directory: `IMAGE_DIRECTORY_ENTRY_EXCEPTION`. Even if your code is
compiled without exception support, this information may still be generated by the linker.
The entries of this data directory are represented by the
{sub-ref}`lief-pe-exceptioninfo` structure, which is specialized for x64 and
ARM64 functions. Regardless of the underlying architecture, each entry in this
table exposes a function RVA.
From a reverse engineering perspective, these RVAs offer a valuable set of
function start addresses that can be used to begin disassembling the binary.
Given a {sub-ref}`lief-pe-binary` instance, one can iterate over these
{sub-ref}`lief-pe-exceptioninfo` entries using {sub-ref}`lief-pe-binary-exceptions`:
```python
pe = lief.PE.parse("Windows.Media.Protection.PlayReady.dll", lief.PE.ParserConfgi.all)
print(pe.exceptions[10])
```
```text
RuntimeFunctionX64 {
RVA: [0x0c9350, 0x0c9382] (50 bytes)
Unwind info RVA: 0x68eb5c
unwind_info_t {
Version: 1
Flags: 0
Size of prologue: 20
Nb opcodes: 8 (6)
Opcodes: [
0x14 SAVE_NONVOL reg=RDI, offset=0x000078
0x14 SAVE_NONVOL reg=RBX, offset=0x000070
0x14 ALLOC_SMALL size=64
0x10 PUSH_NONVOL reg=R15
0x0e PUSH_NONVOL reg=R14
0x0c PUSH_NONVOL reg=R12
];
}
}
```
```python
pe = lief.PE.parse("win11_arm64x_Windows.Media.Protection.PlayReady.dll", lief.PE.ParserConfgi.all)
print(pe.exceptions[10])
```
```text
Runtime Unpacked AArch64 Function {
Range(RVA): 0x00822bb8 - 0x00822c08
Unwind location (RVA): 0x00d63838
Length=80 Vers=0 X=0 E=0, CodeWords=8
Epilogs=1
Prolog unwind:
0x0000 e1...... mov fp, sp
0x0001 81...... stp x29, x30, [sp, #-16]!
0x0002 e6...... save next
0x0003 e6...... save next
0x0004 e6...... save next
0x0005 e6...... save next
0x0006 e76689.. stp q6, q7, [sp, #-160]!
0x0009 fc...... pacibsp
0x000a e4...... end
Epilog #1 unwind: (Offset=10, Index=11, Reserved=0)
0x0000 81...... ldp x29, x30, [sp], #16
0x0001 e74e88.. ldp q14, q15, [sp, #128]
0x0004 e74c86.. ldp q12, q13, [sp, #96]
0x0007 e74a84.. ldp q10, q11, [sp, #64]
0x000a e74882.. ldp q8, q9, [sp, #32]
0x000d e76689.. ldp q6, q7, [sp], #160
0x0010 fc...... autibsp
0x0011 e3...... nop
0x0012 e3...... nop
0x0013 e4...... end
}
```
:::{admonition} ARM64 - `SAVE_ANY_REG`
:class: tip
Thank you to [Eli Friedman](https://github.com/efriedma-quic) and [Martin Storsjö](https://github.com/mstorsjo)
for their work on reverse engineering this undocumented unwind opcode.
:::
LIEF provides a detailed API for the structures involved in PE
exceptions and stack unwinding.
:::{admonition} Performance Considerations
:class: warning
In-depth analysis of exception metadata can introduce significant overhead.
Therefore, {sub-ref}`lief-pe-parser-config-parse_exceptions` must be
**explicitly** enabled.
:::
## ARM64EC / ARM64X
With the recent release of Snapdragon X, ARM64-based Windows computers are
becoming increasingly popular. This shift introduces some changes to
the PE format. One notable change is the introduction of ARM64X binaries, which
can be compared to the Mach-O FAT concept, where a single binary contains multiple
architectures.
In the case of ARM64X, a single PE file encapsulates ARM64 and ARM64EC architectures.
LIEF v0.17.0 exposes the following helpers to determine whether the binary is
ARM64X or ARM64EC: {sub-ref}`lief-pe-binary-is_arm64ec`, {sub-ref}`lief-pe-binary-is_arm64x`.
For an ARM64X binary, you can use {sub-ref}`lief-pe-binary-nested_pe_binary` to access the
embedded ARM64EC **representation** of the binary.
:::{admonition} Performance Considerations
:class: warning
Parsing a nested ARM64EC binary can introduce additional overhead compared to
the 0.16.x version.
Therefore, {sub-ref}`lief-pe-parser-config-parse_arm64x_binary` must be
**explicitly** enabled.
:::
## Other Changes
The workaround involving `undef.h` has been removed. This file was used to
`#undef` certain Windows defines that conflicted with LIEF enum definitions.
You can now safely include Windows headers alongside LIEF headers. If you
encounter any conflicts, please report the issue.
The *builder* engine has been refactored to resolve numerous errors and bugs
associated with PE modifications. It now uses a more conservative approach.
For more details, please refer to the {ref}`PE <format-pe>` page.
The *"PE from Scratch"* feature has been removed, as it had significant bugs
that often resulted in corrupted binaries. This feature will be reintroduced in
a future release. If you rely on this feature, please reach out.
```{eval-rst}
:List of changes:
* Fixed missing original forwarded function name (:issue:`1166`)
* |lief-pe-datadirectory| now exposes |lief-pe-datadirectory-content| to
access the raw bytes wrapped by the data directory
* PE's resource tree can now be parsed in a standalone way using
|lief-pe-resource-node-parse|.
.. code-block:: python
resource_tree = bytes("....")
original_rva = 0x20000
tree: lief.PE.ResourceNode = lief.PE.ResourceNode.parse(resource_tree, original_rva)
```
{{ cross_api }}
-327
View File
@@ -1,327 +0,0 @@
.. _pe_0170_changelog:
PE Changelog for LIEF 0.17.0
============================
Compared to LIEF v0.16.x, version 0.17.0 includes a significant refactoring
of the PE parser and builder. These changes were necessary to align
LIEF's PE functionality with its ELF and Mach-O counterparts.
If your codebase uses LIEF to process PE binaries, you may encounter issues when
upgrading to LIEF 0.17.0. This page provides a comprehensive overview of the
various changes, but it cannot cover every detail. If you encounter an API issue
that is not described here, you can:
1. Join our Discord server and ask your questions: |lief-discord|
2. Review the git diff of the tests. Most of these changes are covered by tests,
so you should be able to find a relevant example.
3. Email me at: ``me[at]romainthomas.fr``
PE Modifications
----------------
To explore the new modification features, you can check the following pages:
.. toctree::
:maxdepth: 1
../formats/pe/modifications/imports
../formats/pe/modifications/resources
../formats/pe/modifications/tls
../formats/pe/modifications/debug
../formats/pe/modifications/exports
COFF String & COFF Symbol
-------------------------
As described in issue :issue:`1043`, if a section name exceeds
8 bytes, the linker may allocate a longer name in the
COFF string pool while setting the section's name with the offset in the COFF
string pool.
You can access this COFF string using |lief-pe-section-coff_string|, while
the string representing the offset (e.g., ``/230``) remains in the
section's name.
Additionally, optional COFF symbols, along with any auxiliary symbols, are now
processed correctly by LIEF:
.. code-block:: python
import lief
pe = lief.PE.parse("libLIEF.dll")
section = pe.sections[10]
print(section.name) # --> '/19'
print(section.coff_string) # --> '.debug_info'
for symbol in pe.symbols:
print(symbol.name)
for aux in symbol.auxiliary_symbols:
print(aux)
Although this example is written in Python, the API is also available in C++
and Rust.
Load Configuration
------------------
The ``IMAGE_LOAD_CONFIG_DIRECTORY`` structures, represented in LIEF by
|lief-pe-loadconfig|, regularly evolve with new Windows releases.
New Windows versions may introduce attributes for additional
functionality, such as Control Flow Guard. To manage these changes,
|lief-pe-loadconfig| previously used a form of inheritance. For each new
attribute, a new class, such as ``LoadConfigurationV12``, would inherit from
``LoadConfigurationV11``. This approach, though systematic, resulted in numerous
modifications -- especially in Rust -- raising questions about the decision to use
inheritance.
Starting with LIEF v0.17.0, |lief-pe-loadconfig| has adopted a **flat**
representation. In this new model, version-dependent attributes are represented
with an ``option<>``-like container.
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. code-block:: python
import lief
pe = lief.PE.parse("demo.exe")
offset: Optional[int] = pe.load_configuration.hotpatch_table_offset
.. tab:: :fa:`regular fa-file-code` C++
.. code-block:: cpp
auto pe = LIEF::PE::Parser::parse("demo.exe");
if (const LoadConfiguration* lconf = pe->load_configuration()) {
LIEF::optional<uint32_t> offset = lconf->hotpatch_table_offset();
}
.. tab:: :fa:`brands fa-rust` Rust
.. code-block:: rust
if let Some(lief::Binary::PE(pe)) = lief::Binary::parse("demo.exe") {
if let Some(lconf) = pe.load_configuration() {
let offset: Option<u32> = lconf.hotpatch_table_offset();
}
}
Additionally, |lief-pe-loadconfig| now provides an API that allows access to
the internal data associated with this structure:
- |lief-pe-chpe_metadata|
- |lief-pe-dynamic-relocation|
- |lief-pe-enclave-configuration|
- |lief-pe-volatile-metadata|
Some of these structures are important to correctly support ARM64EC/ARM64X
PE binaries (\#teasing).
Debug Information
-----------------
LIEF version 0.17.0 supports more types of debug entries and provides a
user-friendly API:
- |lief-pe-vcfeature|
- |lief-pe-fpo|
- |lief-pe-exdllcharacteristics|
- |lief-pe-pdbchecksum|
As described in the :ref:`Debug Modification <pe_debug_modification>`
section, you can modify debug entries to perform various actions:
.. code-block:: python
pe = lief.PE.parse("some.dll")
# Changing the PDB file path to a URL
pe.codeview_pdb.filename = "https://lief.re/"
pe.write("out.dll")
Resources
---------
Some interfaces exposed by the |lief-pe-resource-manager| have been redesigned
to make them more consistent with their underlying representation in the PE
format.
For example, ``lief.PE.LangCodeItem`` has been renamed and refactored into
|lief-pe-resourcestringtable|.
Resource-related enums have been re-scoped to avoid definition conflicts
between Windows headers and LIEF:
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.EXTENDED_WINDOW_STYLES`` | :class:`lief.PE.ResourceDialog.WINDOW_EXTENDED_STYLES` |
+==========================================+======================================================================+
| ``lief.PE.WINDOW_STYLES`` | :class:`lief.PE.ResourceDialog.WINDOW_STYLES` |
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.DIALOG_BOX_STYLES`` | :class:`lief.PE.ResourceDialog.DIALOG_STYLES` |
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.FIXED_VERSION_OS`` | :class:`lief.PE.ResourceVersion.fixed_file_info_t.VERSION_OS` |
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.FIXED_VERSION_FILE_FLAGS`` | :class:`lief.PE.ResourceVersion.fixed_file_info_t.FILE_FLAGS` |
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.FIXED_VERSION_FILE_SUB_TYPES`` | :class:`lief.PE.ResourceVersion.fixed_file_info_t.FILE_TYPE_DETAILS` |
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.ACCELERATOR_FLAGS`` | :class:`lief.PE.ResourceAccelerator.FLAGS` |
+------------------------------------------+----------------------------------------------------------------------+
| ``lief.PE.ACCELERATOR_VK_CODES`` | :class:`lief.PE.ACCELERATOR_CODES` |
+------------------------------------------+----------------------------------------------------------------------+
Exception Info
--------------
For x86-64 and ARM64 PE binaries, stack unwinding information is referenced by
the data directory: ``IMAGE_DIRECTORY_ENTRY_EXCEPTION``. Even if your code is
compiled without exception support, this information may still be generated by the linker.
The entries of this data directory are represented by the
|lief-pe-exceptioninfo| structure, which is specialized for x64 and
ARM64 functions. Regardless of the underlying architecture, each entry in this
table exposes a function RVA.
From a reverse engineering perspective, these RVAs offer a valuable set of
function start addresses that can be used to begin disassembling the binary.
Given a |lief-pe-binary| instance, one can iterate over these
|lief-pe-exceptioninfo| entries using |lief-pe-binary-exceptions|:
.. code-block:: python
pe = lief.PE.parse("Windows.Media.Protection.PlayReady.dll", lief.PE.ParserConfgi.all)
print(pe.exceptions[10])
.. code-block:: text
RuntimeFunctionX64 {
RVA: [0x0c9350, 0x0c9382] (50 bytes)
Unwind info RVA: 0x68eb5c
unwind_info_t {
Version: 1
Flags: 0
Size of prologue: 20
Nb opcodes: 8 (6)
Opcodes: [
0x14 SAVE_NONVOL reg=RDI, offset=0x000078
0x14 SAVE_NONVOL reg=RBX, offset=0x000070
0x14 ALLOC_SMALL size=64
0x10 PUSH_NONVOL reg=R15
0x0e PUSH_NONVOL reg=R14
0x0c PUSH_NONVOL reg=R12
];
}
}
.. code-block:: python
pe = lief.PE.parse("win11_arm64x_Windows.Media.Protection.PlayReady.dll", lief.PE.ParserConfgi.all)
print(pe.exceptions[10])
.. code-block:: text
Runtime Unpacked AArch64 Function {
Range(RVA): 0x00822bb8 - 0x00822c08
Unwind location (RVA): 0x00d63838
Length=80 Vers=0 X=0 E=0, CodeWords=8
Epilogs=1
Prolog unwind:
0x0000 e1...... mov fp, sp
0x0001 81...... stp x29, x30, [sp, #-16]!
0x0002 e6...... save next
0x0003 e6...... save next
0x0004 e6...... save next
0x0005 e6...... save next
0x0006 e76689.. stp q6, q7, [sp, #-160]!
0x0009 fc...... pacibsp
0x000a e4...... end
Epilog #1 unwind: (Offset=10, Index=11, Reserved=0)
0x0000 81...... ldp x29, x30, [sp], #16
0x0001 e74e88.. ldp q14, q15, [sp, #128]
0x0004 e74c86.. ldp q12, q13, [sp, #96]
0x0007 e74a84.. ldp q10, q11, [sp, #64]
0x000a e74882.. ldp q8, q9, [sp, #32]
0x000d e76689.. ldp q6, q7, [sp], #160
0x0010 fc...... autibsp
0x0011 e3...... nop
0x0012 e3...... nop
0x0013 e4...... end
}
.. admonition:: ARM64 - ``SAVE_ANY_REG``
:class: tip
Thank you to `Eli Friedman <https://github.com/efriedma-quic>`_ and `Martin Storsjö <https://github.com/mstorsjo>`_
for their work on reverse engineering this undocumented unwind opcode.
LIEF provides a detailed API for the structures involved in PE
exceptions and stack unwinding.
.. admonition:: Performance Considerations
:class: warning
In-depth analysis of exception metadata can introduce significant overhead.
Therefore, |lief-pe-parser-config-parse_exceptions| must be
**explicitly** enabled.
ARM64EC / ARM64X
----------------
With the recent release of Snapdragon X, ARM64-based Windows computers are
becoming increasingly popular. This shift introduces some changes to
the PE format. One notable change is the introduction of ARM64X binaries, which
can be compared to the Mach-O FAT concept, where a single binary contains multiple
architectures.
In the case of ARM64X, a single PE file encapsulates ARM64 and ARM64EC architectures.
LIEF v0.17.0 exposes the following helpers to determine whether the binary is
ARM64X or ARM64EC: |lief-pe-binary-is_arm64ec|, |lief-pe-binary-is_arm64x|.
For an ARM64X binary, you can use |lief-pe-binary-nested_pe_binary| to access the
embedded ARM64EC **representation** of the binary.
.. admonition:: Performance Considerations
:class: warning
Parsing a nested ARM64EC binary can introduce additional overhead compared to
the 0.16.x version.
Therefore, |lief-pe-parser-config-parse_arm64x_binary| must be
**explicitly** enabled.
Other Changes
-------------
The workaround involving ``undef.h`` has been removed. This file was used to
``#undef`` certain Windows defines that conflicted with LIEF enum definitions.
You can now safely include Windows headers alongside LIEF headers. If you
encounter any conflicts, please report the issue.
The *builder* engine has been refactored to resolve numerous errors and bugs
associated with PE modifications. It now uses a more conservative approach.
For more details, please refer to the :ref:`PE <format-pe>` page.
The *"PE from Scratch"* feature has been removed, as it had significant bugs
that often resulted in corrupted binaries. This feature will be reintroduced in
a future release. If you rely on this feature, please reach out.
:List of changes:
* Fixed missing original forwarded function name (:issue:`1166`)
* |lief-pe-datadirectory| now exposes |lief-pe-datadirectory-content| to
access the raw bytes wrapped by the data directory
* PE's resource tree can now be parsed in a standalone way using
|lief-pe-resource-node-parse|.
.. code-block:: python
resource_tree = bytes("....")
original_rva = 0x20000
tree: lief.PE.ResourceNode = lief.PE.ResourceNode.parse(resource_tree, original_rva)
.. include:: ../_cross_api.rst
+242
View File
@@ -0,0 +1,242 @@
```{eval-rst}
.. role:: strike
:class: strike
```
(compilation_ref)=
# {fa}`solid fa-laptop-code` Compilation
To compile **LIEF**, you need at least the following:
- C++17 compiler (GCC, Clang, MSVC, etc.)
- CMake
- Python >= 3.9 (for the bindings)
:::{note}
Compiling from scratch with all options enabled can take approximately
20 minutes on a standard laptop.
:::
## Libraries only (SDK)
```console
$ git clone https://github.com/lief-project/LIEF.git
$ cd LIEF
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --target LIB_LIEF --config Release
```
:::{warning}
On Windows, you can choose which CRT to use by setting the
`CMAKE_MSVC_RUNTIME_LIBRARY` variable:
```console
$ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ..
```
For Debug, you should set the CRT to **MTd**:
```console
$ cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug ..
$ cmake --build . --target LIB_LIEF --config Debug
```
:::
## Python bindings
The Python bindings are built from the `api/python` directory, which uses a
[PEP 517](https://peps.python.org/pep-0517/) build backend based on
[scikit-build-core](https://scikit-build-core.readthedocs.io/):
```console
$ git clone https://github.com/lief-project/LIEF.git
$ cd LIEF/api/python
$ pip install [-e] [--user] .
# Or
$ pip install [-e] api/python
```
:::{note}
You can speed up the compilation by installing [ccache](https://ccache.dev/)
or [sccache](https://github.com/mozilla/sccache).
:::
You can customize the compilation by setting the `PYLIEF_CONF` environment
variable to the path of a TOML configuration file. By default, the Python
bindings use `config-default.toml` in the Python binding directory:
```toml
[lief.build]
type = "Release"
cache = true
ninja = true
parallel-jobs = 0
[lief.formats]
elf = true
pe = false
macho = true
...
```
```console
$ PYLIEF_CONF=/tmp/my-custom.toml pip install .
```
(lief_free_threaded)=
### Free-threaded Python
Since LIEF 1.0.0, the Python bindings can be compiled against the free-threaded
Python builds. This is controlled through the
`free-threaded` flag of the `[lief.build]` section of the configuration:
```toml
[lief.build]
type = "Release"
free-threaded = true
```
:::{warning}
When MbedTLS is resolved externally (`LIEF_OPT_MBEDTLS_EXTERNAL=ON`), you
must make sure that the provided build enables threading support. LIEF
cannot tweak the threading configuration in that case.
:::
At runtime, you can check whether the currently loaded extension was compiled
with free-threading support through {attr}`lief.__free_threaded__`.
## Runtime features
The {ref}`runtime features <runtime-intro>` are **not** enabled by default and
must be explicitly turned on. See {ref}`runtime-intro` for the CMake options
and TOML configuration used to enable the runtime module.
(lief_debug)=
## Debugging
By default, LIEF is compiled with `CMAKE_BUILD_TYPE` set to `Release`.
You can change this behavior by setting it to either `RelWithDebInfo` or
`Debug` during CMake's configuration step:
```console
$ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo [...] ..
```
Alternatively, the Python bindings can also be compiled with debug information
by changing the `type` in the `[lief.build]` section of `config-default.toml`:
```toml
[lief.build]
type = "RelWithDebInfo"
```
:::{note}
When developing LIEF, you can use:
```console
$ PYLIEF_CONF=~/lief-debug.toml pip install [-e] api/python
```
With `lief-debug.toml` set to:
```toml
[lief.build]
type = "RelWithDebInfo"
...
[lief.logging]
enabled = true
debug = true
```
:::
(lief_third_party)=
## Third Party
LIEF relies on several external projects, and we aim to limit dependencies in
the public headers as much as possible. The following table summarizes these
dependencies and their scopes. `internal` means that it is required to
compile LIEF but not to use it. `external` means that it is required for both.
| Dependency | Scope | Purpose |
| ---------------------------------------- | ---------- | ------------------------------------------ |
| {github-ref}`tcbrindle/span` | `external` | C++11 span interface |
| {github-ref}`TartanLlama/expected` | `external` | Error handling (see: {ref}`err_handling` ) |
| {github-ref}`gabime/spdlog` | `internal` | Logging |
| {github-ref}`Mbed-TLS/mbedtls` | `internal` | ASN.1 parser / Hash functions |
| {github-ref}`nemtrif/utfcpp` | `internal` | Unicode support (for PE and DEX files) |
| {github-ref}`nlohmann/json` | `internal` | Serialize LIEF objects into JSON |
| {github-ref}`wjakob/nanobind` | `internal` | Python bindings |
| {github-ref}`serge-sans-paille/frozen` | `internal` | `constexpr` containers |
| {github-ref}`IOActive/Melkor_ELF_Fuzzer` | `internal` | ELF Fuzzing |
| {github-ref}`catchorg/Catch2` | `internal` | Unit Testing |
With the exception of MbedTLS, all of these dependencies are header-only.
By default, they are embedded and managed by LIEF to simplify compilation and
integration.
Nevertheless, package managers often require linking against system libraries
rather than using vendored dependencies [^ref-issue] [^ref-vcpk].
To address this requirement, you can control the integration of LIEF's
dependencies using the following CMake options:
> - `LIEF_OPT_NLOHMANN_JSON_EXTERNAL`
> - `LIEF_OPT_UTFCPP_EXTERNAL`
> - `LIEF_OPT_MBEDTLS_EXTERNAL`
> - `LIEF_EXTERNAL_SPDLOG`
> - `LIEF_OPT_FROZEN_EXTERNAL`
> - `LIEF_OPT_EXTERNAL_SPAN/LIEF_EXTERNAL_SPAN_DIR`
> - `LIEF_OPT_EXTERNAL_EXPECTED`
> - `LIEF_OPT_NANOBIND_EXTERNAL`
By setting these flags, LIEF will resolve dependencies using CMake's
`find_package(...)`, which relies on `<DEPS>_DIR` to locate the package.
For example, LIEF can be compiled using the following configuration:
```console
$ cmake .. -GNinja \
-DLIEF_OPT_NLOHMANN_JSON_EXTERNAL=ON \
-Dnlohmann_json_DIR=/lief-third-party/json/install/lib/cmake/nlohmann_json \
-DLIEF_OPT_MBEDTLS_EXTERNAL=on \
-DMbedTLS_DIR=/lief-third-party/mbedtls/install/cmake
```
:::{warning}
As mentioned previously, MbedTLS is not header-only. This means that if it is *externalized*, the static
version of LIEF will not include the MbedTLS object files, and the end user will have to manually link
`LIEF.a` with a provided version of MbedTLS.
:::
[^ref-issue]: <https://github.com/lief-project/LIEF/issues/605>
[^ref-vcpk]: <https://learn.microsoft.com/en-us/vcpkg/contributing/maintainer-guide#do-not-use-vendored-dependencies>
## Continuous Integration
LIEF uses GitHub Actions to test and release nightly builds. The configuration
of this CI can also be a good source of information for the compilation process.
In particular, [scripts/docker/linux-sdk-x64](https://github.com/lief-project/LIEF/blob/main/scripts/docker/linux-sdk-x64)
contains the build process to generate the **Linux x86-64 SDK**.
On Windows, the SDK is built with the following Python script:
[scripts/windows/package_sdk.py](https://github.com/lief-project/LIEF/blob/main/scripts/windows/package_sdk.py)
For **OSX**, refer to the CI config [.github/workflows/osx.yml](https://github.com/lief-project/LIEF/blob/main/.github/workflows/osx.yml),
and for **iOS**, see the [scripts/osx/package_ios.sh](https://github.com/lief-project/LIEF/blob/main/scripts/osx/package_ios.sh)
script, to see how LIEF is compiled (and cross-compiled) for these platforms.
## CMake Options
{{ literalinclude("../../cmake/LIEFOptions.cmake") }}
## Docker
See [liefproject](https://hub.docker.com/u/liefproject) on Dockerhub
-261
View File
@@ -1,261 +0,0 @@
.. role:: strike
:class: strike
.. _compilation_ref:
:fa:`solid fa-laptop-code` Compilation
======================================
To compile **LIEF**, you need at least the following:
- C++17 compiler (GCC, Clang, MSVC, etc.)
- CMake
- Python >= 3.9 (for the bindings)
.. note::
Compiling from scratch with all options enabled can take approximately
20 minutes on a standard laptop.
Libraries only (SDK)
--------------------
.. code-block:: console
$ git clone https://github.com/lief-project/LIEF.git
$ cd LIEF
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --target LIB_LIEF --config Release
.. warning::
On Windows, you can choose which CRT to use by setting the
``CMAKE_MSVC_RUNTIME_LIBRARY`` variable:
.. code-block:: console
$ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded ..
For Debug, you should set the CRT to **MTd**:
.. code-block:: console
$ cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug ..
$ cmake --build . --target LIB_LIEF --config Debug
Python bindings
---------------
The Python bindings are built from the ``api/python`` directory, which uses a
`PEP 517 <https://peps.python.org/pep-0517/>`_ build backend based on
`scikit-build-core <https://scikit-build-core.readthedocs.io/>`_:
.. code-block:: console
$ git clone https://github.com/lief-project/LIEF.git
$ cd LIEF/api/python
$ pip install [-e] [--user] .
# Or
$ pip install [-e] api/python
.. note::
You can speed up the compilation by installing `ccache <https://ccache.dev/>`_
or `sccache <https://github.com/mozilla/sccache>`_.
You can customize the compilation by setting the ``PYLIEF_CONF`` environment
variable to the path of a TOML configuration file. By default, the Python
bindings use ``config-default.toml`` in the Python binding directory:
.. code-block:: toml
[lief.build]
type = "Release"
cache = true
ninja = true
parallel-jobs = 0
[lief.formats]
elf = true
pe = false
macho = true
...
.. code-block:: console
$ PYLIEF_CONF=/tmp/my-custom.toml pip install .
.. _lief_free_threaded:
Free-threaded Python
~~~~~~~~~~~~~~~~~~~~
Since LIEF 1.0.0, the Python bindings can be compiled against the free-threaded
Python builds. This is controlled through the
``free-threaded`` flag of the ``[lief.build]`` section of the configuration:
.. code-block:: toml
[lief.build]
type = "Release"
free-threaded = true
.. warning::
When MbedTLS is resolved externally (``LIEF_OPT_MBEDTLS_EXTERNAL=ON``), you
must make sure that the provided build enables threading support. LIEF
cannot tweak the threading configuration in that case.
At runtime, you can check whether the currently loaded extension was compiled
with free-threading support through :attr:`lief.__free_threaded__`.
Runtime features
----------------
The :ref:`runtime features <runtime-intro>` are **not** enabled by default and
must be explicitly turned on. See :ref:`runtime-intro` for the CMake options
and TOML configuration used to enable the runtime module.
.. _lief_debug:
Debugging
---------
By default, LIEF is compiled with ``CMAKE_BUILD_TYPE`` set to ``Release``.
You can change this behavior by setting it to either ``RelWithDebInfo`` or
``Debug`` during CMake's configuration step:
.. code-block:: console
$ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo [...] ..
Alternatively, the Python bindings can also be compiled with debug information
by changing the ``type`` in the ``[lief.build]`` section of ``config-default.toml``:
.. code-block:: toml
[lief.build]
type = "RelWithDebInfo"
.. note::
When developing LIEF, you can use:
.. code-block:: console
$ PYLIEF_CONF=~/lief-debug.toml pip install [-e] api/python
With ``lief-debug.toml`` set to:
.. code-block:: toml
[lief.build]
type = "RelWithDebInfo"
...
[lief.logging]
enabled = true
debug = true
.. _lief_third_party:
Third Party
-----------
LIEF relies on several external projects, and we aim to limit dependencies in
the public headers as much as possible. The following table summarizes these
dependencies and their scopes. ``internal`` means that it is required to
compile LIEF but not to use it. ``external`` means that it is required for both.
+------------------------------------------+--------------+--------------------------------------------+
| Dependency | Scope | Purpose |
+==========================================+==============+============================================+
| :github-ref:`tcbrindle/span` | ``external`` | C++11 span interface |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`TartanLlama/expected` | ``external`` | Error handling (see: :ref:`err_handling` ) |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`gabime/spdlog` | ``internal`` | Logging |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`Mbed-TLS/mbedtls` | ``internal`` | ASN.1 parser / Hash functions |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`nemtrif/utfcpp` | ``internal`` | Unicode support (for PE and DEX files) |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`nlohmann/json` | ``internal`` | Serialize LIEF objects into JSON |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`wjakob/nanobind` | ``internal`` | Python bindings |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`serge-sans-paille/frozen` | ``internal`` | ``constexpr`` containers |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`IOActive/Melkor_ELF_Fuzzer` | ``internal`` | ELF Fuzzing |
+------------------------------------------+--------------+--------------------------------------------+
| :github-ref:`catchorg/Catch2` | ``internal`` | Unit Testing |
+------------------------------------------+--------------+--------------------------------------------+
With the exception of MbedTLS, all of these dependencies are header-only.
By default, they are embedded and managed by LIEF to simplify compilation and
integration.
Nevertheless, package managers often require linking against system libraries
rather than using vendored dependencies [#ref_issue]_ [#ref_vcpk]_.
To address this requirement, you can control the integration of LIEF's
dependencies using the following CMake options:
* ``LIEF_OPT_NLOHMANN_JSON_EXTERNAL``
* ``LIEF_OPT_UTFCPP_EXTERNAL``
* ``LIEF_OPT_MBEDTLS_EXTERNAL``
* ``LIEF_EXTERNAL_SPDLOG``
* ``LIEF_OPT_FROZEN_EXTERNAL``
* ``LIEF_OPT_EXTERNAL_SPAN/LIEF_EXTERNAL_SPAN_DIR``
* ``LIEF_OPT_EXTERNAL_EXPECTED``
* ``LIEF_OPT_NANOBIND_EXTERNAL``
By setting these flags, LIEF will resolve dependencies using CMake's
``find_package(...)``, which relies on ``<DEPS>_DIR`` to locate the package.
For example, LIEF can be compiled using the following configuration:
.. code-block:: console
$ cmake .. -GNinja \
-DLIEF_OPT_NLOHMANN_JSON_EXTERNAL=ON \
-Dnlohmann_json_DIR=/lief-third-party/json/install/lib/cmake/nlohmann_json \
-DLIEF_OPT_MBEDTLS_EXTERNAL=on \
-DMbedTLS_DIR=/lief-third-party/mbedtls/install/cmake
.. warning::
As mentioned previously, MbedTLS is not header-only. This means that if it is *externalized*, the static
version of LIEF will not include the MbedTLS object files, and the end user will have to manually link
``LIEF.a`` with a provided version of MbedTLS.
.. [#ref_issue] https://github.com/lief-project/LIEF/issues/605
.. [#ref_vcpk] https://learn.microsoft.com/en-us/vcpkg/contributing/maintainer-guide#do-not-use-vendored-dependencies
Continuous Integration
----------------------
LIEF uses GitHub Actions to test and release nightly builds. The configuration
of this CI can also be a good source of information for the compilation process.
In particular, `scripts/docker/linux-sdk-x64 <https://github.com/lief-project/LIEF/blob/main/scripts/docker/linux-sdk-x64>`_
contains the build process to generate the **Linux x86-64 SDK**.
On Windows, the SDK is built with the following Python script:
`scripts/windows/package_sdk.py <https://github.com/lief-project/LIEF/blob/main/scripts/windows/package_sdk.py>`_
For **OSX**, refer to the CI config `.github/workflows/osx.yml <https://github.com/lief-project/LIEF/blob/main/.github/workflows/osx.yml>`_,
and for **iOS**, see the `scripts/osx/package_ios.sh <https://github.com/lief-project/LIEF/blob/main/scripts/osx/package_ios.sh>`_
script, to see how LIEF is compiled (and cross-compiled) for these platforms.
CMake Options
-------------
.. literalinclude:: ../../cmake/LIEFOptions.cmake
Docker
------
See `liefproject <https://hub.docker.com/u/liefproject>`_ on Dockerhub
+25 -15
View File
@@ -1,27 +1,24 @@
#!/usr/bin/env python
import sys
from pathlib import Path
sys.path.insert(0, Path(__file__).parent.as_posix())
from typing import TYPE_CHECKING
from sphinx.application import Sphinx
from sphinx_lief_doc.config import init_config as lief_init_config
from sphinx_lief_doc.img_comparison import setup as setup_img_comparison
from sphinx_lief_doc.inheritance_diagram import LIEFInheritanceDiagram
from sphinx_lief_doc.lief_api import setup as setup_lief_api
from sphinx_lief_doc.literalinclude import LiteralInclude
from sphinx_lief_doc.plugin_package import setup as setup_plugin_packages
from sphinx_lief_doc.python_typing import setup as setup_python_typing
from sphinx_lief_doc.roles import setup as setup_roles
from sphinx_lief_doc.rust_domain import RustDomain
from sphinx_lief_doc.sdk_package import setup as setup_sdk_packages
from sphinx_lief_doc.seo import setup as setup_seo
from sphinx_lief_doc.writers.html5 import HTML5Translator
if TYPE_CHECKING:
from sphinx.application import Sphinx
extensions = [
"myst_parser",
"sphinx.ext.mathjax",
"sphinx.ext.autodoc",
"sphinx.ext.extlinks",
@@ -33,7 +30,19 @@ extensions = [
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
source_suffix = {".rst": "restructuredtext"}
source_suffix = {".md": "markdown"}
exclude_patterns = ["_cross_api.md"]
myst_enable_extensions = [
"colon_fence",
"substitution",
]
myst_all_links_external = True
myst_footnote_sort = False
myst_substitutions = {
"cross_api": "```{include} /_cross_api.md\n```",
"literalinclude": LiteralInclude(),
}
extlinks = {
"github-ref": ("https://github.com/%s", "%s"),
@@ -66,15 +75,15 @@ autodoc_default_options = {
# exclude_patterns = [
# "api",
# "tutorials/*.rst",
# "changelog/*.rst",
# "tutorials/*.md",
# "changelog/*.md",
# "extended",
# "formats",
# "changelog.rst",
# "references.rst",
# "intro.rst",
# "installation.rst",
# "compilation.rst",
# "changelog.md",
# "references.md",
# "intro.md",
# "installation.md",
# "compilation.md",
# ]
@@ -90,6 +99,7 @@ def setup(app: Sphinx):
setup_img_comparison(app)
setup_plugin_packages(app)
setup_sdk_packages(app)
setup_seo(app)
app.add_directive("lief-inheritance", LIEFInheritanceDiagram)
app.set_translator("html", HTML5Translator)
+10
View File
@@ -0,0 +1,10 @@
# {fa}`regular fa-file-code` C++
- {cpp:func}`LIEF::Binary::assemble`
- {cpp:class}`LIEF::assembly::Engine`
## AssemblerConfig
```{eval-rst}
.. doxygenclass:: LIEF::assembly::AssemblerConfig
```
-11
View File
@@ -1,11 +0,0 @@
:fa:`regular fa-file-code` C++
--------------------------------
- :cpp:func:`LIEF::Binary::assemble`
- :cpp:class:`LIEF::assembly::Engine`
AssemblerConfig
***************
.. doxygenclass:: LIEF::assembly::AssemblerConfig
+163
View File
@@ -0,0 +1,163 @@
(extended-assembler)=
# {fa}`solid fa-user-secret` Assembler
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
```
## Introduction
In addition to standard file format modifications, it may be necessary to patch
code with custom assembly. This functionality is available through the
{sub-ref}`lief-assemble` function:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/assembler.py", "disassemble-assemble") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/assembler.cpp", "disassemble-assemble") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/assembler.rs", "disassemble-assemble") }}
:::
::::
:::{warning}
The assembler works well for `AArch64/ARM64E`, `x86/x86-64`, and `RISC-V`
but support for other architectures is currently limited.
:::
## Technical Details
Similar to the {ref}`disassembler <extended-disassembler>`, this assembler is
based on the LLVM MC layer.
The assembly text is consumed by the `llvm::MCAsmParser` object, and we
*intercept* the raw generated assembly bytes from the `llvm::MCObjectWriter`.
We also resolve `llvm::MCFixup` for a vast majority of the generated fixups.
An important feature introduced in LIEF 0.17.0 is support for resolving symbols
or labels **on the fly**.
(extended-assembler-contextual-patching)=
## Contextual Assembly Patching
Given assembly code and a target address, we might want to use a **context**
to resolve symbols referenced in the assembly listing.
For example, consider the following patch:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/assembler.py", "context-error") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/assembler.cpp", "context-error") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/assembler.rs", "context-error") }}
:::
::::
In this example, `a_custom_function` is undefined, so the assembler engine
cannot resolve it and raises the following error:
```text
warning: Fixup not resolved:
call a_custom_function
```
LIEF exposes a {sub-ref}`lief-asm-AssemblerConfig` interface that can be used to
configure the engine and to **dynamically** resolve symbols used in the assembly
listing:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/assembler.py", "config-resolver", emphasize_lines="1-9,19") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/assembler.cpp", "config-resolver", emphasize_lines="1-9,11,19") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/assembler.rs", "config-resolver", emphasize_lines="3-12,20") }}
:::
::::
This interface can be used to wrap a context, such as a generic
{sub-ref}`lief-abstract-binary`:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/assembler.py", "config-target", prepend="import lief", emphasize_lines="6,10-13,16") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/assembler.cpp", "config-target", emphasize_lines="4-6,9-12,22") }}
:::
::::
The Rust bindings do not offer the same flexibility to capture the
{sub-ref}`lief-abstract-binary`. Nevertheless, the closure associated with the
{rust:member}`lief::assembly::AssemblerConfig::symbol_resolver [struct]`
can capture most of its context:
::::{tabs}
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/assembler.rs", "config-target", emphasize_lines="5-12") }}
:::
::::
## Use Cases
Patching code with the assembler is a fast alternative to editing raw bytes by
hand: it is useful for bypassing a check while reverse engineering,
hot-patching a bug in a shipped executable, or inserting instrumentation.
### Disabling an Instruction
To strip a single instruction like a call to a telemetry or anti-debugging
routine *without* shifting the rest of the
function we can overwrite it with as many `nop` bytes as it occupied. Pairing the
{ref}`disassembler <extended-disassembler>` with {sub-ref}`lief-assemble` lets you
do this:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/assembler.py", "nop-out") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/assembler.cpp", "nop-out") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/assembler.rs", "nop-out") }}
:::
::::
:::{note}
The snippets above assume `x86/x86-64`, where a `nop` is a single byte,
so `inst.size` of them fill the slot exactly. On fixed-width instruction set such as
`AArch64` every instruction is 4 bytes, so we would emit `inst.size / 4` instead.
:::
## In-Memory Assembler
In addition to patching binaries on disk or within standard file formats, the
assembly engine is also available for JIT compilation and in-memory operations.
This is exposed through the runtime API {sub-ref}`lief-runtime-assemble`, as detailed in the
{ref}`Runtime Memory <runtime_memory>` documentation.
{fa}`brands fa-python` {doc}`Python API <python>`
{fa}`regular fa-file-code` {doc}`C++ API <cpp>`
{fa}`brands fa-rust` {doc}`Rust API <rust>`
{{ cross_api }}
-249
View File
@@ -1,249 +0,0 @@
.. _extended-assembler:
:fa:`solid fa-user-secret` Assembler
-------------------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
----
Introduction
************
In addition to standard file format modifications, it may be necessary to patch
code with custom assembly. This functionality is available through the
|lief-assemble| function:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/assembler.py
:language: python
:start-after: lief-doc: disassemble-assemble-start
:end-before: lief-doc: disassemble-assemble-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/assembler.cpp
:language: cpp
:start-after: lief-doc: disassemble-assemble-start
:end-before: lief-doc: disassemble-assemble-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/assembler.rs
:language: rust
:start-after: lief-doc: disassemble-assemble-start
:end-before: lief-doc: disassemble-assemble-end
:dedent:
.. warning::
The assembler works well for ``AArch64/ARM64E``, ``x86/x86-64``, and ``RISC-V``
but support for other architectures is currently limited.
Technical Details
*****************
Similar to the :ref:`disassembler <extended-disassembler>`, this assembler is
based on the LLVM MC layer.
The assembly text is consumed by the ``llvm::MCAsmParser`` object, and we
*intercept* the raw generated assembly bytes from the ``llvm::MCObjectWriter``.
We also resolve ``llvm::MCFixup`` for a vast majority of the generated fixups.
An important feature introduced in LIEF 0.17.0 is support for resolving symbols
or labels **on the fly**.
.. _extended-assembler-contextual-patching:
Contextual Assembly Patching
****************************
Given assembly code and a target address, we might want to use a **context**
to resolve symbols referenced in the assembly listing.
For example, consider the following patch:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/assembler.py
:language: python
:start-after: lief-doc: context-error-start
:end-before: lief-doc: context-error-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/assembler.cpp
:language: cpp
:start-after: lief-doc: context-error-start
:end-before: lief-doc: context-error-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/assembler.rs
:language: rust
:start-after: lief-doc: context-error-start
:end-before: lief-doc: context-error-end
:dedent:
In this example, ``a_custom_function`` is undefined, so the assembler engine
cannot resolve it and raises the following error:
.. code-block:: text
warning: Fixup not resolved:
call a_custom_function
LIEF exposes a |lief-asm-AssemblerConfig| interface that can be used to
configure the engine and to **dynamically** resolve symbols used in the assembly
listing:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/assembler.py
:language: python
:emphasize-lines: 1-9,19
:start-after: lief-doc: config-resolver-start
:end-before: lief-doc: config-resolver-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/assembler.cpp
:language: cpp
:emphasize-lines: 1-9,11,19
:start-after: lief-doc: config-resolver-start
:end-before: lief-doc: config-resolver-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/assembler.rs
:language: rust
:emphasize-lines: 3-12,20
:start-after: lief-doc: config-resolver-start
:end-before: lief-doc: config-resolver-end
:dedent:
This interface can be used to wrap a context, such as a generic
|lief-abstract-binary|:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/assembler.py
:language: python
:prepend: import lief
:emphasize-lines: 6,10-13,16
:start-after: lief-doc: config-target-start
:end-before: lief-doc: config-target-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/assembler.cpp
:language: cpp
:emphasize-lines: 4-6,9-12,22
:start-after: lief-doc: config-target-start
:end-before: lief-doc: config-target-end
:dedent:
The Rust bindings do not offer the same flexibility to capture the
|lief-abstract-binary|. Nevertheless, the closure associated with the
:rust:member:`lief::assembly::AssemblerConfig::symbol_resolver [struct]`
can capture most of its context:
.. tabs::
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/assembler.rs
:language: rust
:emphasize-lines: 5-12
:start-after: lief-doc: config-target-start
:end-before: lief-doc: config-target-end
:dedent:
Use Cases
*********
Patching code with the assembler is a fast alternative to editing raw bytes by
hand: it is useful for bypassing a check while reverse engineering,
hot-patching a bug in a shipped executable, or inserting instrumentation.
Disabling an Instruction
~~~~~~~~~~~~~~~~~~~~~~~~~
To strip a single instruction like a call to a telemetry or anti-debugging
routine *without* shifting the rest of the
function we can overwrite it with as many ``nop`` bytes as it occupied. Pairing the
:ref:`disassembler <extended-disassembler>` with |lief-assemble| lets you
do this:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/assembler.py
:language: python
:start-after: lief-doc: nop-out-start
:end-before: lief-doc: nop-out-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/assembler.cpp
:language: cpp
:start-after: lief-doc: nop-out-start
:end-before: lief-doc: nop-out-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/assembler.rs
:language: rust
:start-after: lief-doc: nop-out-start
:end-before: lief-doc: nop-out-end
:dedent:
.. note::
The snippets above assume ``x86/x86-64``, where a ``nop`` is a single byte,
so ``inst.size`` of them fill the slot exactly. On fixed-width instruction set such as
``AArch64`` every instruction is 4 bytes, so we would emit ``inst.size / 4`` instead.
In-Memory Assembler
*******************
In addition to patching binaries on disk or within standard file formats, the
assembly engine is also available for JIT compilation and in-memory operations.
This is exposed through the runtime API |lief-runtime-assemble|, as detailed in the
:ref:`Runtime Memory <runtime_memory>` documentation.
:fa:`brands fa-python` :doc:`Python API <python>`
:fa:`regular fa-file-code` :doc:`C++ API <cpp>`
:fa:`brands fa-rust` :doc:`Rust API <rust>`
.. include:: ../../_cross_api.rst
+10
View File
@@ -0,0 +1,10 @@
# {fa}`brands fa-python` Python
- {meth}`lief.Binary.assemble`
- {class}`lief.assembly.Engine`
## AssemblerConfig
```{eval-rst}
.. autoclass:: lief.assembly.AssemblerConfig
```
-12
View File
@@ -1,12 +0,0 @@
:fa:`brands fa-python` Python
------------------------------
- :meth:`lief.Binary.assemble`
- :class:`lief.assembly.Engine`
AssemblerConfig
***************
.. autoclass:: lief.assembly.AssemblerConfig
+3
View File
@@ -0,0 +1,3 @@
# {fa}`brands fa-rust` Rust
- {rust:method}`lief::generic::Binary::assemble [trait]`
-4
View File
@@ -1,4 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
- :rust:method:`lief::generic::Binary::assemble [trait]`
+57
View File
@@ -0,0 +1,57 @@
(debug-info)=
# {fa}`solid fa-magnifying-glass` Debug Info
{ref}`PDB <extended-pdb>` and {ref}`DWARF <extended-dwarf>` share similar
traits which are abstracted by the following classes:
## {fa}`regular fa-file-code` C++
### DebugInfo
```{eval-rst}
.. doxygenclass:: LIEF::DebugInfo
```
### debug_location_t
```{eval-rst}
.. doxygenstruct:: LIEF::debug_location_t
```
### DeclOpt
```{eval-rst}
.. doxygenclass:: LIEF::DeclOpt
```
______________________________________________________________________
## {fa}`brands fa-python` Python
### DebugInfo
```{eval-rst}
.. autoclass:: lief.DebugInfo
```
### debug_location_t
```{eval-rst}
.. autoclass:: lief.debug_location_t
```
### DeclOpt
```{eval-rst}
.. autoclass:: lief.DeclOpt
```
______________________________________________________________________
## {fa}`brands fa-rust` Rust
- {rust:trait}`lief::generic::DebugInfo`
- {rust:struct}`lief::DebugLocation`
- {rust:struct}`lief::DeclOpt`
-59
View File
@@ -1,59 +0,0 @@
.. _debug-info:
:fa:`solid fa-magnifying-glass` Debug Info
------------------------------------------
:ref:`PDB <extended-pdb>` and :ref:`DWARF <extended-dwarf>` share similar
traits which are abstracted by the following classes:
:fa:`regular fa-file-code` C++
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DebugInfo
*********
.. doxygenclass:: LIEF::DebugInfo
debug_location_t
****************
.. doxygenstruct:: LIEF::debug_location_t
DeclOpt
*******
.. doxygenclass:: LIEF::DeclOpt
----
:fa:`brands fa-python` Python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DebugInfo
*********
.. autoclass:: lief.DebugInfo
debug_location_t
****************
.. autoclass:: lief.debug_location_t
DeclOpt
*******
.. autoclass:: lief.DeclOpt
----
:fa:`brands fa-rust` Rust
~~~~~~~~~~~~~~~~~~~~~~~~~
- :rust:trait:`lief::generic::DebugInfo`
- :rust:struct:`lief::DebugLocation`
- :rust:struct:`lief::DeclOpt`
@@ -1,38 +1,41 @@
:fa:`solid fa-microchip` AArch64
--------------------------------
# {fa}`solid fa-microchip` AArch64
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::aarch64::Instruction
```
Opcodes
*******
## Opcodes
See ``LIEF::assembly::aarch64::OPCODE`` in ``include/asm/aarch64/opcodes.hpp``
See `LIEF::assembly::aarch64::OPCODE` in `include/asm/aarch64/opcodes.hpp`
## Operands
Operands
********
```{eval-rst}
.. doxygenclass:: LIEF::assembly::aarch64::Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. doxygenclass:: LIEF::assembly::aarch64::operands::Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. doxygenclass:: LIEF::assembly::aarch64::operands::Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. doxygenclass:: LIEF::assembly::aarch64::operands::Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. doxygenclass:: LIEF::assembly::aarch64::operands::PCRelative
```
@@ -0,0 +1,12 @@
# {fa}`solid fa-microchip` ARM
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::arm::Instruction
```
## Opcodes
See `LIEF::assembly::arm::OPCODE` in `include/asm/arm/opcodes.hpp`
@@ -1,14 +0,0 @@
:fa:`solid fa-microchip` ARM
----------------------------
Instruction
************
.. doxygenclass:: LIEF::assembly::arm::Instruction
Opcodes
*******
See ``LIEF::assembly::arm::OPCODE`` in ``include/asm/arm/opcodes.hpp``
@@ -1,37 +1,41 @@
:fa:`solid fa-microchip` eBPF
-----------------------------
# {fa}`solid fa-microchip` eBPF
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::ebpf::Instruction
```
Opcodes
*******
## Opcodes
See ``LIEF::assembly::ebpf::OPCODE`` in ``include/asm/ebpf/opcodes.hpp``
See `LIEF::assembly::ebpf::OPCODE` in `include/asm/ebpf/opcodes.hpp`
Operands
********
## Operands
```{eval-rst}
.. doxygenclass:: LIEF::assembly::ebpf::Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. doxygenclass:: LIEF::assembly::ebpf::operands::Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. doxygenclass:: LIEF::assembly::ebpf::operands::Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. doxygenclass:: LIEF::assembly::ebpf::operands::Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. doxygenclass:: LIEF::assembly::ebpf::operands::PCRelative
```
@@ -1,37 +1,41 @@
:fa:`solid fa-microchip` Mips
-----------------------------
# {fa}`solid fa-microchip` Mips
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::mips::Instruction
```
Opcodes
*******
## Opcodes
See ``LIEF::assembly::mips::OPCODE`` in ``include/asm/mips/opcodes.hpp``
See `LIEF::assembly::mips::OPCODE` in `include/asm/mips/opcodes.hpp`
Operands
********
## Operands
```{eval-rst}
.. doxygenclass:: LIEF::assembly::mips::Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. doxygenclass:: LIEF::assembly::mips::operands::Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. doxygenclass:: LIEF::assembly::mips::operands::Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. doxygenclass:: LIEF::assembly::mips::operands::Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. doxygenclass:: LIEF::assembly::mips::operands::PCRelative
```
@@ -1,37 +1,41 @@
:fa:`solid fa-microchip` PowerPC
--------------------------------
# {fa}`solid fa-microchip` PowerPC
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::powerpc::Instruction
```
Opcodes
*******
## Opcodes
See ``LIEF::assembly::powerpc::OPCODE`` in ``include/asm/powerpc/opcodes.hpp``
See `LIEF::assembly::powerpc::OPCODE` in `include/asm/powerpc/opcodes.hpp`
Operands
********
## Operands
```{eval-rst}
.. doxygenclass:: LIEF::assembly::powerpc::Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. doxygenclass:: LIEF::assembly::powerpc::operands::Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. doxygenclass:: LIEF::assembly::powerpc::operands::Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. doxygenclass:: LIEF::assembly::powerpc::operands::Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. doxygenclass:: LIEF::assembly::powerpc::operands::PCRelative
```
@@ -1,37 +1,41 @@
:fa:`solid fa-microchip` RISC-V
-------------------------------
# {fa}`solid fa-microchip` RISC-V
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::riscv::Instruction
```
Opcodes
*******
## Opcodes
See ``LIEF::assembly::riscv::OPCODE`` in ``include/asm/riscv/opcodes.hpp``
See `LIEF::assembly::riscv::OPCODE` in `include/asm/riscv/opcodes.hpp`
Operands
********
## Operands
```{eval-rst}
.. doxygenclass:: LIEF::assembly::riscv::Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. doxygenclass:: LIEF::assembly::riscv::operands::Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. doxygenclass:: LIEF::assembly::riscv::operands::Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. doxygenclass:: LIEF::assembly::riscv::operands::Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. doxygenclass:: LIEF::assembly::riscv::operands::PCRelative
```
@@ -1,37 +1,41 @@
:fa:`solid fa-microchip` X86/x86-64
-----------------------------------
# {fa}`solid fa-microchip` X86/x86-64
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::x86::Instruction
```
Opcodes
*******
## Opcodes
See ``LIEF::assembly::x86::OPCODE`` in ``include/asm/x86/opcodes.hpp``
See `LIEF::assembly::x86::OPCODE` in `include/asm/x86/opcodes.hpp`
Operands
********
## Operands
```{eval-rst}
.. doxygenclass:: LIEF::assembly::x86::Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. doxygenclass:: LIEF::assembly::x86::operands::Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. doxygenclass:: LIEF::assembly::x86::operands::Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. doxygenclass:: LIEF::assembly::x86::operands::Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. doxygenclass:: LIEF::assembly::x86::operands::PCRelative
```
@@ -1,9 +1,8 @@
:fa:`regular fa-file-code` C++
--------------------------------
# {fa}`regular fa-file-code` C++
Architectures
*************
## Architectures
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-microchip">&nbsp;</i>Architectures
:maxdepth: 1
@@ -15,14 +14,16 @@ Architectures
arch/ebpf
arch/mips
arch/powerpc
```
Engine
******
## Engine
```{eval-rst}
.. doxygenclass:: LIEF::assembly::Engine
```
Instruction
************
## Instruction
```{eval-rst}
.. doxygenclass:: LIEF::assembly::Instruction
```
+200
View File
@@ -0,0 +1,200 @@
(extended-disassembler)=
# {fa}`solid fa-dna` Disassembler
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp/index
python/index
rust
```
## Introduction
LIEF Extended provides a user-friendly API for disassembling code within various
parts of executable formats for the following architectures:
x86/x86-64, ARM, AArch64, RISC-V, MIPS, PowerPC, and eBPF.
You can begin disassembling code within a binary using the {sub-ref}`lief-disassemble`
function, which is exposed in the abstraction layer:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/disassembler.py", "disassemble") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/disassembler.cpp", "disassemble") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/disassembler.rs", "disassemble") }}
:::
::::
From a design perspective, the disassembler returns a *lazy* iterator,
yielding a {sub-ref}`lief-asm-instruction` instance as it evaluates the
instruction at each address.
Consequently, when calling `elf.disassemble_address(0x400)`, no disassembly
occurs until the iterator is advanced.
Instructions are represented by the {sub-ref}`lief-asm-instruction` object,
which is extended by architecture-specific objects:
- {sub-ref}`lief-asm-x86-instruction`
- {sub-ref}`lief-asm-arm-instruction`
- {sub-ref}`lief-asm-aarch64-instruction`
- {sub-ref}`lief-asm-powerpc-instruction`
- {sub-ref}`lief-asm-mips-instruction`
- {sub-ref}`lief-asm-riscv-instruction`
- {sub-ref}`lief-asm-ebpf-instruction`
In Python, you can check the effective type of
a {class}`lief.assembly.Instruction` with `isinstance(...)`:
{{ literalinclude("../../../code/python/disassembler.py", "downcast") }}
In C++, downcasting is performed using the function:
{cpp:func}`LIEF::assembly::Instruction::as`:
{{ literalinclude("../../../code/cpp/disassembler.cpp", "downcast") }}
In Rust, instructions are represented by the enum {rust:enum}`lief::assembly::Instructions`.
Thus, you can write:
{{ literalinclude("../../../code/rust/src/disassembler.rs", "downcast") }}
:::{note}
You can also check the assembler documentation here: {ref}`Assembler <extended-assembler>`
:::
For the `x86/x86-64` and `AArch64` architectures, you can also iterate
over an instruction's operands:
::::{tabs}
:::{tab} {fa}`solid fa-microchip` AArch64
{{ literalinclude("../../../code/python/disassembler.py", "operands-aarch64", prepend="import lief") }}
:::
:::{tab} {fa}`solid fa-microchip` x86/x86-64
{{ literalinclude("../../../code/python/disassembler.py", "operands-x86", prepend="import lief") }}
:::
::::
You can check the documentation of these architectures for more details about
the exposed API.
## x86/x86-64
On x86/x86-64, {sub-ref}`lief-asm-x86-instruction` also exposes an API to inspect and
rewrite the `LOCK` prefix of an instruction:
- {sub-ref}`lief-assembly-x86-Instruction-has_lock_prefix`
- {sub-ref}`lief-assembly-x86-Instruction-is_lockable`
- {sub-ref}`lief-assembly-x86-Instruction-is_atomic`
- {sub-ref}`lief-assembly-x86-Instruction-lock`
- {sub-ref}`lief-assembly-x86-Instruction-unlock`
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/disassembler.py", "x86-lock", prepend="import lief") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/disassembler.cpp", "x86-lock") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/disassembler.rs", "x86-lock") }}
:::
::::
## Use Cases
### DWARF Function
In addition to the regular {sub-ref}`lief-disassemble` API, you can use
{sub-ref}`lief-dwarf-function-instructions` to disassemble a {ref}`DWARF <extended-dwarf>`
function.
:::{warning}
{sub-ref}`lief-dwarf-function-instructions` only works if the DWARF debug info
is **embedded** in the binary. This is the default behavior for
{ref}`ELF <format-elf>` binaries, but this is not the case for Mach-O
`.dSYM` files.
:::
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/disassembler.py", "dwarf-func", prepend="import lief") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/disassembler.cpp", "dwarf-func") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/disassembler.rs", "dwarf-func") }}
:::
::::
### Dyld Shared Cache
A disassembly API is also provided for the {sub-ref}`lief-dsc-dyldsharedcache` object
via {sub-ref}`lief-dsc-dyldsharedcache-disassemble`:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/disassembler.py", "dsc-disassemble") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/disassembler.cpp", "dsc-disassemble") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/disassembler.rs", "dsc-disassemble") }}
:::
::::
### COFF Support
The {sub-ref}`lief-coff-Binary` interface does not inherit from the generic {sub-ref}`lief-abstract-binary`,
but it also exposes an API to disassemble code in COFF object files: {sub-ref}`lief-coff-binary-disassemble`.
For more details, please check the {ref}`COFF Disassembler <format-coff-disassembler>` section
### In-Memory Disassembler
The disassembler is also available for analyzing code directly in the memory of
the running process. This functionality is exposed through the runtime API
{sub-ref}`lief-runtime-disassemble`, as detailed in the {ref}`Runtime Memory <runtime_memory>`
documentation.
## Technical Details
The disassembler is based on LLVM's MC layer, which is known to be efficient and
accurate for disassembling code. This LLVM MC layer is already used by
other projects like [capstone](https://www.capstone-engine.org/) or, more
recently, [Nyxstone](https://github.com/emproof-com/nyxstone).
Compared to Capstone, LIEF uses a mainstream LLVM version with limited
modifications to the MC layer. On the other hand, it does not expose a C API,
supports fewer architectures than Capstone, and does not expose a standalone API.
:::{note}
The current LLVM version is {sub-ref}`lief-llvm-version`.
:::
Unlike Nyxstone's disassembler, LIEF hides LLVM from the public API,
meaning that LLVM does not need to be installed on the system.
On the other hand, it does not expose a standalone API.
The major difference between LIEF's disassembler and other projects is that
it **does not expose a standalone API** for disassembling arbitrary code.
The disassembler is bound to the object from which the API is
exposed ({sub-ref}`lief-abstract-binary`, {sub-ref}`lief-dwarf-function`,
{sub-ref}`lief-dsc-dyldsharedcache-disassemble`, etc.).
{fa}`brands fa-python` {doc}`Python API <python/index>`
{fa}`regular fa-file-code` {doc}`C++ API <cpp/index>`
{fa}`brands fa-rust` Rust API: {rust:module}`lief::assembly`
{{ cross_api }}
-291
View File
@@ -1,291 +0,0 @@
.. _extended-disassembler:
:fa:`solid fa-dna` Disassembler
-------------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp/index
python/index
rust
----
Introduction
************
LIEF Extended provides a user-friendly API for disassembling code within various
parts of executable formats for the following architectures:
x86/x86-64, ARM, AArch64, RISC-V, MIPS, PowerPC, and eBPF.
You can begin disassembling code within a binary using the |lief-disassemble|
function, which is exposed in the abstraction layer:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/disassembler.cpp
:language: cpp
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/disassembler.rs
:language: rust
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
From a design perspective, the disassembler returns a *lazy* iterator,
yielding a |lief-asm-instruction| instance as it evaluates the
instruction at each address.
Consequently, when calling ``elf.disassemble_address(0x400)``, no disassembly
occurs until the iterator is advanced.
Instructions are represented by the |lief-asm-instruction| object,
which is extended by architecture-specific objects:
- |lief-asm-x86-instruction|
- |lief-asm-arm-instruction|
- |lief-asm-aarch64-instruction|
- |lief-asm-powerpc-instruction|
- |lief-asm-mips-instruction|
- |lief-asm-riscv-instruction|
- |lief-asm-ebpf-instruction|
In Python, you can check the effective type of
a :class:`lief.assembly.Instruction` with ``isinstance(...)``:
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:start-after: lief-doc: downcast-start
:end-before: lief-doc: downcast-end
:dedent:
In C++, downcasting is performed using the function:
:cpp:func:`LIEF::assembly::Instruction::as`:
.. literalinclude:: ../../../code/cpp/disassembler.cpp
:language: cpp
:start-after: lief-doc: downcast-start
:end-before: lief-doc: downcast-end
:dedent:
In Rust, instructions are represented by the enum :rust:enum:`lief::assembly::Instructions`.
Thus, you can write:
.. literalinclude:: ../../../code/rust/src/disassembler.rs
:language: rust
:start-after: lief-doc: downcast-start
:end-before: lief-doc: downcast-end
:dedent:
.. note::
You can also check the assembler documentation here: :ref:`Assembler <extended-assembler>`
For the ``x86/x86-64`` and ``AArch64`` architectures, you can also iterate
over an instruction's operands:
.. tabs::
.. tab:: :fa:`solid fa-microchip` AArch64
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:prepend: import lief
:start-after: lief-doc: operands-aarch64-start
:end-before: lief-doc: operands-aarch64-end
:dedent:
.. tab:: :fa:`solid fa-microchip` x86/x86-64
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:prepend: import lief
:start-after: lief-doc: operands-x86-start
:end-before: lief-doc: operands-x86-end
:dedent:
You can check the documentation of these architectures for more details about
the exposed API.
x86/x86-64
**********
On x86/x86-64, |lief-asm-x86-instruction| also exposes an API to inspect and
rewrite the ``LOCK`` prefix of an instruction:
- |lief-assembly-x86-Instruction-has_lock_prefix|
- |lief-assembly-x86-Instruction-is_lockable|
- |lief-assembly-x86-Instruction-is_atomic|
- |lief-assembly-x86-Instruction-lock|
- |lief-assembly-x86-Instruction-unlock|
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:prepend: import lief
:start-after: lief-doc: x86-lock-start
:end-before: lief-doc: x86-lock-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/disassembler.cpp
:language: cpp
:start-after: lief-doc: x86-lock-start
:end-before: lief-doc: x86-lock-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/disassembler.rs
:language: rust
:start-after: lief-doc: x86-lock-start
:end-before: lief-doc: x86-lock-end
:dedent:
Use Cases
*********
DWARF Function
~~~~~~~~~~~~~~
In addition to the regular |lief-disassemble| API, you can use
|lief-dwarf-function-instructions| to disassemble a :ref:`DWARF <extended-dwarf>`
function.
.. warning::
|lief-dwarf-function-instructions| only works if the DWARF debug info
is **embedded** in the binary. This is the default behavior for
:ref:`ELF <format-elf>` binaries, but this is not the case for Mach-O
``.dSYM`` files.
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:prepend: import lief
:start-after: lief-doc: dwarf-func-start
:end-before: lief-doc: dwarf-func-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/disassembler.cpp
:language: cpp
:start-after: lief-doc: dwarf-func-start
:end-before: lief-doc: dwarf-func-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/disassembler.rs
:language: rust
:start-after: lief-doc: dwarf-func-start
:end-before: lief-doc: dwarf-func-end
:dedent:
Dyld Shared Cache
~~~~~~~~~~~~~~~~~
A disassembly API is also provided for the |lief-dsc-dyldsharedcache| object
via |lief-dsc-dyldsharedcache-disassemble|:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/disassembler.py
:language: python
:start-after: lief-doc: dsc-disassemble-start
:end-before: lief-doc: dsc-disassemble-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/disassembler.cpp
:language: cpp
:start-after: lief-doc: dsc-disassemble-start
:end-before: lief-doc: dsc-disassemble-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/disassembler.rs
:language: rust
:start-after: lief-doc: dsc-disassemble-start
:end-before: lief-doc: dsc-disassemble-end
:dedent:
COFF Support
~~~~~~~~~~~~
The |lief-coff-Binary| interface does not inherit from the generic |lief-abstract-binary|,
but it also exposes an API to disassemble code in COFF object files: |lief-coff-binary-disassemble|.
For more details, please check the :ref:`COFF Disassembler <format-coff-disassembler>` section
In-Memory Disassembler
~~~~~~~~~~~~~~~~~~~~~~
The disassembler is also available for analyzing code directly in the memory of
the running process. This functionality is exposed through the runtime API
|lief-runtime-disassemble|, as detailed in the :ref:`Runtime Memory <runtime_memory>`
documentation.
Technical Details
*****************
The disassembler is based on LLVM's MC layer, which is known to be efficient and
accurate for disassembling code. This LLVM MC layer is already used by
other projects like `capstone <https://www.capstone-engine.org/>`_ or, more
recently, `Nyxstone <https://github.com/emproof-com/nyxstone>`_.
Compared to Capstone, LIEF uses a mainstream LLVM version with limited
modifications to the MC layer. On the other hand, it does not expose a C API,
supports fewer architectures than Capstone, and does not expose a standalone API.
.. note::
The current LLVM version is |lief-llvm-version|.
Unlike Nyxstone's disassembler, LIEF hides LLVM from the public API,
meaning that LLVM does not need to be installed on the system.
On the other hand, it does not expose a standalone API.
The major difference between LIEF's disassembler and other projects is that
it **does not expose a standalone API** for disassembling arbitrary code.
The disassembler is bound to the object from which the API is
exposed (|lief-abstract-binary|, |lief-dwarf-function|,
|lief-dsc-dyldsharedcache-disassemble|, etc.).
:fa:`brands fa-python` :doc:`Python API <python/index>`
:fa:`regular fa-file-code` :doc:`C++ API <cpp/index>`
:fa:`brands fa-rust` Rust API: :rust:module:`lief::assembly`
.. include:: ../../_cross_api.rst
@@ -1,62 +1,77 @@
:fa:`solid fa-microchip` AArch64
--------------------------------
# {fa}`solid fa-microchip` AArch64
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.aarch64.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.aarch64.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.aarch64.OPCODE``
See: `lief.assembly.aarch64.OPCODE`
## Operands
Operands
********
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.aarch64.Operand
:top-classes: lief._lief.assembly.aarch64.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.aarch64.Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.aarch64.operands.Immediate
:top-classes: lief._lief.assembly.aarch64.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.aarch64.operands.Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.aarch64.operands.Register
:top-classes: lief._lief.assembly.aarch64.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.aarch64.operands.Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.aarch64.operands.Memory
:top-classes: lief._lief.assembly.aarch64.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.aarch64.operands.Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.aarch64.operands.PCRelative
:top-classes: lief._lief.assembly.aarch64.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.aarch64.operands.PCRelative
```
@@ -1,16 +1,17 @@
:fa:`solid fa-microchip` ARM
----------------------------
# {fa}`solid fa-microchip` ARM
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.arm.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.arm.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.arm.OPCODE``
See: `lief.assembly.arm.OPCODE`
@@ -1,62 +1,77 @@
:fa:`solid fa-microchip` eBPF
-----------------------------
# {fa}`solid fa-microchip` eBPF
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.ebpf.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.ebpf.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.ebpf.OPCODE``
See: `lief.assembly.ebpf.OPCODE`
## Operands
Operands
********
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.ebpf.Operand
:top-classes: lief._lief.assembly.ebpf.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.ebpf.Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.ebpf.operands.Immediate
:top-classes: lief._lief.assembly.ebpf.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.ebpf.operands.Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.ebpf.operands.Register
:top-classes: lief._lief.assembly.ebpf.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.ebpf.operands.Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.ebpf.operands.Memory
:top-classes: lief._lief.assembly.ebpf.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.ebpf.operands.Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.ebpf.operands.PCRelative
:top-classes: lief._lief.assembly.ebpf.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.ebpf.operands.PCRelative
```
@@ -1,62 +1,77 @@
:fa:`solid fa-microchip` Mips
-----------------------------
# {fa}`solid fa-microchip` Mips
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.mips.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.mips.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.mips.OPCODE``
See: `lief.assembly.mips.OPCODE`
## Operands
Operands
********
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.mips.Operand
:top-classes: lief._lief.assembly.mips.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.mips.Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.mips.operands.Immediate
:top-classes: lief._lief.assembly.mips.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.mips.operands.Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.mips.operands.Register
:top-classes: lief._lief.assembly.mips.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.mips.operands.Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.mips.operands.Memory
:top-classes: lief._lief.assembly.mips.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.mips.operands.Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.mips.operands.PCRelative
:top-classes: lief._lief.assembly.mips.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.mips.operands.PCRelative
```
@@ -1,62 +1,77 @@
:fa:`solid fa-microchip` PowerPC
--------------------------------
# {fa}`solid fa-microchip` PowerPC
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.powerpc.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.powerpc.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.powerpc.OPCODE``
See: `lief.assembly.powerpc.OPCODE`
## Operands
Operands
********
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.powerpc.Operand
:top-classes: lief._lief.assembly.powerpc.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.powerpc.Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.powerpc.operands.Immediate
:top-classes: lief._lief.assembly.powerpc.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.powerpc.operands.Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.powerpc.operands.Register
:top-classes: lief._lief.assembly.powerpc.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.powerpc.operands.Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.powerpc.operands.Memory
:top-classes: lief._lief.assembly.powerpc.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.powerpc.operands.Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.powerpc.operands.PCRelative
:top-classes: lief._lief.assembly.powerpc.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.powerpc.operands.PCRelative
```
@@ -1,62 +1,77 @@
:fa:`solid fa-microchip` RISC-V
--------------------------------
# {fa}`solid fa-microchip` RISC-V
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.riscv.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.riscv.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.riscv.OPCODE``
See: `lief.assembly.riscv.OPCODE`
## Operands
Operands
********
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.riscv.Operand
:top-classes: lief._lief.assembly.riscv.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.riscv.Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.riscv.operands.Immediate
:top-classes: lief._lief.assembly.riscv.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.riscv.operands.Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.riscv.operands.Register
:top-classes: lief._lief.assembly.riscv.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.riscv.operands.Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.riscv.operands.Memory
:top-classes: lief._lief.assembly.riscv.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.riscv.operands.Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.riscv.operands.PCRelative
:top-classes: lief._lief.assembly.riscv.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.riscv.operands.PCRelative
```
@@ -1,61 +1,77 @@
:fa:`solid fa-microchip` x86/x86-64
-----------------------------------
# {fa}`solid fa-microchip` x86/x86-64
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.x86.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.x86.Instruction
```
Opcodes
*******
## Opcodes
See: ``lief.assembly.x86.OPCODE``
See: `lief.assembly.x86.OPCODE`
Operands
********
## Operands
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.x86.Operand
:top-classes: lief._lief.assembly.x86.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.x86.Operand
```
Immediate
~~~~~~~~~
### Immediate
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.x86.operands.Immediate
:top-classes: lief._lief.assembly.x86.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.x86.operands.Immediate
```
Register
~~~~~~~~
### Register
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.x86.operands.Register
:top-classes: lief._lief.assembly.x86.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.x86.operands.Register
```
Memory
~~~~~~
### Memory
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.x86.operands.Memory
:top-classes: lief._lief.assembly.x86.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.x86.operands.Memory
```
PCRelative
~~~~~~~~~~
### PCRelative
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.x86.operands.PCRelative
:top-classes: lief._lief.assembly.x86.Operand
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.x86.operands.PCRelative
```
@@ -1,9 +1,8 @@
:fa:`brands fa-python` Python
------------------------------
# {fa}`brands fa-python` Python
Architectures
*************
## Architectures
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-microchip">&nbsp;</i>Architectures
:maxdepth: 1
@@ -15,18 +14,22 @@ Architectures
arch/riscv
arch/mips
arch/powerpc
```
Engine
******
## Engine
```{eval-rst}
.. autoclass:: lief.assembly.Engine
```
Instruction
************
## Instruction
```{eval-rst}
.. lief-inheritance:: lief._lief.assembly.Instruction
:top-classes: lief._lief.assembly.Instruction
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.assembly.Instruction
```
+5
View File
@@ -0,0 +1,5 @@
# {fa}`brands fa-rust` Rust
:::{note}
Please check: {rust:module}`lief::assembly`
:::
@@ -1,6 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
.. note::
Please check: :rust:module:`lief::assembly`
@@ -1,57 +1,72 @@
:fa:`regular fa-file-code` C++
--------------------------------
# {fa}`regular fa-file-code` C++
.. note::
You can also find the Doxygen documentation here: `here <../../doxygen/>`_
:::{note}
You can also find the Doxygen documentation here: [here](../../doxygen/)
:::
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::load(const std::string &path, const std::string &arch = "")
```
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::load(const std::vector<std::string> &files)
```
Cache Processing
****************
## Cache Processing
.. warning::
If you aim at extracting several libraries from a dyld shared cache, it is
**highly** recommended to enable caching. Otherwise, performances can be
impacted.
:::{warning}
If you aim at extracting several libraries from a dyld shared cache, it is
**highly** recommended to enable caching. Otherwise, performances can be
impacted.
:::
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::enable_cache()
```
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::enable_cache(const std::string &dir)
```
DyldSharedCache
***************
## DyldSharedCache
```{eval-rst}
.. doxygenclass:: LIEF::dsc::DyldSharedCache
```
Dylib
*****
## Dylib
```{eval-rst}
.. doxygenclass:: LIEF::dsc::Dylib
```
MappingInfo
***********
## MappingInfo
```{eval-rst}
.. doxygenclass:: LIEF::dsc::MappingInfo
```
SubCache
********
## SubCache
```{eval-rst}
.. doxygenclass:: LIEF::dsc::SubCache
```
Utilities
*********
## Utilities
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::is_shared_cache(BinaryStream&)
```
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::is_shared_cache(const std::vector< uint8_t > &)
```
```{eval-rst}
.. doxygenfunction:: LIEF::dsc::is_shared_cache(const uint8_t *, size_t)
```
+173
View File
@@ -0,0 +1,173 @@
(extended-dsc)=
# {fa}`solid fa-diagram-predecessor` Dyld Shared Cache
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
```
## Introduction
LIEF's Dyld shared cache support enables the inspection and extraction of
libraries from the Apple Dyld shared cache.
One can load a shared cache using the {sub-ref}`lief-dsc-load` function:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dsc.py", "load", prepend="import lief") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dsc.cpp", "load", prepend="#include <LIEF/DyldSharedCache.hpp>") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dsc.rs", "load") }}
:::
::::
:::{warning}
{sub-ref}`lief-dsc-load` takes as input either a directory for loading the **whole**
shared cache or a set of files to load a subset of the cache.
:::
From this {sub-ref}`lief-dsc-dyldsharedcache` object, we can inspect the embedded
{sub-ref}`lief-dsc-dylib` as follows:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dsc.py", "libraries") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dsc.cpp", "libraries") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dsc.rs", "libraries") }}
:::
::::
It is worth mentioning that {sub-ref}`lief-dsc-dylib` exposes the {sub-ref}`lief-dsc-dylib-get`
method, which can be used to **extract** a {sub-ref}`lief-macho-binary` instance from
Dyld shared cache libraries:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dsc.py", "extract") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dsc.cpp", "extract") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dsc.rs", "extract") }}
:::
::::
Finally, we can leverage the {sub-ref}`lief-macho-binary-write` function to write back
the {sub-ref}`lief-macho-binary` object:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dsc.py", "write") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dsc.cpp", "write") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dsc.rs", "write") }}
:::
::::
:::{warning}
By default, LIEF **does not** remove Dyld shared cache optimizations.
To remove some of these optimizations, you can check the {sub-ref}`lief-dsc-dylib-eopt`
structure.
:::
## {fa}`solid fa-stopwatch` Performance Considerations
Dyld shared cache files are quite large, meaning they cannot be processed in
the same way as standard {sub-ref}`lief-macho-binary` or {sub-ref}`lief-elf-binary` binaries.
The Dyld shared cache support in LIEF follows the principle:
*don't pay overhead for what you don't access*. This is the opposite of the
implementation of {sub-ref}`lief-pe-parse`, {sub-ref}`lief-macho-parse`, and {sub-ref}`lief-elf-parse`.
:::{note}
These functions parse all format structures (with decent performance)
because:
1. Most binary sizes are less than one gigabyte.
2. A complete representation is required for modifying binaries.
:::
From a technical perspective, LIEF uses a {cpp:class}`LIEF::FileStream` to
access Dyld shared cache structures on demand. Thus, in-memory consumption
is limited to the size of the structures being accessed. The drawback of
using {cpp:class}`~LIEF::FileStream` is that because it uses file-based access,
it takes more time compared to a {cpp:class}`LIEF::VectorStream`.
Additionally, LIEF's Dyld shared cache implementation **heavily** relies on
the iterator pattern to follow the principle: *don't pay overhead for what you don't access*.
For instance, {sub-ref}`lief-dsc-dyldsharedcache-libraries` returns an **iterator**
over the {sub-ref}`lief-dsc-dylib`. Therefore, if you don't iterate, you don't pay for the
access and parsing of the {sub-ref}`lief-dsc-dylib` objects.
Where possible, LIEF implements the random access iterator trait [^footnote-1]
so that we can programmatically do:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dsc.py", "random-access") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dsc.cpp", "random-access") }}
:::
::::
When extracting a {sub-ref}`lief-macho-binary` from a {sub-ref}`lief-dsc-dylib` object using
{sub-ref}`lief-dsc-dylib-get`, **the extraction can take a substantial amount of time**,
especially if certain deoptimizations are enabled (c.f. {sub-ref}`lief-dsc-dylib-eopt`).
For instance, {sub-ref}`lief-dsc-dylib-eopt-fix_branches` may require iterating over the
Dyld shared cache's stub islands several times. To improve overall performance,
LIEF provides a cache-based optimization that can be enabled and configured with:
- {sub-ref}`lief-dsc-enable_cache`
- {sub-ref}`lief-dsc-dyldsharedcache-enable_caching`
:::{admonition} When should you turn caching on?
:class: warning
You can **skip** LIEF's caching if:
- You don't plan to extract libraries from the shared cache.
- You plan to extract only one library from the shared cache and **only once**
- You don't want to have LIEF cache artifacts on your system.
For all other situations, you should turn on {sub-ref}`lief-dsc-enable_cache`.
**By default, the cache mechanism is not enabled.**
:::
[^footnote-1]: <https://en.cppreference.com/w/cpp/iterator/random_access_iterator>
## {fa}`solid fa-book-open-reader` References
- {github-ref}`arandomdev/DyldExtractor`
- {github-ref}`blacktop/ipsw`
- {github-ref}`apple-oss-distributions/dyld`
- <https://www.romainthomas.fr/post/24-09-apple-lockdown-dbi-lifting/>
{fa}`brands fa-python` {doc}`Python API <python>`
{fa}`regular fa-file-code` {doc}`C++ API <cpp>`
{fa}`brands fa-rust` Rust API: {rust:module}`lief::dsc`
{{ cross_api }}
-244
View File
@@ -1,244 +0,0 @@
.. _extended-dsc:
:fa:`solid fa-diagram-predecessor` Dyld Shared Cache
-----------------------------------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
----
Introduction
************
LIEF's Dyld shared cache support enables the inspection and extraction of
libraries from the Apple Dyld shared cache.
One can load a shared cache using the |lief-dsc-load| function:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dsc.py
:language: python
:prepend: import lief
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dsc.cpp
:language: cpp
:prepend: #include <LIEF/DyldSharedCache.hpp>
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dsc.rs
:language: rust
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. warning::
|lief-dsc-load| takes as input either a directory for loading the **whole**
shared cache or a set of files to load a subset of the cache.
From this |lief-dsc-dyldsharedcache| object, we can inspect the embedded
|lief-dsc-dylib| as follows:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dsc.py
:language: python
:start-after: lief-doc: libraries-start
:end-before: lief-doc: libraries-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dsc.cpp
:language: cpp
:start-after: lief-doc: libraries-start
:end-before: lief-doc: libraries-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dsc.rs
:language: rust
:start-after: lief-doc: libraries-start
:end-before: lief-doc: libraries-end
:dedent:
It is worth mentioning that |lief-dsc-dylib| exposes the |lief-dsc-dylib-get|
method, which can be used to **extract** a |lief-macho-binary| instance from
Dyld shared cache libraries:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dsc.py
:language: python
:start-after: lief-doc: extract-start
:end-before: lief-doc: extract-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dsc.cpp
:language: cpp
:start-after: lief-doc: extract-start
:end-before: lief-doc: extract-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dsc.rs
:language: rust
:start-after: lief-doc: extract-start
:end-before: lief-doc: extract-end
:dedent:
Finally, we can leverage the |lief-macho-binary-write| function to write back
the |lief-macho-binary| object:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dsc.py
:language: python
:start-after: lief-doc: write-start
:end-before: lief-doc: write-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dsc.cpp
:language: cpp
:start-after: lief-doc: write-start
:end-before: lief-doc: write-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dsc.rs
:language: rust
:start-after: lief-doc: write-start
:end-before: lief-doc: write-end
:dedent:
.. warning::
By default, LIEF **does not** remove Dyld shared cache optimizations.
To remove some of these optimizations, you can check the |lief-dsc-dylib-eopt|
structure.
:fa:`solid fa-stopwatch` Performance Considerations
****************************************************
Dyld shared cache files are quite large, meaning they cannot be processed in
the same way as standard |lief-macho-binary| or |lief-elf-binary| binaries.
The Dyld shared cache support in LIEF follows the principle:
*don't pay overhead for what you don't access*. This is the opposite of the
implementation of |lief-pe-parse|, |lief-macho-parse|, and |lief-elf-parse|.
.. note::
These functions parse all format structures (with decent performance)
because:
1. Most binary sizes are less than one gigabyte.
2. A complete representation is required for modifying binaries.
From a technical perspective, LIEF uses a :cpp:class:`LIEF::FileStream` to
access Dyld shared cache structures on demand. Thus, in-memory consumption
is limited to the size of the structures being accessed. The drawback of
using :cpp:class:`~LIEF::FileStream` is that because it uses file-based access,
it takes more time compared to a :cpp:class:`LIEF::VectorStream`.
Additionally, LIEF's Dyld shared cache implementation **heavily** relies on
the iterator pattern to follow the principle: *don't pay overhead for what you don't access*.
For instance, |lief-dsc-dyldsharedcache-libraries| returns an **iterator**
over the |lief-dsc-dylib|. Therefore, if you don't iterate, you don't pay for the
access and parsing of the |lief-dsc-dylib| objects.
Where possible, LIEF implements the random access iterator trait [1]_
so that we can programmatically do:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dsc.py
:language: python
:start-after: lief-doc: random-access-start
:end-before: lief-doc: random-access-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dsc.cpp
:language: cpp
:start-after: lief-doc: random-access-start
:end-before: lief-doc: random-access-end
:dedent:
When extracting a |lief-macho-binary| from a |lief-dsc-dylib| object using
|lief-dsc-dylib-get|, **the extraction can take a substantial amount of time**,
especially if certain deoptimizations are enabled (c.f. |lief-dsc-dylib-eopt|).
For instance, |lief-dsc-dylib-eopt-fix_branches| may require iterating over the
Dyld shared cache's stub islands several times. To improve overall performance,
LIEF provides a cache-based optimization that can be enabled and configured with:
- |lief-dsc-enable_cache|
- |lief-dsc-dyldsharedcache-enable_caching|
.. admonition:: When should you turn caching on?
:class: warning
You can **skip** LIEF's caching if:
- You don't plan to extract libraries from the shared cache.
- You plan to extract only one library from the shared cache and **only once**
- You don't want to have LIEF cache artifacts on your system.
For all other situations, you should turn on |lief-dsc-enable_cache|.
**By default, the cache mechanism is not enabled.**
.. [1] https://en.cppreference.com/w/cpp/iterator/random_access_iterator
:fa:`solid fa-book-open-reader` References
*******************************************
- :github-ref:`arandomdev/DyldExtractor`
- :github-ref:`blacktop/ipsw`
- :github-ref:`apple-oss-distributions/dyld`
- https://www.romainthomas.fr/post/24-09-apple-lockdown-dbi-lifting/
:fa:`brands fa-python` :doc:`Python API <python>`
:fa:`regular fa-file-code` :doc:`C++ API <cpp>`
:fa:`brands fa-rust` Rust API: :rust:module:`lief::dsc`
.. include:: ../../_cross_api.rst
+48
View File
@@ -0,0 +1,48 @@
# {fa}`brands fa-python` Python
```{eval-rst}
.. autofunction:: lief.dsc.load
```
## Cache Processing
:::{warning}
If you aim at extracting several libraries from a dyld shared cache, it is
**highly** recommended to enable caching. Otherwise, performances can be
impacted.
:::
```{eval-rst}
.. autofunction:: lief.dsc.enable_cache
```
## DyldSharedCache
```{eval-rst}
.. autoclass:: lief.dsc.DyldSharedCache
```
## Dylib
```{eval-rst}
.. autoclass:: lief.dsc.Dylib
```
## MappingInfo
```{eval-rst}
.. autoclass:: lief.dsc.MappingInfo
```
## SubCache
```{eval-rst}
.. autoclass:: lief.dsc.SubCache
```
## Utilities
```{eval-rst}
.. autofunction:: lief.is_shared_cache
```
-41
View File
@@ -1,41 +0,0 @@
:fa:`brands fa-python` Python
------------------------------
.. autofunction:: lief.dsc.load
Cache Processing
****************
.. warning::
If you aim at extracting several libraries from a dyld shared cache, it is
**highly** recommended to enable caching. Otherwise, performances can be
impacted.
.. autofunction:: lief.dsc.enable_cache
DyldSharedCache
***************
.. autoclass:: lief.dsc.DyldSharedCache
Dylib
*****
.. autoclass:: lief.dsc.Dylib
MappingInfo
***********
.. autoclass:: lief.dsc.MappingInfo
SubCache
********
.. autoclass:: lief.dsc.SubCache
Utilities
*********
.. autofunction:: lief.is_shared_cache
+5
View File
@@ -0,0 +1,5 @@
# {fa}`brands fa-rust` Rust
:::{note}
Please check: {rust:module}`lief::dsc`
:::
-6
View File
@@ -1,6 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
.. note::
Please check: :rust:module:`lief::dsc`
+420
View File
@@ -0,0 +1,420 @@
# {fa}`regular fa-file-code` C++
:::{note}
You can also find the Doxygen documentation here: [here](../../doxygen/)
:::
```{eval-rst}
.. doxygenfunction:: LIEF::dwarf::load
```
## DebugInfo
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::DebugInfo
```
______________________________________________________________________
## CompilationUnit
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::CompilationUnit
```
______________________________________________________________________
## Function
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::Function
```
______________________________________________________________________
## Parameter
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::Parameter
```
______________________________________________________________________
## Formal Parameter
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::parameters::Formal
```
______________________________________________________________________
## Template Value Parameter
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::parameters::TemplateValue
```
______________________________________________________________________
## Template Type Parameter
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::parameters::TemplateType
```
______________________________________________________________________
## Scope
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::Scope
```
______________________________________________________________________
## Variable
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::Variable
```
______________________________________________________________________
## LexicalBlock
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::LexicalBlock
```
______________________________________________________________________
## Type
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::Type
```
______________________________________________________________________
## Array
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Array
```
______________________________________________________________________
## Base
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Base
```
______________________________________________________________________
## ClassLike
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::ClassLike
```
______________________________________________________________________
## Structure
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Structure
```
______________________________________________________________________
## Class
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Class
```
______________________________________________________________________
## Union
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Union
```
______________________________________________________________________
## Packed
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Packed
```
______________________________________________________________________
## Const
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Const
```
______________________________________________________________________
## Pointer
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Pointer
```
______________________________________________________________________
## Typedef
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Typedef
```
______________________________________________________________________
## Atomic
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Atomic
```
______________________________________________________________________
## Coarray
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Coarray
```
______________________________________________________________________
## Dynamic
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Dynamic
```
______________________________________________________________________
## Enum
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Enum
```
______________________________________________________________________
## File
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::File
```
______________________________________________________________________
## Immutable
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Immutable
```
______________________________________________________________________
## Interface
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Interface
```
______________________________________________________________________
## PointerToMember
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::PointerToMember
```
______________________________________________________________________
## RValueReference
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::RValueReference
```
______________________________________________________________________
## Reference
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Reference
```
______________________________________________________________________
## Restrict
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Restrict
```
______________________________________________________________________
## SetTy
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::SetTy
```
______________________________________________________________________
## Shared
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Shared
```
______________________________________________________________________
## StringTy
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::StringTy
```
______________________________________________________________________
## Subroutine
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Subroutine
```
______________________________________________________________________
## TemplateAlias
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::TemplateAlias
```
______________________________________________________________________
## Thrown
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Thrown
```
______________________________________________________________________
## Volatile
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::types::Volatile
```
______________________________________________________________________
## Editor
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::Editor
```
______________________________________________________________________
## Editor - CompilationUnit
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::CompilationUnit
```
______________________________________________________________________
## Editor - Function
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::Function
```
______________________________________________________________________
## Editor - Variable
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::Variable
```
______________________________________________________________________
## Editor - Type
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::Type
```
______________________________________________________________________
## Editor - PointerType
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::PointerType
```
______________________________________________________________________
## Editor - EnumType
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::EnumType
```
______________________________________________________________________
## Editor - BaseType
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::BaseType
```
______________________________________________________________________
## Editor - ArrayType
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::ArrayType
```
______________________________________________________________________
## Editor - FunctionType
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::FunctionType
```
______________________________________________________________________
## Editor - TypeDef
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::TypeDef
```
______________________________________________________________________
## Editor - StructType
```{eval-rst}
.. doxygenclass:: LIEF::dwarf::editor::StructType
```
-376
View File
@@ -1,376 +0,0 @@
:fa:`regular fa-file-code` C++
--------------------------------
.. note::
You can also find the Doxygen documentation here: `here <../../doxygen/>`_
.. doxygenfunction:: LIEF::dwarf::load
DebugInfo
*********
.. doxygenclass:: LIEF::dwarf::DebugInfo
----------
CompilationUnit
***************
.. doxygenclass:: LIEF::dwarf::CompilationUnit
----------
Function
********
.. doxygenclass:: LIEF::dwarf::Function
----------
Parameter
*********
.. doxygenclass:: LIEF::dwarf::Parameter
----------
Formal Parameter
****************
.. doxygenclass:: LIEF::dwarf::parameters::Formal
----------
Template Value Parameter
************************
.. doxygenclass:: LIEF::dwarf::parameters::TemplateValue
----------
Template Type Parameter
************************
.. doxygenclass:: LIEF::dwarf::parameters::TemplateType
----------
Scope
******
.. doxygenclass:: LIEF::dwarf::Scope
----------
Variable
********
.. doxygenclass:: LIEF::dwarf::Variable
----------
LexicalBlock
************
.. doxygenclass:: LIEF::dwarf::LexicalBlock
----------
Type
****
.. doxygenclass:: LIEF::dwarf::Type
----------
Array
*****
.. doxygenclass:: LIEF::dwarf::types::Array
----------
Base
****
.. doxygenclass:: LIEF::dwarf::types::Base
----------
ClassLike
**********
.. doxygenclass:: LIEF::dwarf::types::ClassLike
----------
Structure
*********
.. doxygenclass:: LIEF::dwarf::types::Structure
----------
Class
*****
.. doxygenclass:: LIEF::dwarf::types::Class
----------
Union
*****
.. doxygenclass:: LIEF::dwarf::types::Union
----------
Packed
******
.. doxygenclass:: LIEF::dwarf::types::Packed
----------
Const
*****
.. doxygenclass:: LIEF::dwarf::types::Const
----------
Pointer
*******
.. doxygenclass:: LIEF::dwarf::types::Pointer
----------
Typedef
*******
.. doxygenclass:: LIEF::dwarf::types::Typedef
----------
Atomic
******
.. doxygenclass:: LIEF::dwarf::types::Atomic
----------
Coarray
*******
.. doxygenclass:: LIEF::dwarf::types::Coarray
----------
Dynamic
*******
.. doxygenclass:: LIEF::dwarf::types::Dynamic
----------
Enum
****
.. doxygenclass:: LIEF::dwarf::types::Enum
----------
File
****
.. doxygenclass:: LIEF::dwarf::types::File
----------
Immutable
*********
.. doxygenclass:: LIEF::dwarf::types::Immutable
----------
Interface
*********
.. doxygenclass:: LIEF::dwarf::types::Interface
----------
PointerToMember
***************
.. doxygenclass:: LIEF::dwarf::types::PointerToMember
----------
RValueReference
***************
.. doxygenclass:: LIEF::dwarf::types::RValueReference
----------
Reference
*********
.. doxygenclass:: LIEF::dwarf::types::Reference
----------
Restrict
********
.. doxygenclass:: LIEF::dwarf::types::Restrict
----------
SetTy
******
.. doxygenclass:: LIEF::dwarf::types::SetTy
----------
Shared
******
.. doxygenclass:: LIEF::dwarf::types::Shared
----------
StringTy
********
.. doxygenclass:: LIEF::dwarf::types::StringTy
----------
Subroutine
**********
.. doxygenclass:: LIEF::dwarf::types::Subroutine
----------
TemplateAlias
*************
.. doxygenclass:: LIEF::dwarf::types::TemplateAlias
----------
Thrown
******
.. doxygenclass:: LIEF::dwarf::types::Thrown
----------
Volatile
********
.. doxygenclass:: LIEF::dwarf::types::Volatile
----------
Editor
******
.. doxygenclass:: LIEF::dwarf::Editor
----------
Editor - CompilationUnit
************************
.. doxygenclass:: LIEF::dwarf::editor::CompilationUnit
----------
Editor - Function
*****************
.. doxygenclass:: LIEF::dwarf::editor::Function
----------
Editor - Variable
*****************
.. doxygenclass:: LIEF::dwarf::editor::Variable
----------
Editor - Type
**************
.. doxygenclass:: LIEF::dwarf::editor::Type
----------
Editor - PointerType
********************
.. doxygenclass:: LIEF::dwarf::editor::PointerType
----------
Editor - EnumType
*****************
.. doxygenclass:: LIEF::dwarf::editor::EnumType
----------
Editor - BaseType
*****************
.. doxygenclass:: LIEF::dwarf::editor::BaseType
----------
Editor - ArrayType
******************
.. doxygenclass:: LIEF::dwarf::editor::ArrayType
----------
Editor - FunctionType
*********************
.. doxygenclass:: LIEF::dwarf::editor::FunctionType
----------
Editor - TypeDef
****************
.. doxygenclass:: LIEF::dwarf::editor::TypeDef
----------
Editor - StructType
*******************
.. doxygenclass:: LIEF::dwarf::editor::StructType
+197
View File
@@ -0,0 +1,197 @@
(extended-dwarf)=
# {fa}`solid fa-bars-staggered` DWARF
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
```
## Introduction
DWARF debug information can be embedded directly within a binary
(the default for ELF files) or stored in a separate, dedicated file.
When DWARF debug information is embedded within the binary,
you can access it using the {sub-ref}`lief-dwarf-binary-debug-info` attribute.
This attribute returns a {sub-ref}`lief-dwarf-debug-info` object:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "embedded", prepend="import lief") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "embedded") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "embedded") }}
:::
::::
Additionally, the {sub-ref}`lief-dwarf-load` function can be used to load a
DWARF file, whether it is embedded or standalone:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "load", prepend="import lief") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "load") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "load") }}
:::
::::
Once loaded, you can use the {sub-ref}`lief-dwarf-debug-info` API to interact with the
debug information:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "iterate") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "iterate") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "iterate") }}
:::
::::
(extended-dwarf-load-ext)=
In the case of an external DWARF file, you can bind this debug file to
a {sub-ref}`lief-abstract-binary` using the {sub-ref}`lief-abstract-binary-load_debug_info`
function.
Here's an example:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "load-external") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "load-external") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "load-external") }}
:::
::::
This external loading API is useful for adding debug information that might not
already be present in the binary. For instance, the {sub-ref}`lief-disassemble` function
can leverage this additional debug information to disassemble functions
defined in the debug file previously loaded:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "disassemble") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "disassemble") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "disassemble") }}
:::
::::
Additionally, you may also want to explore the
{ref}`BinaryNinja <plugins-binaryninja-dwarf>` and
{ref}`Ghidra <plugins-ghidra-dwarf>` DWARF export plugins, which generate
debug information based on the analyses performed by these frameworks.
(extended-dwarf-to-decl)=
## Generating C/C++ Definitions
DWARF functions, variables, types and compilation units can be turned back into
a C/C++ definition thanks to the `to_decl()` function:
- {sub-ref}`lief-dwarf-function-to_decl`
- {sub-ref}`lief-dwarf-variable-to_decl`
- {sub-ref}`lief-dwarf-type-to_decl`
- {sub-ref}`lief-dwarf-cu-to_decl`
The generated output can be configured with a {sub-ref}`lief-declopt` structure (e.g. to
prefer C++ syntax or change the indentation):
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "to-decl") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "to-decl") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "to-decl") }}
:::
::::
(extended-dwarf-editor)=
## DWARF Editor
:::{admonition} Editing Existing DWARF
:class: warning
LIEF does not currently support modifying an **existing** DWARF file.
:::
LIEF provides a comprehensive high-level API for programmatically creating
DWARF files. This works by using the {sub-ref}`lief-dwarf-editor` interface, which can be
instantiated using {sub-ref}`lief-dwarf-editor-from_binary`:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "editor-from-binary") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "editor-from-binary") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "editor-from-binary") }}
:::
::::
Given this {sub-ref}`lief-dwarf-editor`, you can create one or more
{sub-ref}`lief-dwarf-editor-CompilationUnit` entries, which own various
{sub-ref}`lief-dwarf-editor-Function`, {sub-ref}`lief-dwarf-editor-Variable`, and
{sub-ref}`lief-dwarf-editor-Type` objects.
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/dwarf.py", "editor-create") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/dwarf.cpp", "editor-create") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/dwarf.rs", "editor-create") }}
:::
::::
:::{admonition} BinaryNinja & Ghidra
:class: note
This feature is provided as a plugin for {ref}`BinaryNinja <plugins-binaryninja-dwarf>`
and {ref}`Ghidra <plugins-ghidra-dwarf>`.
:::
______________________________________________________________________
## API
You can find the documentation of the API for the different languages here:
{fa}`brands fa-python` {doc}`Python API <python>`
{fa}`regular fa-file-code` {doc}`C++ API <cpp>`
{fa}`brands fa-rust` Rust API: {rust:module}`lief::dwarf`
{{ cross_api }}
-316
View File
@@ -1,316 +0,0 @@
.. _extended-dwarf:
:fa:`solid fa-bars-staggered` DWARF
-----------------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
----
Introduction
************
DWARF debug information can be embedded directly within a binary
(the default for ELF files) or stored in a separate, dedicated file.
When DWARF debug information is embedded within the binary,
you can access it using the |lief-dwarf-binary-debug-info| attribute.
This attribute returns a |lief-dwarf-debug-info| object:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:prepend: import lief
:start-after: lief-doc: embedded-start
:end-before: lief-doc: embedded-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: embedded-start
:end-before: lief-doc: embedded-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: embedded-start
:end-before: lief-doc: embedded-end
:dedent:
Additionally, the |lief-dwarf-load| function can be used to load a
DWARF file, whether it is embedded or standalone:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:prepend: import lief
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
Once loaded, you can use the |lief-dwarf-debug-info| API to interact with the
debug information:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:start-after: lief-doc: iterate-start
:end-before: lief-doc: iterate-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: iterate-start
:end-before: lief-doc: iterate-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: iterate-start
:end-before: lief-doc: iterate-end
:dedent:
.. _extended-dwarf-load-ext:
In the case of an external DWARF file, you can bind this debug file to
a |lief-abstract-binary| using the |lief-abstract-binary-load_debug_info|
function.
Here's an example:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:start-after: lief-doc: load-external-start
:end-before: lief-doc: load-external-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: load-external-start
:end-before: lief-doc: load-external-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: load-external-start
:end-before: lief-doc: load-external-end
:dedent:
This external loading API is useful for adding debug information that might not
already be present in the binary. For instance, the |lief-disassemble| function
can leverage this additional debug information to disassemble functions
defined in the debug file previously loaded:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
Additionally, you may also want to explore the
:ref:`BinaryNinja <plugins-binaryninja-dwarf>` and
:ref:`Ghidra <plugins-ghidra-dwarf>` DWARF export plugins, which generate
debug information based on the analyses performed by these frameworks.
.. _extended-dwarf-to-decl:
Generating C/C++ Definitions
****************************
DWARF functions, variables, types and compilation units can be turned back into
a C/C++ definition thanks to the ``to_decl()`` function:
- |lief-dwarf-function-to_decl|
- |lief-dwarf-variable-to_decl|
- |lief-dwarf-type-to_decl|
- |lief-dwarf-cu-to_decl|
The generated output can be configured with a |lief-declopt| structure (e.g. to
prefer C++ syntax or change the indentation):
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:start-after: lief-doc: to-decl-start
:end-before: lief-doc: to-decl-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: to-decl-start
:end-before: lief-doc: to-decl-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: to-decl-start
:end-before: lief-doc: to-decl-end
:dedent:
.. _extended-dwarf-editor:
DWARF Editor
************
.. admonition:: Editing Existing DWARF
:class: warning
LIEF does not currently support modifying an **existing** DWARF file.
LIEF provides a comprehensive high-level API for programmatically creating
DWARF files. This works by using the |lief-dwarf-editor| interface, which can be
instantiated using |lief-dwarf-editor-from_binary|:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:start-after: lief-doc: editor-from-binary-start
:end-before: lief-doc: editor-from-binary-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: editor-from-binary-start
:end-before: lief-doc: editor-from-binary-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: editor-from-binary-start
:end-before: lief-doc: editor-from-binary-end
:dedent:
Given this |lief-dwarf-editor|, you can create one or more
|lief-dwarf-editor-CompilationUnit| entries, which own various
|lief-dwarf-editor-Function|, |lief-dwarf-editor-Variable|, and
|lief-dwarf-editor-Type| objects.
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/dwarf.py
:language: python
:start-after: lief-doc: editor-create-start
:end-before: lief-doc: editor-create-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/dwarf.cpp
:language: cpp
:start-after: lief-doc: editor-create-start
:end-before: lief-doc: editor-create-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/dwarf.rs
:language: rust
:start-after: lief-doc: editor-create-start
:end-before: lief-doc: editor-create-end
:dedent:
.. admonition:: BinaryNinja & Ghidra
:class: note
This feature is provided as a plugin for :ref:`BinaryNinja <plugins-binaryninja-dwarf>`
and :ref:`Ghidra <plugins-ghidra-dwarf>`.
----
API
****
You can find the documentation of the API for the different languages here:
:fa:`brands fa-python` :doc:`Python API <python>`
:fa:`regular fa-file-code` :doc:`C++ API <cpp>`
:fa:`brands fa-rust` Rust API: :rust:module:`lief::dwarf`
.. include:: ../../_cross_api.rst
@@ -1,530 +1,653 @@
:fa:`brands fa-python` Python
-----------------------------
# {fa}`brands fa-python` Python
```{eval-rst}
.. autofunction:: lief.dwarf.load
```
DebugInfo
**********
## DebugInfo
```{eval-rst}
.. autoclass:: lief.dwarf.DebugInfo
```
----------
______________________________________________________________________
CompilationUnit
***************
## CompilationUnit
```{eval-rst}
.. autoclass:: lief.dwarf.CompilationUnit
```
----------
______________________________________________________________________
Function
********
## Function
```{eval-rst}
.. autoclass:: lief.dwarf.Function
```
----------
______________________________________________________________________
Parameter
*********
## Parameter
```{eval-rst}
.. autoclass:: lief.dwarf.Parameter
```
----------
______________________________________________________________________
Formal Parameter
****************
## Formal Parameter
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.parameters.Formal
:top-classes: lief._lief.dwarf.Parameter
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.parameters.Formal
```
----------
______________________________________________________________________
Template Value Parameter
************************
## Template Value Parameter
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.parameters.TemplateValue
:top-classes: lief._lief.dwarf.Parameter
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.parameters.TemplateValue
```
----------
______________________________________________________________________
Template Type Parameter
***********************
## Template Type Parameter
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.parameters.TemplateType
:top-classes: lief._lief.dwarf.Parameter
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.parameters.TemplateType
```
----------
______________________________________________________________________
Scope
*****
## Scope
```{eval-rst}
.. autoclass:: lief.dwarf.Scope
```
----------
______________________________________________________________________
## Variable
Variable
********
```{eval-rst}
.. autoclass:: lief.dwarf.Variable
```
----------
______________________________________________________________________
LexicalBlock
************
## LexicalBlock
```{eval-rst}
.. autoclass:: lief.dwarf.LexicalBlock
```
----------
______________________________________________________________________
Type
****
## Type
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.Type
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.Type
```
----------
______________________________________________________________________
## Array
Array
*****
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Array
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Array
```
----------
______________________________________________________________________
## Base
Base
****
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Base
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Base
```
----------
______________________________________________________________________
## ClassLike
ClassLike
*********
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.ClassLike
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.ClassLike
```
----------
______________________________________________________________________
## Structure
Structure
*********
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Structure
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Structure
```
----------
______________________________________________________________________
## Class
Class
*****
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Class
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Class
```
----------
______________________________________________________________________
Union
*****
## Union
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Union
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Union
```
----------
______________________________________________________________________
## Packed
Packed
******
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Packed
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Packed
```
----------
______________________________________________________________________
## Const
Const
*****
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Const
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Const
```
----------
______________________________________________________________________
Pointer
*******
## Pointer
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Pointer
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Pointer
```
----------
______________________________________________________________________
Typedef
*******
## Typedef
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Typedef
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Typedef
```
----------
______________________________________________________________________
Atomic
******
## Atomic
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Atomic
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Atomic
```
----------
______________________________________________________________________
Coarray
*******
## Coarray
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Coarray
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Coarray
```
----------
______________________________________________________________________
Dynamic
*******
## Dynamic
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Dynamic
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Dynamic
```
----------
______________________________________________________________________
Enum
****
## Enum
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Enum
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Enum
```
----------
______________________________________________________________________
File
****
## File
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.File
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.File
```
----------
______________________________________________________________________
Immutable
*********
## Immutable
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Immutable
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Immutable
```
----------
______________________________________________________________________
Interface
*********
## Interface
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Interface
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Interface
```
----------
______________________________________________________________________
PointerToMember
***************
## PointerToMember
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.PointerToMember
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.PointerToMember
```
----------
______________________________________________________________________
RValueReference
***************
## RValueReference
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.RValueReference
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.RValueReference
```
----------
______________________________________________________________________
Reference
*********
## Reference
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Reference
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Reference
```
----------
______________________________________________________________________
Restrict
********
## Restrict
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Restrict
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Restrict
```
----------
______________________________________________________________________
SetTy
*****
## SetTy
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.SetTy
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.SetTy
```
----------
______________________________________________________________________
Shared
******
## Shared
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Shared
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Shared
```
----------
______________________________________________________________________
StringTy
********
## StringTy
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.StringTy
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.StringTy
```
----------
______________________________________________________________________
Subroutine
**********
## Subroutine
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Subroutine
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Subroutine
```
----------
______________________________________________________________________
TemplateAlias
*************
## TemplateAlias
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.TemplateAlias
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.TemplateAlias
```
----------
______________________________________________________________________
Thrown
******
## Thrown
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Thrown
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Thrown
```
----------
______________________________________________________________________
Volatile
********
## Volatile
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.types.Volatile
:top-classes: lief._lief.dwarf.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.types.Volatile
```
----------
______________________________________________________________________
Editor
******
## Editor
```{eval-rst}
.. autoclass:: lief.dwarf.Editor
```
----------
______________________________________________________________________
Editor - CompilationUnit
************************
## Editor - CompilationUnit
```{eval-rst}
.. autoclass:: lief.dwarf.editor.CompilationUnit
```
----------
______________________________________________________________________
Editor - Function
*****************
## Editor - Function
```{eval-rst}
.. autoclass:: lief.dwarf.editor.Function
```
----------
______________________________________________________________________
Editor - Variable
*****************
## Editor - Variable
```{eval-rst}
.. autoclass:: lief.dwarf.editor.Variable
```
----------
Editor - Type
*************
______________________________________________________________________
## Editor - Type
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.Type
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.Type
```
----------
______________________________________________________________________
Editor - PointerType
********************
## Editor - PointerType
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.PointerType
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.PointerType
```
----------
______________________________________________________________________
Editor - EnumType
*****************
## Editor - EnumType
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.EnumType
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.EnumType
```
----------
______________________________________________________________________
Editor - BaseType
*****************
## Editor - BaseType
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.BaseType
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.BaseType
```
----------
______________________________________________________________________
Editor - ArrayType
******************
## Editor - ArrayType
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.ArrayType
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.ArrayType
```
----------
______________________________________________________________________
Editor - FunctionType
*********************
## Editor - FunctionType
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.FunctionType
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.FunctionType
```
----------
______________________________________________________________________
Editor - TypeDef
****************
## Editor - TypeDef
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.TypeDef
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.TypeDef
```
----------
______________________________________________________________________
Editor - StructType
*******************
## Editor - StructType
```{eval-rst}
.. lief-inheritance:: lief._lief.dwarf.editor.StructType
:top-classes: lief._lief.dwarf.editor.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.dwarf.editor.StructType
```
+5
View File
@@ -0,0 +1,5 @@
# {fa}`brands fa-rust` Rust
:::{note}
Please check: {rust:module}`lief::dwarf`
:::
-6
View File
@@ -1,6 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
.. note::
Please check: :rust:module:`lief::dwarf`
@@ -1,10 +1,8 @@
.. _extended-intro:
(extended-intro)=
:fa:`cubes` What is LIEF Extended?
----------------------------------
# {fa}`cubes` What is LIEF Extended?
Introduction
************
## Introduction
*LIEF Extended* is an enhanced version of LIEF, providing additional features
such as support for the Dyld shared cache, Objective-C metadata, PDB, and DWARF.
@@ -15,6 +13,7 @@ was not originally intended for integration into the core LIEF project.
You can find the differences between the two versions in this table:
```{eval-rst}
+---------------------------------------------+-------------------+-------------------+----------------------------------------------------+
| Module | Regular Version | Extended Version | Note |
+=============================================+===================+===================+====================================================+
@@ -48,92 +47,89 @@ You can find the differences between the two versions in this table:
+---------------------------------------------+-------------------+-------------------+----------------------------------------------------+
| :ref:`Assembler <extended-assembler>` | :xmark:`mark` | :fa-check:`check` | Support based on LLVM :ref:`[1] <extended-llvm>` |
+---------------------------------------------+-------------------+-------------------+----------------------------------------------------+
```
.. raw:: html
<div class="card shadow-light">
<div class="card-body">
<h5 class="card-title"><i class="fab fa-github text-darkblue mr-2"></i>Get Access</h5>
<p class="card-text">To access the extended version, you must <b>oauth-login</b> with <b>GitHub</b> here:</p>
<a href="https://extended.lief.re/" target="_blank" class="btn btn-pink text-uppercase-bold-sm shadow-sm mx-2 hover-lift-light"><i class="fa-solid fa-cubes mr-2"></i>LIEF Extended</a>
</div>
```{raw} html
<div class="card shadow-light">
<div class="card-body">
<h3 class="card-title"><i class="fab fa-github text-darkblue mr-2"></i>Get Access</h3>
<p class="card-text">To access the extended version, you must <b>oauth-login</b> with <b>GitHub</b> here:</p>
<a href="https://extended.lief.re/" target="_blank" class="btn btn-pink text-uppercase-bold-sm shadow-sm mx-2 hover-lift-light"><i class="fa-solid fa-cubes mr-2"></i>LIEF Extended</a>
</div>
<br />
</div>
<br />
```
To access the extended version, you must **oauth-login** with **GitHub** here: |lief-extended-url|.
To access the extended version, you must **oauth-login** with **GitHub** here: {sub-ref}`lief-extended-url`.
Once logged in, you can download the package of your choice
(e.g., LIEF Extended - Python 3.10 for macOS arm64).
:::{admonition} Email
:class: warning
.. admonition:: Email
:class: warning
If you don't receive the download email, you can download the package directly
from your **History** section.
:::
If you don't receive the download email, you can download the package directly
from your **History** section.
Versioning
**********
## Versioning
LIEF Extended uses a slightly different versioning scheme than regular LIEF packages.
First, **every extended package** is based on the current ``main`` branch
First, **every extended package** is based on the current `main` branch
of LIEF. If you need an (extended) build for a specific commit or tag,
please contact |lief-extended-email|.
please contact {sub-ref}`lief-extended-email`.
In Python, you can check the commit of LIEF being used in the extended version
with:
.. code-block:: bash
```bash
# Make sure it's the extended version
$ python -c "import lief;print(lief.__extended__)"
# Make sure it's the extended version
$ python -c "import lief;print(lief.__extended__)"
# Print LIEF's main commit
$ python -c "import lief;print(lief.__LIEF_MAIN_COMMIT__)"
```
# Print LIEF's main commit
$ python -c "import lief;print(lief.__LIEF_MAIN_COMMIT__)"
With the C++/Rust SDK, you can call |lief-extended-version-info| to
With the C++/Rust SDK, you can call {sub-ref}`lief-extended-version-info` to
get details about the current version.
Additional features exposed by LIEF Extended are not always represented in
a public commit while still being git-versioned. An incremental build number is
used to represent internal changes not associated with a public commit.
For example, version ``0.16.0.2380`` includes 10 more commits than
version ``0.16.0.2370``.
For example, version `0.16.0.2380` includes 10 more commits than
version `0.16.0.2370`.
Python Wheels
*************
## Python Wheels
Python packages are delivered as a wheel for the required platform/version
(e.g., ``lief_extended-0.16.0.post2370-cp312-cp312-win_amd64.whl``).
(e.g., `lief_extended-0.16.0.post2370-cp312-cp312-win_amd64.whl`).
You can install this wheel using pip in one of the following ways:
.. code-block:: console
$ venv\Scripts\python.exe -m pip install C:\Users\tmp\lief_extended-0.16.0.post2370-cp312-cp312-win_amd64.whl
```console
$ venv\Scripts\python.exe -m pip install C:\Users\tmp\lief_extended-0.16.0.post2370-cp312-cp312-win_amd64.whl
```
Or
.. code-block:: console
$ venv\Scripts\python.exe -m pip install --find-links C:\Users\tmp\ lief_extended
```console
$ venv\Scripts\python.exe -m pip install --find-links C:\Users\tmp\ lief_extended
```
You can verify that LIEF Extended is correctly installed with:
.. code-block:: console
```console
$ python -c "import lief;print(lief.__extended__)"
True
```
$ python -c "import lief;print(lief.__extended__)"
True
## C++ SDK
C++ SDK
*******
The C++ SDK is delivered as a `.zip/.tar.gz` archive containing:
The C++ SDK is delivered as a ``.zip/.tar.gz`` archive containing:
- A compiled shared library (``libLIEF.so``, ``LIEF.dll``, ``libLIEF.dylib``)
- A compiled shared library (`libLIEF.so`, `LIEF.dll`, `libLIEF.dylib`)
- Header files
- CMake helper files
@@ -142,64 +138,60 @@ LIEF, and the shared library is compiled with all extended features.
Here is the layout for the macOS arm64 SDK, for example:
.. code-block:: text
```text
LIEF-extended-sdk-0.16.0.2378-Darwin-arm64/
lib/libLIEF.dylib
lib/cmake/LIEF/lief-extended-config-version.cmake
include/[...]
```
LIEF-extended-sdk-0.16.0.2378-Darwin-arm64/
lib/libLIEF.dylib
lib/cmake/LIEF/lief-extended-config-version.cmake
include/[...]
## Rust SDK
Rust SDK
********
The Rust SDK is also delivered as a `.zip/.tar.gz` archive containing all the
files needed for use with the `LIEF_RUST_PRECOMPILED` environment variable,
as described in the {ref}`Rust <lief_rust_bindings>` section.
The Rust SDK is also delivered as a ``.zip/.tar.gz`` archive containing all the
files needed for use with the ``LIEF_RUST_PRECOMPILED`` environment variable,
as described in the :ref:`Rust <lief_rust_bindings>` section.
Once the archive is extracted, you just have to set the ``LIEF_RUST_PRECOMPILED``
Once the archive is extracted, you just have to set the `LIEF_RUST_PRECOMPILED`
environment variable to the extracted path:
.. code-block:: console
```console
$ tar xzvf LIEF-extended-rust-0.16.0.2378-Linux-x86_64.tar.gz
LIEF-extended-rust-0.16.0.2378-Linux-x86_64/lib/
LIEF-extended-rust-0.16.0.2378-Linux-x86_64/lib/libLIEF.so
LIEF-extended-rust-0.16.0.2378-Linux-x86_64/lib/liblief-sys.a
$ tar xzvf LIEF-extended-rust-0.16.0.2378-Linux-x86_64.tar.gz
LIEF-extended-rust-0.16.0.2378-Linux-x86_64/lib/
LIEF-extended-rust-0.16.0.2378-Linux-x86_64/lib/libLIEF.so
LIEF-extended-rust-0.16.0.2378-Linux-x86_64/lib/liblief-sys.a
$ export LIEF_RUST_PRECOMPILED=$(pwd)/LIEF-extended-rust-0.16.0.2378-Linux-x86_64
$ export LIEF_RUST_PRECOMPILED=$(pwd)/LIEF-extended-rust-0.16.0.2378-Linux-x86_64
```
You can then use all the extended features in Rust:
.. code-block:: console
```console
$ cargo build my-lief-extended-project
```
$ cargo build my-lief-extended-project
.. _extended-llvm:
LIEF Extended & LLVM
********************
(extended-llvm)=
## LIEF Extended & LLVM
LIEF Extended relies on LLVM for certain features, such as the
:ref:`disassembler <extended-disassembler>` and
:ref:`DWARF <extended-dwarf>`/:ref:`PDB <extended-pdb>` support.
{ref}`disassembler <extended-disassembler>` and
{ref}`DWARF <extended-dwarf>`/{ref}`PDB <extended-pdb>` support.
The LLVM version used by LIEF is based on the upstream version and integrated
into LIEF Extended so that users do not have to handle LLVM compilation or
integration.
.. note::
LIEF is currently using LLVM |lief-llvm-version|.
:::{note}
LIEF is currently using LLVM {sub-ref}`lief-llvm-version`.
:::
Whenever possible and appropriate, bug fixes and enhancements have been
submitted as PRs to the LLVM project:
- :llvm-pr:`119057`
- :llvm-pr:`119056`
- :llvm-pr:`116480`
- :llvm-pr:`116479`
- :llvm-pr:`97954`
- {llvm-pr}`119057`
- {llvm-pr}`119056`
- {llvm-pr}`116480`
- {llvm-pr}`116479`
- {llvm-pr}`97954`
.. include:: ../_cross_api.rst
{{ cross_api }}
+67
View File
@@ -0,0 +1,67 @@
# C++
:::{note}
You can also find the Doxygen documentation here: [here](../../doxygen/)
:::
## Metadata
```{eval-rst}
.. doxygenclass:: LIEF::objc::Metadata
```
______________________________________________________________________
## Class
```{eval-rst}
.. doxygenclass:: LIEF::objc::Class
```
______________________________________________________________________
## Category
```{eval-rst}
.. doxygenclass:: LIEF::objc::Category
```
______________________________________________________________________
## Protocol
```{eval-rst}
.. doxygenclass:: LIEF::objc::Protocol
```
______________________________________________________________________
## Instance Variable (IVar)
```{eval-rst}
.. doxygenclass:: LIEF::objc::IVar
```
______________________________________________________________________
## Method
```{eval-rst}
.. doxygenclass:: LIEF::objc::Method
```
______________________________________________________________________
## Property
```{eval-rst}
.. doxygenclass:: LIEF::objc::Property
```
______________________________________________________________________
## DeclOpt
```{eval-rst}
.. doxygenstruct:: LIEF::objc::DeclOpt
```
-67
View File
@@ -1,67 +0,0 @@
C++
-------
.. note::
You can also find the Doxygen documentation here: `here <../../doxygen/>`_
Metadata
*********
.. doxygenclass:: LIEF::objc::Metadata
----------
Class
*****
.. doxygenclass:: LIEF::objc::Class
----------
Category
********
.. doxygenclass:: LIEF::objc::Category
----------
Protocol
********
.. doxygenclass:: LIEF::objc::Protocol
----------
Instance Variable (IVar)
************************
.. doxygenclass:: LIEF::objc::IVar
----------
Method
******
.. doxygenclass:: LIEF::objc::Method
----------
Property
********
.. doxygenclass:: LIEF::objc::Property
----------
DeclOpt
*******
.. doxygenstruct:: LIEF::objc::DeclOpt
+143
View File
@@ -0,0 +1,143 @@
(extended-objc)=
# {fa}`brands fa-apple` Objective-C
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 2
cpp
python
rust
```
## Introduction
This module enables inspecting Objective-C metadata within a Mach-O
binary.
If a Mach-O binary embeds Objective-C metadata, it can be accessed through
{sub-ref}`lief-macho-binary-objc-metadata`:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/objc.py", "check") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/objc.cpp", "check") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/objc.rs", "check") }}
:::
::::
At this point, one can use the API exposed by the {sub-ref}`lief-objc-metadata` class
to inspect the Objective-C metadata.
In particular, the {sub-ref}`lief-objc-metadata-to_decl` function can be used to generate
a header-like output of all the Objective-C metadata found in the binary.
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/objc.py", "inspect") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/objc.cpp", "inspect") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/objc.rs", "inspect") }}
:::
::::
## Class Dump
When performing binary analysis, it can be useful to generate header-like
information to get a global overview of the structures present in the
Objective-C metadata.
```{image} ../../_static/objc-class-dump.webp
:alt: Objective-C class dump based on LIEF & LLVM
```
LIEF provides a way to generate this header-like information at various levels:
- {sub-ref}`lief-objc-metadata-to_decl_opt`
- {sub-ref}`lief-objc-class-to_decl_opt`
- {sub-ref}`lief-objc-proto-to_decl_opt`
Technically, this output is created by generating a Clang AST and applying
the LLVM printer visitor to it.
::::{tabs}
:::{tab} {fa}`brands fa-rust` Code
{{ literalinclude("../../../code/rust/src/objc.rs", "classdump") }}
:::
:::{tab} {fa}`solid fa-terminal` Result
```{code-block} objc
@interface APMEventFilter<APMAudienceFilter> {
bool _sessionScoped;
bool _dynamic;
bool _sequence;
int _audienceID;
int _filterID;
NSString * _eventName;
NSData * _data;
}
// Address: 0x0101859ee0
- (NSObject *)initWithAudienceID:(APMEventFilter *)self filterID:(SEL)id eventName:(int)arg2 data:(int)arg3 sessionScoped:(NSObject *)arg4 dynamic:(NSObject *)arg5 sequence:(bool)arg6 :(bool)arg7 :(bool)arg8;
// Address: 0x0101682590
- (int)audienceID:(APMEventFilter *)self :(SEL)id;
// Address: 0x01017b6d98
- (int)filterID:(APMEventFilter *)self :(SEL)id;
// Address: 0x01018a4a6c
- (bool)isSessionScoped:(APMEventFilter *)self :(SEL)id;
// Address: 0x01017630d4
- (bool)isDynamic:(APMEventFilter *)self :(SEL)id;
// Address: 0x01016adbb4
- (bool)isSequence:(APMEventFilter *)self :(SEL)id;
// Address: 0x010187a5f8
- (NSObject *)eventName:(APMEventFilter *)self :(SEL)id;
// Address: 0x0101581bfc
- (NSObject *)data:(APMEventFilter *)self :(SEL)id;
// Address: 0x01018e1f3c
- (void).cxx_destruct:(APMEventFilter *)self :(SEL)id;
@property void eventName;
@property void data;
@property void audienceID;
@property void filterID;
@property void sessionScoped;
@property void dynamic;
@property void sequence;
@property void hash;
@property void superclass;
@property void description;
@property void debugDescription;
@end
```
:::
::::
The {sub-ref}`lief-objc-declopt` can be used to customize the generated output. For
example, we can remove the commented addresses associated with Objective-C
methods using this option:
{{ literalinclude("../../../code/python/objc.py", "no-address") }}
## {fa}`solid fa-book-open-reader` References
- {github-ref}`romainthomas/iCDump`
- {github-ref}`nygard/class-dump`
- <https://www.romainthomas.fr/post/23-01-icdump/>
## API
You can find the documentation of the API for the different languages here:
{fa}`brands fa-python` {doc}`Python API <python>`
{fa}`regular fa-file-code` {doc}`C++ API <cpp>`
{fa}`brands fa-rust` Rust API: {rust:module}`lief::objc`
{{ cross_api }}
-184
View File
@@ -1,184 +0,0 @@
.. _extended-objc:
:fa:`brands fa-apple` Objective-C
---------------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 2
cpp
python
rust
----
Introduction
************
This module enables inspecting Objective-C metadata within a Mach-O
binary.
If a Mach-O binary embeds Objective-C metadata, it can be accessed through
|lief-macho-binary-objc-metadata|:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/objc.py
:language: python
:start-after: lief-doc: check-start
:end-before: lief-doc: check-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/objc.cpp
:language: cpp
:start-after: lief-doc: check-start
:end-before: lief-doc: check-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/objc.rs
:language: rust
:start-after: lief-doc: check-start
:end-before: lief-doc: check-end
:dedent:
At this point, one can use the API exposed by the |lief-objc-metadata| class
to inspect the Objective-C metadata.
In particular, the |lief-objc-metadata-to_decl| function can be used to generate
a header-like output of all the Objective-C metadata found in the binary.
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/objc.py
:language: python
:start-after: lief-doc: inspect-start
:end-before: lief-doc: inspect-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/objc.cpp
:language: cpp
:start-after: lief-doc: inspect-start
:end-before: lief-doc: inspect-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/objc.rs
:language: rust
:start-after: lief-doc: inspect-start
:end-before: lief-doc: inspect-end
:dedent:
Class Dump
**********
When performing binary analysis, it can be useful to generate header-like
information to get a global overview of the structures present in the
Objective-C metadata.
.. image:: ../../_static/objc-class-dump.webp
:alt: Objective-C class dump based on LIEF & LLVM
LIEF provides a way to generate this header-like information at various levels:
- |lief-objc-metadata-to_decl_opt|
- |lief-objc-class-to_decl_opt|
- |lief-objc-proto-to_decl_opt|
Technically, this output is created by generating a Clang AST and applying
the LLVM printer visitor to it.
.. tabs::
.. tab:: :fa:`brands fa-rust` Code
.. literalinclude:: ../../../code/rust/src/objc.rs
:language: rust
:start-after: lief-doc: classdump-start
:end-before: lief-doc: classdump-end
:dedent:
.. tab:: :fa:`solid fa-terminal` Result
.. code-block:: objc
@interface APMEventFilter<APMAudienceFilter> {
bool _sessionScoped;
bool _dynamic;
bool _sequence;
int _audienceID;
int _filterID;
NSString * _eventName;
NSData * _data;
}
// Address: 0x0101859ee0
- (NSObject *)initWithAudienceID:(APMEventFilter *)self filterID:(SEL)id eventName:(int)arg2 data:(int)arg3 sessionScoped:(NSObject *)arg4 dynamic:(NSObject *)arg5 sequence:(bool)arg6 :(bool)arg7 :(bool)arg8;
// Address: 0x0101682590
- (int)audienceID:(APMEventFilter *)self :(SEL)id;
// Address: 0x01017b6d98
- (int)filterID:(APMEventFilter *)self :(SEL)id;
// Address: 0x01018a4a6c
- (bool)isSessionScoped:(APMEventFilter *)self :(SEL)id;
// Address: 0x01017630d4
- (bool)isDynamic:(APMEventFilter *)self :(SEL)id;
// Address: 0x01016adbb4
- (bool)isSequence:(APMEventFilter *)self :(SEL)id;
// Address: 0x010187a5f8
- (NSObject *)eventName:(APMEventFilter *)self :(SEL)id;
// Address: 0x0101581bfc
- (NSObject *)data:(APMEventFilter *)self :(SEL)id;
// Address: 0x01018e1f3c
- (void).cxx_destruct:(APMEventFilter *)self :(SEL)id;
@property void eventName;
@property void data;
@property void audienceID;
@property void filterID;
@property void sessionScoped;
@property void dynamic;
@property void sequence;
@property void hash;
@property void superclass;
@property void description;
@property void debugDescription;
@end
The |lief-objc-declopt| can be used to customize the generated output. For
example, we can remove the commented addresses associated with Objective-C
methods using this option:
.. literalinclude:: ../../../code/python/objc.py
:language: python
:start-after: lief-doc: no-address-start
:end-before: lief-doc: no-address-end
:dedent:
:fa:`solid fa-book-open-reader` References
*******************************************
- :github-ref:`romainthomas/iCDump`
- :github-ref:`nygard/class-dump`
- https://www.romainthomas.fr/post/23-01-icdump/
API
****
You can find the documentation of the API for the different languages here:
:fa:`brands fa-python` :doc:`Python API <python>`
:fa:`regular fa-file-code` :doc:`C++ API <cpp>`
:fa:`brands fa-rust` Rust API: :rust:module:`lief::objc`
.. include:: ../../_cross_api.rst
+63
View File
@@ -0,0 +1,63 @@
# Python
## Metadata
```{eval-rst}
.. autoclass:: lief.objc.Metadata
```
______________________________________________________________________
## Class
```{eval-rst}
.. autoclass:: lief.objc.Class
```
______________________________________________________________________
## Category
```{eval-rst}
.. autoclass:: lief.objc.Category
```
______________________________________________________________________
## Protocol
```{eval-rst}
.. autoclass:: lief.objc.Protocol
```
______________________________________________________________________
## Method
```{eval-rst}
.. autoclass:: lief.objc.Method
```
______________________________________________________________________
## IVar
```{eval-rst}
.. autoclass:: lief.objc.IVar
```
______________________________________________________________________
## Property
```{eval-rst}
.. autoclass:: lief.objc.Property
```
______________________________________________________________________
## DeclOpt
```{eval-rst}
.. autoclass:: lief.objc.DeclOpt
```
-58
View File
@@ -1,58 +0,0 @@
Python
-------
Metadata
********
.. autoclass:: lief.objc.Metadata
----------
Class
*****
.. autoclass:: lief.objc.Class
----------
Category
********
.. autoclass:: lief.objc.Category
----------
Protocol
********
.. autoclass:: lief.objc.Protocol
----------
Method
******
.. autoclass:: lief.objc.Method
----------
IVar
****
.. autoclass:: lief.objc.IVar
----------
Property
********
.. autoclass:: lief.objc.Property
----------
DeclOpt
*******
.. autoclass:: lief.objc.DeclOpt
+5
View File
@@ -0,0 +1,5 @@
# {fa}`brands fa-rust` Rust
:::{note}
Please check: {rust:module}`lief::objc`
:::
-6
View File
@@ -1,6 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
.. note::
Please check: :rust:module:`lief::objc`
+175
View File
@@ -0,0 +1,175 @@
# C++
:::{note}
You can also find the Doxygen documentation here: [here](../../doxygen/)
:::
```{eval-rst}
.. doxygenfunction:: LIEF::pdb::load
```
## DebugInfo
```{eval-rst}
.. doxygenclass:: LIEF::pdb::DebugInfo
```
______________________________________________________________________
## PublicSymbol
```{eval-rst}
.. doxygenclass:: LIEF::pdb::PublicSymbol
```
______________________________________________________________________
## CompilationUnit
```{eval-rst}
.. doxygenclass:: LIEF::pdb::CompilationUnit
```
______________________________________________________________________
## BuildMetadata
```{eval-rst}
.. doxygenclass:: LIEF::pdb::BuildMetadata
```
______________________________________________________________________
## Function
```{eval-rst}
.. doxygenclass:: LIEF::pdb::Function
```
______________________________________________________________________
## Type
```{eval-rst}
.. doxygenclass:: LIEF::pdb::Type
```
______________________________________________________________________
## Array
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Array
```
______________________________________________________________________
## Attribute (type)
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Attribute
```
______________________________________________________________________
## BitField
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::BitField
```
______________________________________________________________________
## ClassLike
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::ClassLike
```
______________________________________________________________________
## Structure
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Structure
```
______________________________________________________________________
## Class
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Class
```
______________________________________________________________________
## Interface
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Interface
```
______________________________________________________________________
## Enum
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Enum
```
______________________________________________________________________
## Function (type)
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Function
```
______________________________________________________________________
## Method (type)
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Method
```
______________________________________________________________________
## Modifier
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Modifier
```
______________________________________________________________________
## Pointer
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Pointer
```
______________________________________________________________________
## Simple
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Simple
```
______________________________________________________________________
## Union
```{eval-rst}
.. doxygenclass:: LIEF::pdb::types::Union
```
## Utilities
```{eval-rst}
.. doxygenfunction:: LIEF::pdb::is_pdb(const std::string&)
```
-155
View File
@@ -1,155 +0,0 @@
C++
-------
.. note::
You can also find the Doxygen documentation here: `here <../../doxygen/>`_
.. doxygenfunction:: LIEF::pdb::load
DebugInfo
*********
.. doxygenclass:: LIEF::pdb::DebugInfo
----------
PublicSymbol
************
.. doxygenclass:: LIEF::pdb::PublicSymbol
----------
CompilationUnit
***************
.. doxygenclass:: LIEF::pdb::CompilationUnit
----------
BuildMetadata
*************
.. doxygenclass:: LIEF::pdb::BuildMetadata
----------
Function
********
.. doxygenclass:: LIEF::pdb::Function
----------
Type
********
.. doxygenclass:: LIEF::pdb::Type
----------
Array
********
.. doxygenclass:: LIEF::pdb::types::Array
----------
Attribute (type)
****************
.. doxygenclass:: LIEF::pdb::types::Attribute
----------
BitField
********
.. doxygenclass:: LIEF::pdb::types::BitField
----------
ClassLike
*********
.. doxygenclass:: LIEF::pdb::types::ClassLike
----------
Structure
*********
.. doxygenclass:: LIEF::pdb::types::Structure
----------
Class
*****
.. doxygenclass:: LIEF::pdb::types::Class
----------
Interface
*********
.. doxygenclass:: LIEF::pdb::types::Interface
----------
Enum
********
.. doxygenclass:: LIEF::pdb::types::Enum
----------
Function (type)
***************
.. doxygenclass:: LIEF::pdb::types::Function
----------
Method (type)
*************
.. doxygenclass:: LIEF::pdb::types::Method
----------
Modifier
********
.. doxygenclass:: LIEF::pdb::types::Modifier
----------
Pointer
********
.. doxygenclass:: LIEF::pdb::types::Pointer
----------
Simple
********
.. doxygenclass:: LIEF::pdb::types::Simple
----------
Union
********
.. doxygenclass:: LIEF::pdb::types::Union
Utilities
*********
.. doxygenfunction:: LIEF::pdb::is_pdb(const std::string&)
+131
View File
@@ -0,0 +1,131 @@
(extended-pdb)=
# {fa}`brands fa-windows` PDB
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
```
## Introduction
Unlike DWARF debug information, PDB debug information is always stored
externally from the original binary. Nevertheless, the original binary keeps
the path of the PDB file in the {sub-ref}`lief-pe-codeviewpdb-filename` attribute.
Based on this fact, {sub-ref}`lief-pdb-binary-debug-info` tries to instantiate a
{sub-ref}`lief-pdb-debug-info` object using this file path. If it fails, it returns
`nullptr` or `None`.
You can also instantiate a {sub-ref}`lief-pdb-debug-info` object using {sub-ref}`lief-pdb-load`:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/pdb.py", "load") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/pdb.cpp", "load") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/pdb.rs", "load") }}
:::
::::
At this point, the PDB instance ({sub-ref}`lief-pdb-debug-info`) can be used to explore
the PDB debug information:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/pdb.py", "explore") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/pdb.cpp", "explore") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/pdb.rs", "explore") }}
:::
::::
(extended-pdb-load-ext)=
You can also use the {sub-ref}`lief-abstract-binary-load_debug_info` function to bind
a PDB file to an existing {sub-ref}`lief-abstract-binary`:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/pdb.py", "load-ext") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/pdb.cpp", "load-ext") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/pdb.rs", "load-ext") }}
:::
::::
Note that {sub-ref}`lief-abstract-binary-load_debug_info` can also attach an external
DWARF file to a PE binary, even though this is not a typical use case.
For instance, the {ref}`BinaryNinja <plugins-binaryninja-dwarf>` and
{ref}`Ghidra <plugins-ghidra-dwarf>` DWARF export plugins can generate
a DWARF file for a PE binary based on analyses performed by these frameworks.
This external loading API is useful for adding debug information that might not
already be present in the binary. For instance, the {sub-ref}`lief-disassemble` function
can leverage this additional debug information to disassemble functions
defined in the debug file previously loaded:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/pdb.py", "disassemble") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/pdb.cpp", "disassemble") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/pdb.rs", "disassemble") }}
:::
::::
(extended-pdb-to-decl)=
## Generating C/C++ Definitions
PDB types, functions and compilation units can be turned into C/C++ definitions
using the `to_decl()` function:
- {sub-ref}`lief-pdb-type-to_decl`
- {sub-ref}`lief-pdb-function-to_decl`
- {sub-ref}`lief-pdb-cu-to_decl`
The generated output can be configured with a {sub-ref}`lief-declopt` structure:
::::{tabs}
:::{tab} {fa}`brands fa-python` Python
{{ literalinclude("../../../code/python/pdb.py", "to-decl") }}
:::
:::{tab} {fa}`regular fa-file-code` C++
{{ literalinclude("../../../code/cpp/pdb.cpp", "to-decl") }}
:::
:::{tab} {fa}`brands fa-rust` Rust
{{ literalinclude("../../../code/rust/src/pdb.rs", "to-decl") }}
:::
::::
______________________________________________________________________
## API
You can find the documentation of the API for the different languages here:
{fa}`brands fa-python` {doc}`Python API <python>`
{fa}`regular fa-file-code` {doc}`C++ API <cpp>`
{fa}`brands fa-rust` Rust API: {rust:module}`lief::pdb`
{{ cross_api }}
-207
View File
@@ -1,207 +0,0 @@
.. _extended-pdb:
:fa:`brands fa-windows` PDB
----------------------------
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
rust
----
Introduction
************
Unlike DWARF debug information, PDB debug information is always stored
externally from the original binary. Nevertheless, the original binary keeps
the path of the PDB file in the |lief-pe-codeviewpdb-filename| attribute.
Based on this fact, |lief-pdb-binary-debug-info| tries to instantiate a
|lief-pdb-debug-info| object using this file path. If it fails, it returns
``nullptr`` or ``None``.
You can also instantiate a |lief-pdb-debug-info| object using |lief-pdb-load|:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/pdb.py
:language: python
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/pdb.cpp
:language: cpp
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/pdb.rs
:language: rust
:start-after: lief-doc: load-start
:end-before: lief-doc: load-end
:dedent:
At this point, the PDB instance (|lief-pdb-debug-info|) can be used to explore
the PDB debug information:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/pdb.py
:language: python
:start-after: lief-doc: explore-start
:end-before: lief-doc: explore-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/pdb.cpp
:language: cpp
:start-after: lief-doc: explore-start
:end-before: lief-doc: explore-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/pdb.rs
:language: rust
:start-after: lief-doc: explore-start
:end-before: lief-doc: explore-end
:dedent:
.. _extended-pdb-load-ext:
You can also use the |lief-abstract-binary-load_debug_info| function to bind
a PDB file to an existing |lief-abstract-binary|:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/pdb.py
:language: python
:start-after: lief-doc: load-ext-start
:end-before: lief-doc: load-ext-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/pdb.cpp
:language: cpp
:start-after: lief-doc: load-ext-start
:end-before: lief-doc: load-ext-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/pdb.rs
:language: rust
:start-after: lief-doc: load-ext-start
:end-before: lief-doc: load-ext-end
:dedent:
Note that |lief-abstract-binary-load_debug_info| can also attach an external
DWARF file to a PE binary, even though this is not a typical use case.
For instance, the :ref:`BinaryNinja <plugins-binaryninja-dwarf>` and
:ref:`Ghidra <plugins-ghidra-dwarf>` DWARF export plugins can generate
a DWARF file for a PE binary based on analyses performed by these frameworks.
This external loading API is useful for adding debug information that might not
already be present in the binary. For instance, the |lief-disassemble| function
can leverage this additional debug information to disassemble functions
defined in the debug file previously loaded:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/pdb.py
:language: python
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/pdb.cpp
:language: cpp
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/pdb.rs
:language: rust
:start-after: lief-doc: disassemble-start
:end-before: lief-doc: disassemble-end
:dedent:
.. _extended-pdb-to-decl:
Generating C/C++ Definitions
****************************
PDB types, functions and compilation units can be turned into C/C++ definitions
using the ``to_decl()`` function:
- |lief-pdb-type-to_decl|
- |lief-pdb-function-to_decl|
- |lief-pdb-cu-to_decl|
The generated output can be configured with a |lief-declopt| structure:
.. tabs::
.. tab:: :fa:`brands fa-python` Python
.. literalinclude:: ../../../code/python/pdb.py
:language: python
:start-after: lief-doc: to-decl-start
:end-before: lief-doc: to-decl-end
:dedent:
.. tab:: :fa:`regular fa-file-code` C++
.. literalinclude:: ../../../code/cpp/pdb.cpp
:language: cpp
:start-after: lief-doc: to-decl-start
:end-before: lief-doc: to-decl-end
:dedent:
.. tab:: :fa:`brands fa-rust` Rust
.. literalinclude:: ../../../code/rust/src/pdb.rs
:language: rust
:start-after: lief-doc: to-decl-start
:end-before: lief-doc: to-decl-end
:dedent:
----
API
****
You can find the documentation of the API for the different languages here:
:fa:`brands fa-python` :doc:`Python API <python>`
:fa:`regular fa-file-code` :doc:`C++ API <cpp>`
:fa:`brands fa-rust` Rust API: :rust:module:`lief::pdb`
.. include:: ../../_cross_api.rst
+261
View File
@@ -0,0 +1,261 @@
# Python
```{eval-rst}
.. autofunction:: lief.pdb.load
```
## DebugInfo
```{eval-rst}
.. autoclass:: lief.pdb.DebugInfo
```
______________________________________________________________________
## CompilationUnit
```{eval-rst}
.. autoclass:: lief.pdb.CompilationUnit
```
______________________________________________________________________
## BuildMetadata
```{eval-rst}
.. autoclass:: lief.pdb.BuildMetadata
```
______________________________________________________________________
## PublicSymbol
```{eval-rst}
.. autoclass:: lief.pdb.PublicSymbol
```
______________________________________________________________________
## Function
```{eval-rst}
.. autoclass:: lief.pdb.Function
```
______________________________________________________________________
## Type
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.Type
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.Type
```
______________________________________________________________________
## Array
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Array
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Array
```
______________________________________________________________________
## Attribute (type)
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Attribute
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Attribute
```
______________________________________________________________________
## BitField
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.BitField
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.BitField
```
______________________________________________________________________
## ClassLike
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.ClassLike
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.ClassLike
```
______________________________________________________________________
## Structure
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Structure
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Structure
```
______________________________________________________________________
## Class
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Class
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Class
```
______________________________________________________________________
## Interface
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Interface
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Interface
```
______________________________________________________________________
## Enum
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Enum
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Enum
```
______________________________________________________________________
## Function (type)
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Function
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Function
```
______________________________________________________________________
## Method (type)
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Method
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Method
```
______________________________________________________________________
## Modifier
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Modifier
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Modifier
```
______________________________________________________________________
## Pointer
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Pointer
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Pointer
```
______________________________________________________________________
## Simple
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Simple
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Simple
```
______________________________________________________________________
## Union
```{eval-rst}
.. lief-inheritance:: lief._lief.pdb.types.Union
:top-classes: lief._lief.pdb.Type
:parts: 2
```
```{eval-rst}
.. autoclass:: lief.pdb.types.Union
```
______________________________________________________________________
## Utilities
```{eval-rst}
.. autofunction:: lief.is_pdb
```
-214
View File
@@ -1,214 +0,0 @@
Python
-------
.. autofunction:: lief.pdb.load
DebugInfo
**********
.. autoclass:: lief.pdb.DebugInfo
----------
CompilationUnit
***************
.. autoclass:: lief.pdb.CompilationUnit
----------
BuildMetadata
*************
.. autoclass:: lief.pdb.BuildMetadata
----------
PublicSymbol
************
.. autoclass:: lief.pdb.PublicSymbol
----------
Function
********
.. autoclass:: lief.pdb.Function
----------
Type
********
.. lief-inheritance:: lief._lief.pdb.Type
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.Type
----------
Array
*****
.. lief-inheritance:: lief._lief.pdb.types.Array
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Array
----------
Attribute (type)
****************
.. lief-inheritance:: lief._lief.pdb.types.Attribute
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Attribute
----------
BitField
********
.. lief-inheritance:: lief._lief.pdb.types.BitField
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.BitField
----------
ClassLike
*********
.. lief-inheritance:: lief._lief.pdb.types.ClassLike
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.ClassLike
----------
Structure
*********
.. lief-inheritance:: lief._lief.pdb.types.Structure
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Structure
----------
Class
*****
.. lief-inheritance:: lief._lief.pdb.types.Class
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Class
----------
Interface
*********
.. lief-inheritance:: lief._lief.pdb.types.Interface
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Interface
----------
Enum
****
.. lief-inheritance:: lief._lief.pdb.types.Enum
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Enum
----------
Function (type)
***************
.. lief-inheritance:: lief._lief.pdb.types.Function
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Function
----------
Method (type)
*************
.. lief-inheritance:: lief._lief.pdb.types.Method
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Method
----------
Modifier
********
.. lief-inheritance:: lief._lief.pdb.types.Modifier
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Modifier
----------
Pointer
*******
.. lief-inheritance:: lief._lief.pdb.types.Pointer
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Pointer
----------
Simple
******
.. lief-inheritance:: lief._lief.pdb.types.Simple
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Simple
----------
Union
******
.. lief-inheritance:: lief._lief.pdb.types.Union
:top-classes: lief._lief.pdb.Type
:parts: 2
.. autoclass:: lief.pdb.types.Union
----------
Utilities
*********
.. autofunction:: lief.is_pdb
+5
View File
@@ -0,0 +1,5 @@
# {fa}`brands fa-rust` Rust
:::{note}
Please check: {rust:module}`lief::pdb`
:::
-6
View File
@@ -1,6 +0,0 @@
:fa:`brands fa-rust` Rust
---------------------------
.. note::
Please check: :rust:module:`lief::pdb`
@@ -1,47 +1,56 @@
:fa:`regular fa-file-code` C++
--------------------------------
# {fa}`regular fa-file-code` C++
Utilities
*********
## Utilities
```{eval-rst}
.. doxygenfunction:: LIEF::ART::is_art(const std::string&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::ART::is_art(const std::vector<uint8_t>&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::ART::version(const std::string&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::ART::version(const std::vector<uint8_t>&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::ART::android_version
:project: lief
```
----------
______________________________________________________________________
Parser
*******
## Parser
```{eval-rst}
.. doxygenclass:: LIEF::ART::Parser
:project: lief
```
----------
______________________________________________________________________
## File
File
****
```{eval-rst}
.. doxygenclass:: LIEF::ART::File
:project: lief
```
----------
______________________________________________________________________
Header
******
## Header
```{eval-rst}
.. doxygenclass:: LIEF::ART::Header
:project: lief
```
@@ -1,17 +1,16 @@
.. _format-art:
(format-art)=
:fa:`brands fa-android` ART
---------------------------
# {fa}`brands fa-android` ART
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
----
```
LIEF provides **basic** support for Android's ART files. For details about
this format, please refer to the :ref:`Android Formats <tuto-android-formats>`
this format, please refer to the {ref}`Android Formats <tuto-android-formats>`
tutorial.
+41
View File
@@ -0,0 +1,41 @@
# {fa}`brands fa-python` Python
## Utilities
```{eval-rst}
.. autofunction:: lief.is_art
```
```{eval-rst}
.. autofunction:: lief.ART.version
```
```{eval-rst}
.. autofunction:: lief.ART.android_version
```
______________________________________________________________________
## Parser
```{eval-rst}
.. autofunction:: lief.ART.parse
```
______________________________________________________________________
## File
```{eval-rst}
.. autoclass:: lief.ART.File
```
______________________________________________________________________
## Header
```{eval-rst}
.. autoclass:: lief.ART.Header
```
-37
View File
@@ -1,37 +0,0 @@
:fa:`brands fa-python` Python
------------------------------
Utilities
*********
.. autofunction:: lief.is_art
.. autofunction:: lief.ART.version
.. autofunction:: lief.ART.android_version
----------
Parser
******
.. autofunction:: lief.ART.parse
----------
File
****
.. autoclass:: lief.ART.File
----------
Header
******
.. autoclass:: lief.ART.Header
+131
View File
@@ -0,0 +1,131 @@
# {fa}`regular fa-file-code` C++
## Utilities
```{eval-rst}
.. doxygenfunction:: LIEF::DEX::is_dex(const std::string&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::DEX::is_dex(const std::vector<uint8_t>&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::DEX::version(const std::string&)
:project: lief
```
```{eval-rst}
.. doxygenfunction:: LIEF::DEX::version(const std::vector<uint8_t>&)
:project: lief
```
______________________________________________________________________
## Parser
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Parser
:project: lief
```
______________________________________________________________________
## File
```{eval-rst}
.. doxygenclass:: LIEF::DEX::File
:project: lief
```
______________________________________________________________________
## Header
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Header
:project: lief
```
______________________________________________________________________
## Method
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Method
:project: lief
```
______________________________________________________________________
## Class
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Class
:project: lief
```
______________________________________________________________________
## Field
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Field
:project: lief
```
______________________________________________________________________
## Code Info
```{eval-rst}
.. doxygenclass:: LIEF::DEX::CodeInfo
:project: lief
```
______________________________________________________________________
## Prototype
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Prototype
:project: lief
```
______________________________________________________________________
## Type
```{eval-rst}
.. doxygenclass:: LIEF::DEX::Type
:project: lief
```
______________________________________________________________________
## MapList
```{eval-rst}
.. doxygenclass:: LIEF::DEX::MapList
:project: lief
```
______________________________________________________________________
## MapItem
```{eval-rst}
.. doxygenclass:: LIEF::DEX::MapItem
:project: lief
```
-116
View File
@@ -1,116 +0,0 @@
:fa:`regular fa-file-code` C++
--------------------------------
Utilities
*********
.. doxygenfunction:: LIEF::DEX::is_dex(const std::string&)
:project: lief
.. doxygenfunction:: LIEF::DEX::is_dex(const std::vector<uint8_t>&)
:project: lief
.. doxygenfunction:: LIEF::DEX::version(const std::string&)
:project: lief
.. doxygenfunction:: LIEF::DEX::version(const std::vector<uint8_t>&)
:project: lief
----------
Parser
*******
.. doxygenclass:: LIEF::DEX::Parser
:project: lief
----------
File
****
.. doxygenclass:: LIEF::DEX::File
:project: lief
----------
Header
******
.. doxygenclass:: LIEF::DEX::Header
:project: lief
----------
Method
******
.. doxygenclass:: LIEF::DEX::Method
:project: lief
----------
Class
*****
.. doxygenclass:: LIEF::DEX::Class
:project: lief
----------
Field
*****
.. doxygenclass:: LIEF::DEX::Field
:project: lief
----------
Code Info
*********
.. doxygenclass:: LIEF::DEX::CodeInfo
:project: lief
----------
Prototype
*********
.. doxygenclass:: LIEF::DEX::Prototype
:project: lief
----------
Type
****
.. doxygenclass:: LIEF::DEX::Type
:project: lief
----------
MapList
*******
.. doxygenclass:: LIEF::DEX::MapList
:project: lief
----------
MapItem
*******
.. doxygenclass:: LIEF::DEX::MapItem
:project: lief
@@ -1,16 +1,15 @@
.. _format-dex:
(format-dex)=
:fa:`brands fa-android` DEX
----------------------------
# {fa}`brands fa-android` DEX
```{eval-rst}
.. toctree::
:caption: <i class="fa-solid fa-code">&nbsp;</i>API
:maxdepth: 1
cpp
python
----
```
LIEF enables parsing Android DEX files as detailed in the tutorial:
:ref:`Android Formats <tuto-android-formats>`.
{ref}`Android Formats <tuto-android-formats>`.

Some files were not shown because too many files have changed in this diff Show More