Query a thread's start address for validation. @param ThreadId - The target thread's ID. @return The start address of the target thread. */
| 47 | @return The start address of the target thread. |
| 48 | */ |
| 49 | PVOID |
| 50 | ThreadFilter::GetThreadStartAddress ( |
| 51 | _In_ HANDLE ThreadId |
| 52 | ) |
| 53 | { |
| 54 | NTSTATUS status; |
| 55 | PVOID startAddress; |
| 56 | PETHREAD threadObject; |
| 57 | HANDLE threadHandle; |
| 58 | ULONG returnLength; |
| 59 | |
| 60 | startAddress = NULL; |
| 61 | threadHandle = NULL; |
| 62 | |
| 63 | // |
| 64 | // First look up the PETHREAD of the thread. |
| 65 | // |
| 66 | status = PsLookupThreadByThreadId(ThreadId, &threadObject); |
| 67 | if (NT_SUCCESS(status) == FALSE) |
| 68 | { |
| 69 | DBGPRINT("ThreadFilter!GetThreadStartAddress: Failed to lookup thread 0x%X by its ID.", ThreadId); |
| 70 | goto Exit; |
| 71 | } |
| 72 | |
| 73 | // |
| 74 | // Open a handle to the thread. |
| 75 | // |
| 76 | status = ObOpenObjectByPointer(threadObject, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, GENERIC_ALL, *PsThreadType, KernelMode, &threadHandle); |
| 77 | if (NT_SUCCESS(status) == FALSE) |
| 78 | { |
| 79 | DBGPRINT("ThreadFilter!GetThreadStartAddress: Failed to open handle to process with status 0x%X.", status); |
| 80 | goto Exit; |
| 81 | } |
| 82 | |
| 83 | // |
| 84 | // Query the thread's start address. |
| 85 | // |
| 86 | status = NtQueryInformationThread(threadHandle, ThreadQuerySetWin32StartAddress, &startAddress, sizeof(startAddress), &returnLength); |
| 87 | if (NT_SUCCESS(status) == FALSE) |
| 88 | { |
| 89 | DBGPRINT("ThreadFilter!GetThreadStartAddress: Failed to query thread start address with status 0x%X.", status); |
| 90 | goto Exit; |
| 91 | } |
| 92 | Exit: |
| 93 | if (threadHandle != NULL) |
| 94 | { |
| 95 | ZwClose(threadHandle); |
| 96 | } |
| 97 | return startAddress; |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | Called when a new thread is created. Ensure the thread is legit. |
nothing calls this directly
no test coverage detected