PsSetCreateThreadNotifyRoutine IRQL and ZwQueryInformationThread

The thread notify callback for PsSetCreateThreadNotifyRoutine can run at either PASSIVE or APC. I need to call ZwQueryInformationThread on thread creation to capture thread start address information, however ZwQueryInformationThread must be called at PASSIVE only. What are my options here to avoid a bsod if my notification callback gets called at APC? Can I just queue a work item and pass the process and thread id to the work item routine and call ZwQueryInformationThread at that point? I guess in that case you’d have to just hope the thread hadn’t already exited before the work item executed?

The first question is what are you trying to get from ZwQueryInformationThread? The only officially documented use is to get the ThreadPagePriority. There may be other ways to get the information you are looking for.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

I am requesting ThreadQuerySetWin32StartAddress. I am requesting the thread start address to be able to call ZwQueryVirtualMemory and capture MemoryBasicInformation about the process memory the thread is executing against. Specifically to get memory state and type information.

I guess in that case you’d have to just hope the thread hadn’t already exited before the work item executed?

IIRC, PsSetCreateThreadNotifyRoutine callback gets executed in context of newly-created thread (which, IIRC,was officially stated in the documentation) , which means the thread just cannot exit until the callback returns. Therefore, you can post a workitem and wait on event in your callback…

I am requesting ThreadQuerySetWin32StartAddress

Actually, I am not 100% sure this info is available at the time your callback gets invoked, but this is already a different story…

Anton Bassov

IIRC, PsSetCreateThreadNotifyRoutine callback gets executed in context of newly-created thread
PsSetCreateThreadNotifyRoutine callback is executed in the context of the thread that created the new thread. PsSetCreateNotifyRoutineEx allows you to get into the context of the created thread, but it is only available starting in Windows 10 according to the documentation. It certainly isn’t exported in ntoskrnl going back to Windows 7 as far as I can see.

Actually, I am not 100% sure this info is available at the time your callback gets invoked, but this is already a different story…

It has been available every time in my testing so far. Why wouldn’t it be available?