Getting your PDB name from a running executable (Windows)

Sometimes it’s useful to find the link to the PDB file belonging to your executable. It can be renamed or otherwise unavailable, so you can’t always derive it from the executable name.

If there is a PDB link in the executable, it’s stored in the debug dictionary, which lives in the PE header. Here’s some code (with virtually no error checking) that allows you to peak at that info:

struct PdbInfo
{
  DWORD     Signature;
  BYTE      Guid[16];
  DWORD     Age;
  char      PdbFileName[1];
};

int main()
{
  // Figure out where the executable is mapped in memory.
  uintptr_t base_pointer = (uintptr_t) GetModuleHandle(NULL);

  // This is where the MZ...blah header lives (the DOS header)
  IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*) base_pointer;

  // We want the PE header.
  IMAGE_FILE_HEADER* file_header = (IMAGE_FILE_HEADER*) (base_pointer + dos_header->e_lfanew + 4);

  // Straight after that is the optional header (which technically is optional, but in practice always there.)
  IMAGE_OPTIONAL_HEADER* opt_header = (IMAGE_OPTIONAL_HEADER*) (((char*)file_header) + sizeof(IMAGE_FILE_HEADER));

  // Grab the debug data directory which has an indirection to its data
  IMAGE_DATA_DIRECTORY* dir = &opt_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];

  // Convert that data to the right type.
  IMAGE_DEBUG_DIRECTORY* dbg_dir = (IMAGE_DEBUG_DIRECTORY*) (base_pointer + dir->VirtualAddress);

  // Check to see that the data has the right type
  if (IMAGE_DEBUG_TYPE_CODEVIEW == dbg_dir->Type)
  {
    PdbInfo* pdb_info = (PdbInfo*) (base_pointer + dbg_dir->AddressOfRawData);
    if (0 == memcmp(&pdb_info->Signature, "RSDS", 4))
    {
      printf("PDB path: %s\n", pdb_info->PdbFileName);
    }
  }

  return 0;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s