| 248 | // |
| 249 | |
| 250 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast) |
| 251 | { |
| 252 | PBYTE pbLast = (PBYTE)hModuleLast + MM_ALLOCATION_GRANULARITY; |
| 253 | |
| 254 | MEMORY_BASIC_INFORMATION mbi; |
| 255 | ZeroMemory(&mbi, sizeof(mbi)); |
| 256 | |
| 257 | // Find the next memory region that contains a mapped PE image. |
| 258 | // |
| 259 | for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) { |
| 260 | if (VirtualQuery(pbLast, &mbi, sizeof(mbi)) <= 0) { |
| 261 | break; |
| 262 | } |
| 263 | |
| 264 | // Skip uncommitted regions and guard pages. |
| 265 | // |
| 266 | if ((mbi.State != MEM_COMMIT) || |
| 267 | ((mbi.Protect & 0xff) == PAGE_NOACCESS) || |
| 268 | (mbi.Protect & PAGE_GUARD)) { |
| 269 | continue; |
| 270 | } |
| 271 | |
| 272 | __try { |
| 273 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbLast; |
| 274 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE || |
| 275 | (DWORD)pDosHeader->e_lfanew > mbi.RegionSize || |
| 276 | (DWORD)pDosHeader->e_lfanew < sizeof(*pDosHeader)) { |
| 277 | continue; |
| 278 | } |
| 279 | |
| 280 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + |
| 281 | pDosHeader->e_lfanew); |
| 282 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { |
| 283 | continue; |
| 284 | } |
| 285 | |
| 286 | SetLastError(NO_ERROR); |
| 287 | return (HMODULE)pDosHeader; |
| 288 | } |
| 289 | #pragma prefast(suppress:28940, "A bad pointer means this probably isn't a PE header.") |
| 290 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? |
| 291 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { |
| 292 | continue; |
| 293 | } |
| 294 | } |
| 295 | return NULL; |
| 296 | } |
| 297 | |
| 298 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule) |
| 299 | { |
no outgoing calls
no test coverage detected
searching dependent graphs…