>I’m writting a device driver from which I need to execute code in the
context of the Winlogon process, specifically in the context of one of its
threads. For this I have to queue a kernel mode APC to one of Winlogon
already-created threads but don’t know how to get the Winlogon thread
list. Does anyone knows how to do this? Also, what’s the definition for
NtQueueApcThread?
To enumerate the threads, use ToolHelp or PSAPI. You can do it with native
API, but it is way harder
If for some reason you can’t use Win32 API calls:
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
The info class you need is SystemProcessesAndThreadsInformation (5), you
have to pass as SystemInformation a buffer large enough to hold all the
SYSTEM_PROCESSES and the SYSTEM_THREADS structures you need to find
winlogon. They will be returned with this layout:
SYSTEM_PROCESSES // process entry for the first process
SYSTEM_THREADS // a thread entry for every thread in the process
SYSTEM_THREADS
SYSTEM_THREADS
…
SYSTEM_THREADS
SYSTEM_PROCESSES // process entry for the second process
SYSTEM_THREADS // a thread entry for every thread in the process
…
The number of threads (i.e. the number of elements in the following
SYSTEM_THREADS array) is in the field ThreadCount of every process entry,
the array’s head is Threads[0], if you simply want to skip all the threads
and go to the next process in the list, move the pointer by NextEntryDelta
bytes. WinLogon can be identified this way:
Idle
|
± System
|
± smss.exe
|
± csrss.exe
± winlogon.exe
± os2ss.exe (optionally)
± psxss.exe (optionally)
That is: idle is always pid 0, System is the only process inherited from
Idle, smss is the only process inherited from System, of all the processes
inherited from smss the one with “winlogon” inside the name is WinLogon,
the others are the subsystems (I wish there was a cleaner way, though)
To open the thread:
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
);
You’ll need THREAD_SET_CONTEXT access to queue an APC. For the ClientId
parameter the process id is optional.
The prototype for NtQueueApcThread is:
NTSYSAPI
NTSTATUS
NTAPI
ZwQueueApcThread(
IN HANDLE ThreadHandle,
IN PKNORMAL_ROUTINE ApcRoutine,
IN PVOID ApcContext OPTIONAL,
IN PVOID Argument1 OPTIONAL,
IN PVOID Argument2 OPTIONAL
);
The APC routine must have this signature:
VOID (NTAPI *PKNORMAL_ROUTINE)(PVOID ApcContext, PVOID Argument1, PVOID
Argument2);
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com