Called when a new thread is created. Ensure the thread is legit. @param ProcessId - The process ID of the process receiving the new thread. @param ThreadId - The thread ID of the new thread. @param Create - Whether or not this is termination of a thread or creation. */
| 104 | @param Create - Whether or not this is termination of a thread or creation. |
| 105 | */ |
| 106 | VOID |
| 107 | ThreadFilter::ThreadNotifyRoutine ( |
| 108 | _In_ HANDLE ProcessId, |
| 109 | _In_ HANDLE ThreadId, |
| 110 | _In_ BOOLEAN Create |
| 111 | ) |
| 112 | { |
| 113 | ULONG processThreadCount; |
| 114 | PVOID threadStartAddress; |
| 115 | PSTACK_RETURN_INFO threadCreateStack; |
| 116 | ULONG threadCreateStackSize; |
| 117 | PUNICODE_STRING threadCallerName; |
| 118 | PUNICODE_STRING threadTargetName; |
| 119 | |
| 120 | threadCreateStack = NULL; |
| 121 | threadCreateStackSize = 20; |
| 122 | threadCallerName = NULL; |
| 123 | threadTargetName = NULL; |
| 124 | |
| 125 | // |
| 126 | // We don't really care about thread termination or if the thread is kernel-mode. |
| 127 | // |
| 128 | if (Create == FALSE || ExGetPreviousMode() == KernelMode) |
| 129 | { |
| 130 | return; |
| 131 | } |
| 132 | |
| 133 | // |
| 134 | // If we can't find the process or it's the first thread of the process, skip it. |
| 135 | // |
| 136 | if (ImageHistoryFilter::AddProcessThreadCount(ProcessId, &processThreadCount) == FALSE || |
| 137 | processThreadCount <= 1) |
| 138 | { |
| 139 | return; |
| 140 | } |
| 141 | |
| 142 | // |
| 143 | // Walk the stack. |
| 144 | // |
| 145 | ThreadFilter::Walker.WalkAndResolveStack(&threadCreateStack, &threadCreateStackSize, STACK_HISTORY_TAG); |
| 146 | |
| 147 | // |
| 148 | // Grab the name of the caller. |
| 149 | // |
| 150 | if (ImageHistoryFilter::GetProcessImageFileName(PsGetCurrentProcessId(), &threadCallerName) == FALSE) |
| 151 | { |
| 152 | goto Exit; |
| 153 | } |
| 154 | |
| 155 | threadTargetName = threadCallerName; |
| 156 | |
| 157 | // |
| 158 | // We only need to resolve again if the target process is a different than the caller. |
| 159 | // |
| 160 | if (PsGetCurrentProcessId() != ProcessId) |
| 161 | { |
| 162 | // |
| 163 | // Grab the name of the target. |
nothing calls this directly
no test coverage detected