| 74 | } |
| 75 | |
| 76 | DWORD CThreadFunctions::GetMainThreadId() |
| 77 | { |
| 78 | auto hSnap = g_winapiApiTable->CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL); |
| 79 | if (!IS_VALID_HANDLE(hSnap)) |
| 80 | { |
| 81 | DEBUG_LOG(LL_ERR, "CreateToolhelp32Snapshot fail! Error: %u", g_winapiApiTable->GetLastError()); |
| 82 | return 0; |
| 83 | } |
| 84 | |
| 85 | THREADENTRY32 ti = { 0 }; |
| 86 | ti.dwSize = sizeof(ti); |
| 87 | |
| 88 | auto pIDH = (IMAGE_DOS_HEADER*)g_winapiModuleTable->hBaseModule; |
| 89 | if (pIDH->e_magic != IMAGE_DOS_SIGNATURE) |
| 90 | return false; |
| 91 | |
| 92 | auto pINH = (IMAGE_NT_HEADERS32*)(pIDH->e_lfanew + (DWORD)pIDH); |
| 93 | if (pINH->Signature != IMAGE_NT_SIGNATURE) |
| 94 | return false; |
| 95 | |
| 96 | auto pEntryPoint = pINH->OptionalHeader.AddressOfEntryPoint + pINH->OptionalHeader.ImageBase; |
| 97 | if (!pEntryPoint) |
| 98 | return 0; |
| 99 | |
| 100 | if (g_winapiApiTable->Thread32First(hSnap, &ti)) |
| 101 | { |
| 102 | do { |
| 103 | if (ti.th32OwnerProcessID == g_winapiApiTable->GetCurrentProcessId()) |
| 104 | { |
| 105 | auto hThread = g_winapiApiTable->OpenThread(THREAD_QUERY_INFORMATION, false, ti.th32ThreadID); |
| 106 | if (IS_VALID_HANDLE(hThread)) |
| 107 | { |
| 108 | auto dwStartAddress = GetThreadStartAddress(hThread); |
| 109 | if (dwStartAddress == pEntryPoint) |
| 110 | { |
| 111 | g_winapiApiTable->CloseHandle(hThread); |
| 112 | g_winapiApiTable->CloseHandle(hSnap); |
| 113 | |
| 114 | return ti.th32ThreadID; |
| 115 | } |
| 116 | g_winapiApiTable->CloseHandle(hThread); |
| 117 | } |
| 118 | } |
| 119 | } while (g_winapiApiTable->Thread32Next(hSnap, &ti)); |
| 120 | } |
| 121 | |
| 122 | g_winapiApiTable->CloseHandle(hSnap); |
| 123 | return 0; |
| 124 | } |
| 125 | |
| 126 | |
| 127 | DWORD CThreadFunctions::GetThreadIdFromAddress(DWORD dwAddress) |
nothing calls this directly
no test coverage detected