SEH-wrapped PE parse: reads from dllBase may fault on unmapped pages during module teardown. Returns true if newMod was populated. Kept free of C++ objects with destructors so MSVC allows the __try/__except (C2712).
| 156 | // module teardown. Returns true if newMod was populated. Kept free of C++ |
| 157 | // objects with destructors so MSVC allows the __try/__except (C2712). |
| 158 | static bool parseModuleHeader(ULONG64 pc, const BYTE *dllBase, CachedModule &newMod) noexcept { |
| 159 | __try { |
| 160 | const IMAGE_DOS_HEADER *dos = (const IMAGE_DOS_HEADER*)dllBase; |
| 161 | if (dos->e_magic != IMAGE_DOS_SIGNATURE) { addNegCache(pc); return false; } |
| 162 | const IMAGE_NT_HEADERS64 *nt = (const IMAGE_NT_HEADERS64*)(dllBase + dos->e_lfanew); |
| 163 | if (nt->Signature != IMAGE_NT_SIGNATURE || |
| 164 | nt->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_EXCEPTION) { |
| 165 | addNegCache(pc); return false; |
| 166 | } |
| 167 | const IMAGE_DATA_DIRECTORY &excDir = |
| 168 | nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION]; |
| 169 | if (!excDir.VirtualAddress || excDir.Size < sizeof(RUNTIME_FUNCTION)) { |
| 170 | addNegCache(pc); return false; |
| 171 | } |
| 172 | newMod.base = (ULONG64)dllBase; |
| 173 | newMod.end = (ULONG64)dllBase + nt->OptionalHeader.SizeOfImage; |
| 174 | newMod.pdata = (PRUNTIME_FUNCTION)(dllBase + excDir.VirtualAddress); |
| 175 | newMod.pdataLast = (excDir.Size / sizeof(RUNTIME_FUNCTION)) - 1; |
| 176 | return true; |
| 177 | } __except (EXCEPTION_EXECUTE_HANDLER) { |
| 178 | addNegCache(pc); |
| 179 | return false; |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // Incremental add for late-loaded DLLs via GetModuleHandleExW — avoids full snapshot reinit. |
| 184 | // |
no test coverage detected