Enumerate all modules loaded in the process (DLL's), and their sections
| 198 | |
| 199 | // Enumerate all modules loaded in the process (DLL's), and their sections |
| 200 | std::vector<ProcessLoadedDll> ProcessEnumerateModules(HANDLE hProcess) { |
| 201 | std::vector<ProcessLoadedDll> processLoadedDlls; |
| 202 | |
| 203 | if (!hProcess || hProcess == INVALID_HANDLE_VALUE) { |
| 204 | LOG_A(LOG_ERROR, "ProcessEnumerateModules: Invalid process handle"); |
| 205 | return processLoadedDlls; |
| 206 | } |
| 207 | |
| 208 | PROCESS_BASIC_INFORMATION pbi = {}; |
| 209 | ULONG returnLength; |
| 210 | |
| 211 | // PBI |
| 212 | NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &returnLength); |
| 213 | if (status != 0) { |
| 214 | LOG_A(LOG_ERROR, "ProcessEnumerateModules: Error: Could not NtQueryInformationProcess for %lu, error: %lu", |
| 215 | static_cast<unsigned long>(status), GetLastError()); |
| 216 | return processLoadedDlls; |
| 217 | } |
| 218 | |
| 219 | // PEB |
| 220 | MYPEB peb = {}; |
| 221 | if (!ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) { |
| 222 | LOG_A(LOG_WARNING, "ProcessEnumerateModules: Error: Could not ReadProcessMemory1 error: %lu", |
| 223 | GetLastError()); |
| 224 | return processLoadedDlls; |
| 225 | } |
| 226 | |
| 227 | if (!peb.Ldr) { |
| 228 | LOG_A(LOG_WARNING, "ProcessEnumerateModules: PEB.Ldr is NULL"); |
| 229 | return processLoadedDlls; |
| 230 | } |
| 231 | |
| 232 | // PEB_LDR_DATA |
| 233 | PEB_LDR_DATA ldr = {}; |
| 234 | if (!ReadProcessMemory(hProcess, peb.Ldr, &ldr, sizeof(PEB_LDR_DATA), NULL)) { |
| 235 | LOG_A(LOG_WARNING, "ProcessEnumerateModules: ReadProcessMemory failed for PEB_LDR_DATA. Error: %lu", GetLastError()); |
| 236 | return processLoadedDlls; |
| 237 | } |
| 238 | |
| 239 | // InMemoryOrderModuleList |
| 240 | LIST_ENTRY* head = &ldr.InMemoryOrderModuleList; |
| 241 | LIST_ENTRY* current = ldr.InMemoryOrderModuleList.Flink; |
| 242 | |
| 243 | // Prevent infinite loop by limiting iterations |
| 244 | int maxIterations = 1000; |
| 245 | int iteration = 0; |
| 246 | |
| 247 | while (current != head && iteration < maxIterations) { |
| 248 | ProcessLoadedDll processLoadedDll = {}; |
| 249 | |
| 250 | _LDR_DATA_TABLE_ENTRY entry = {}; |
| 251 | if (!ReadProcessMemory(hProcess, CONTAINING_RECORD(current, _LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks), |
| 252 | &entry, sizeof(_LDR_DATA_TABLE_ENTRY), NULL)) |
| 253 | { |
| 254 | LOG_A(LOG_WARNING, "ProcessEnumerateModules: ReadProcessMemory failed for LDR_DATA_TABLE_ENTRY. Error: %lu", GetLastError()); |
| 255 | break; |
| 256 | } |
| 257 |