NtQueryInformationProcess から現在のプロセスのPEBを取得し、std::list<> に LDR_DATA_TABLE_ENTRY へのポインタを格納し、GetPdbOfSystemFileW(...) を呼び出します。
今回はGetCurrentProcess()を使い現在プロセスのを取得していますが、
任意のプロセスハンドルのを取得する場合は、ReadProcessMemoryでPEBなど読み取りましょう。
#include "stdafx.h" #include <list> #include <winternl.h> #include <DbgHelp.h> #include <dia2.h> #pragma comment(lib, "dbghelp.lib") #pragma comment(lib, "diaguids.lib") #pragma comment(lib, "ntdll.lib") extern "C" NTSTATUS NTAPI NtQueryInformationProcess(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); BOOL WINAPI GetPdbOfSystemFileW(__in LPCWSTR lpszFileName, __out LPWSTR lpszPdbPath) { SYMSRV_INDEX_INFOW SymInfo = { 0 }; WCHAR szCurPath[MAX_PATH], szSysFile[MAX_PATH]; WCHAR szSymName[MAX_PATH]; GetCurrentDirectory(MAX_PATH, szCurPath); StringCchPrintf(szSymName, MAX_PATH, L"srv*%s*http://msdl.microsoft.com/download/symbols", szCurPath); GetSystemDirectory(szSysFile, MAX_PATH); StringCchPrintf(szSysFile, MAX_PATH, L"%s\\%s", szSysFile, lpszFileName); SymSetOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_DEBUG); if (!SymInitializeW(GetCurrentProcess(), szSymName, FALSE)) return FALSE; SymInfo.sizeofstruct = sizeof(SYMSRV_INDEX_INFOW); if (!SymSrvGetFileIndexInfoW(lpszFileName, &SymInfo, 0)) return FALSE; if (!SymFindFileInPathW(GetCurrentProcess(), NULL, SymInfo.pdbfile, &SymInfo.guid, SymInfo.age, 0, SSRVOPT_GUIDPTR, lpszPdbPath, NULL, NULL)) return FALSE; return TRUE; } NTSTATUS NTAPI GetLoaderDataTableEntries(__out std::list<LDR_DATA_TABLE_ENTRY*> *pModules) { PROCESS_BASIC_INFORMATION pbi; NTSTATUS ntStatus; PEB_LDR_DATA *pLdrData; LIST_ENTRY *pCurrentList; LIST_ENTRY *pList; LDR_DATA_TABLE_ENTRY *pLdrTable; if (!pModules) return STATUS_INVALID_PARAMETER; ntStatus = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL); if (NT_SUCCESS(ntStatus)) { pLdrData = pbi.PebBaseAddress->Ldr; if (pLdrData != NULL) { pCurrentList = pLdrData->InLoadOrderModuleList.Flink; pList = pLdrData->InLoadOrderModuleList.Blink; while (pCurrentList != pList) { pLdrTable = reinterpret_cast<LDR_DATA_TABLE_ENTRY*>(pCurrentList); if (pLdrTable != NULL) { pModules->push_back(pLdrTable); pCurrentList = pLdrTable->InLoadOrderModuleList.Flink; continue; } break; } } } return ntStatus; } int main() { std::list<LDR_DATA_TABLE_ENTRY*> ModuleList; if (NT_SUCCESS(GetLoaderDataTableEntries(&ModuleList))) { for (LDR_DATA_TABLE_ENTRY* pLdrTable : ModuleList) { WCHAR szPdbFile[MAX_PATH]; if (GetPdbOfSystemFileW(pLdrTable->FullDllName.Buffer, szPdbFile)) { _tprintf(L"%s\n", szPdbFile); } else { _tprintf(L"%s is not found. \n", pLdrTable->FullDllName.Buffer); } } } getchar(); return 0; }