3.9 KiB
(extended-pdb)=
{fa}brands fa-windows PDB
.. toctree::
:caption: <i class="fa-solid fa-code"> </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 analysis 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 }}