| 1439 | }; |
| 1440 | |
| 1441 | static _TEB* GetTEB(HANDLE hThread) |
| 1442 | { |
| 1443 | bool loadedManually = false; |
| 1444 | HMODULE module = GetModuleHandleA("ntdll.dll"); |
| 1445 | |
| 1446 | if (!module) |
| 1447 | { |
| 1448 | module = LoadLibraryA("ntdll.dll"); |
| 1449 | loadedManually = true; |
| 1450 | } |
| 1451 | |
| 1452 | NTSTATUS(__stdcall *NtQueryInformationThread)(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength); |
| 1453 | NtQueryInformationThread = reinterpret_cast<decltype(NtQueryInformationThread)>(GetProcAddress(module, "NtQueryInformationThread")); |
| 1454 | |
| 1455 | if (NtQueryInformationThread) |
| 1456 | { |
| 1457 | NT_TIB tib = { 0 }; |
| 1458 | THREAD_BASIC_INFORMATION tbi = { 0 }; |
| 1459 | |
| 1460 | NTSTATUS status = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), nullptr); |
| 1461 | if (status >= 0) |
| 1462 | { |
| 1463 | _TEB* teb = (_TEB*)tbi.TebBaseAddress; |
| 1464 | return teb; |
| 1465 | } |
| 1466 | } |
| 1467 | |
| 1468 | if (loadedManually) |
| 1469 | { |
| 1470 | FreeLibrary(module); |
| 1471 | } |
| 1472 | |
| 1473 | return NULL; |
| 1474 | } |
| 1475 | |
| 1476 | static void** GetThreadLocalAddressMap(HANDLE hThread) |
| 1477 | { |
no outgoing calls
no test coverage detected