void LoadProcessModules(HANDLE hProcess, ULONG procID) { if(!ntQueryInformationProcess) { return false; } SIZE_T len = 0; // get the peb address PROCESS_BASIC_INFORMATION pbi; if(!NT_SUCCESS(ntQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &len))) { return false; } // read the loader data address char* pLdrDataOffset = (char*)pbi.PebBaseAddress + offsetof(PEB, Ldr); PPEB_LDR_DATA pLdrData; if(!ReadProcessMemory(hProcess, pLdrDataOffset, &pLdrData, sizeof(pLdrData), &len)) { return false; } // read the actual loader data, from the pointer read above PEB_LDR_DATA ldrData; if(!ReadProcessMemory(hProcess, pLdrData, &ldrData, sizeof(ldrData), &len)) { return false; } // initialize a new symbol table entry HANDLE hDbgProc = PIDHANDLE(procID); { WinLib::CSectionLock lock(dbgLock); if(!SymInitialize(hDbgProc, symPath, FALSE)) { return false; } SymRegisterCallback64(hDbgProc, &SymCallback, reinterpret_cast(this)); } // traverse the module list, reading each modules entry LIST_ENTRY* pMod = ldrData.InMemoryOrderModuleList.Flink; LIST_ENTRY* pStart = pMod; do { LDR_DATA_TABLE_ENTRY* entryBase = CONTAINING_RECORD(pMod, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); LDR_DATA_TABLE_ENTRY ldrMod = {0}; if(ReadProcessMemory(hProcess, entryBase, &ldrMod, sizeof(ldrMod), &len)) { if(ldrMod.DllBase) { std::wstring dllName(ldrMod.FullDllName.Length / sizeof(WCHAR), 0); if(ReadProcessMemory(hProcess, ldrMod.FullDllName.Buffer, &dllName[0], ldrMod.FullDllName.Length, &len)) { boost::algorithm::to_lower(dllName); WinLib::CSectionLock lock(dbgLock); SymLoadModuleEx(hDbgProc, NULL, dllName.c_str(), NULL, reinterpret_cast(ldrMod.DllBase), 0, NULL, 0); } } pMod = ldrMod.InMemoryOrderLinks.Flink; } } while(pMod != pStart); }