PDB


Introduction

Compared to DWARF debug info, the PDB debug info are always externalized from the original binary. Nevertheless, the original binary keeps the path of the PDB file in the attribute .
import lief

pe = lief.PE.parse("some.exe")
if debug_info := pe.debug_info:
    assert isinstance(debug_info, lief.pdb.DebugInfo)
    print(f"PDB Debug handler: {debug_info}")

# Or you can load the PDB directly:
pdb: lief.pdb.DebugInfo = lief.pdb.load("some.pdb")
At this point, the PDB instance () can be used to explore the PDB debug info:
print("arg={}, guid={}", pdb.age, pdb.guid)

for sym in pdb.public_symbols:
    print("name={}, section={}, RVA={}",
          sym.name, sym.section_name, sym.RVA)

for ty in pdb.types:
    if isinstance(ty, lief.pdb.types.Class):
        print("Class[name]={}", ty.name)

for cu in pdb.compilation_units:
    print("module={}", cu.module_name)
    for src in cu.sources:
        print("  - {}", src)

    for func in cu.functions:
        print("name={}, section={}, RVA={}, code_size={}",
              func.name, func.section_name, func.RVA, func.code_size)
import lief

binary: lief.Binary = ... # Can be an ELF/PE/Mach-O [...]

dbg: lief.DebugInfo = binary.load_debug_info(r"C:\Users\romain\LIEF.pdb")
Note that can also attach an external DWARF file on a PE binary even if this is not the regular use case. For instance, BinaryNinja and Ghidra DWARF export plugin can generate a DWARF file based on the analyses performed by these frameworks for a PE binary.
This external loading API is useful for adding debug information that might not already be present in the binary. For instance, the function can leverage this additional debug information to disassemble functions defined in the debug file previously loaded:
import lief

binary: lief.Binary = ... # Can be an ELF/PE/Mach-O [...]

dbg: lief.DebugInfo = binary.load_debug_info(r"C:\Users\romain\LIEF.pdb")

# The location (address/size) of `my_function` is defined in LIEF.pdb
for inst in binary.disassemble("my_function"):
    print(inst)

API

You can find the documentation of the API for the different languages here:

Python API

C++ API

Rust API: lief::pdb