Get main thread ID of a process using NtQuerySystemInformation
| 134 | } |
| 135 | // Get main thread ID of a process using NtQuerySystemInformation |
| 136 | DWORD GetMainThreadId(DWORD pid) |
| 137 | { |
| 138 | ULONG bufferSize = 0x10000; |
| 139 | PVOID buffer = nullptr; |
| 140 | NTSTATUS status; |
| 141 | PNtQuerySystemInformation NtQuerySystemInformation = |
| 142 | (PNtQuerySystemInformation)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtQuerySystemInformation"); |
| 143 | |
| 144 | do { |
| 145 | buffer = VirtualAlloc(nullptr, bufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); |
| 146 | if (!buffer) return 0; |
| 147 | |
| 148 | status = NtQuerySystemInformation(SystemProcessInformation, buffer, bufferSize, nullptr); |
| 149 | if (status == STATUS_INFO_LENGTH_MISMATCH) { |
| 150 | VirtualFree(buffer, 0, MEM_RELEASE); |
| 151 | bufferSize *= 2; |
| 152 | } |
| 153 | } while (status == STATUS_INFO_LENGTH_MISMATCH); |
| 154 | |
| 155 | if (!NT_SUCCESS(status)) { |
| 156 | VirtualFree(buffer, 0, MEM_RELEASE); |
| 157 | return 0; |
| 158 | } |
| 159 | |
| 160 | DWORD mainThreadId = 0; |
| 161 | LARGE_INTEGER earliestCreateTime = { 0x7FFFFFFFFFFFFFFF }; |
| 162 | auto spi = (MY_SYSTEM_PROCESS_INFORMATION*)buffer; |
| 163 | |
| 164 | while (true) { |
| 165 | if ((DWORD)(ULONG_PTR)spi->UniqueProcessId == pid) |
| 166 | { |
| 167 | if (spi->NumberOfThreads > 0) |
| 168 | { |
| 169 | mainThreadId = (DWORD)(ULONG_PTR)spi->Threads[0].ClientId.UniqueThread; |
| 170 | } |
| 171 | break; |
| 172 | } |
| 173 | |
| 174 | if (spi->NextEntryOffset == 0) break; |
| 175 | spi = (MY_SYSTEM_PROCESS_INFORMATION*)((BYTE*)spi + spi->NextEntryOffset); |
| 176 | } |
| 177 | |
| 178 | VirtualFree(buffer, 0, MEM_RELEASE); |
| 179 | return mainThreadId; |
| 180 | } |
| 181 | |
| 182 | void ResumeProcessLoop(DWORD pid) |
| 183 | { |