// ExtraPdbName.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <cstdio>
struct PdbInfo
{
DWORD Signature;
BYTE Guid[16];
DWORD Age;
char PdbFileName[1];
};
int main(int argc, char* argv[])
{
for (int i = 1; i < argc; ++i)
{
HMODULE module = ::LoadLibraryA(argv[i]);
if (module == 0)
{
std::cout << "Failed load :" << argv[i] << std::endl;
continue;
}
// Figure out where the executable is mapped in memory.
uintptr_t base_pointer = (uintptr_t)module;
// 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("%s PDB path: %s\n", argv[i], pdb_info->PdbFileName);
}
}
::FreeLibrary(module);
}
system("pause");
return 0;
}