Generate a PDB from Ghidra
This project is still very much a WIP, but the basic components should be usable.
- Download the latest version from github releases
- Copy
assets/PdbGen.javainto your ghidra_scripts folder (%USERPROFILE%/ghidra_scripts). - Copy
assets/pdbgen.exeinto a folder on your PATH - Run the pdbgen script via Ghidra's Script Manager
- The first time it runs, it will ask for an output location for the generated pdbs.
- The pdb will be saved in a symsrv compatible path using that output location as the base directory.
- Update your _NT_SYMBOL_PATH / WinDbgX settings with the folder you selected when you first ran the script
- make sure it is before any
cache*entries, otherwise WinDbgX will not reload from the generated pdb.
- make sure it is before any
- Open WinDbgX and run "reload /f" to load the new pdb.
- Once you have made changes in Ghidra, regenerate the pdb file using one of the following:
- Ctrl-G Keybind
- Tools -> Generate PDB
- Script Manager
- Reload the new symbols in WinDbgX to load the changes
.reload /f <module>
- If WinDbgX is not picking up the new symbols, ensure that there is no
cache*entry before the generated symbol location.cache*tells WinDbgX to store a copy of the .pdb file at the given location.- WinDbgX will not go back to check for a newer version.
- this applies to all symbols fetched from sorces processed after this entry.
- The default location for WinDbgX cache is
C:\ProgramData\Dbg\Sym.
- PDBGen will ask for a directory to store its generated pdbs in
- if you need to change this in the future, edit the file mentioned in the console output
- you can override this by setting the
OVERRIDE_SYMBOL_OUTPUT_PATHvalue in the script.
- Currently only global function symbols and data types are currently generated.
- dt <module!typename>
- x <module!symbolname>
- function names should be resolved in the callstack.
- If the CodeView entry in the DEBUG_DATA_DIRECTORY has been removed, it will fail to generate a pdb
- This is because the path to pdb is dictated by the
signature/guidandagevalues in this entry. - WinDbgX will use the files TimeDateStamp and SizeOfImage to fetch a legacy .dbg file, which I would like to support in the future.
- This is because the path to pdb is dictated by the
- You can dump a pdb using llvm's pdbutil tool:
llvm-pdbutil.exe dump --all <pdbpath> - We do not need the original binary for Ghidra (it has all the information already)
- however I would like to support IDA, which AFAIK discards the pe headers after importing.
# You will require a c++17 compliant compiler
git clone --config core.autocrlf=false --branch llvmorg-16.0.0 --single-branch https://github.com/llvm/llvm-project.git
git clone https://github.com/wandel/pdbgen.git --branch develop
git -C llvm-project apply ../pdbgen/llvm-debuginfo.patch # fix a bug in GSIStreamBuilder
cmake -B llvm-project/build -S llvm-project/llvm -Thost=x64
cmake --build llvm-project/build --target llvm-pdbutil # will take 10mins or so
cmake -B pdbgen/build -S pdbgen/core -DLLVM_DIR=../../llvm-project/build/lib/cmake/llvm -Thost=x64
cmake --build pdbgen/build- Clean this mess up
- Add symbols for function arguments
- Add symbols for local variables in functions
- Support Strings
- Build with Clang instead of Visual Studio 2019
- Support building & running on linux
- Support IDA
- Avoid requiring the original executable file