PsCreateSystemThread 创建一个执行在内核模式的系统线程。
注意:创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。
函数原型:
NTSTATUS PsCreateSystemThread(
_Out_ PHANDLE ThreadHandle,
_In_ ULONG DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ HANDLE ProcessHandle,
_Out_opt_ PCLIENT_ID ClientId,
_In_ PKSTART_ROUTINE StartRoutine,
_In_opt_ PVOID StartContext
);
ThreadHandle [out]
返回的handle。当此handle不再使用时,调用ZwClose关闭。对于windows vista以及以后版本,这个handle是一个内核句柄。
DesiredAccess [in]
ACCESS_MASK值,创建的权限。一般取THREAD_ALL_ACCESS。
ObjectAttributes [in, optional]
线程属性,一般设为null。
ProcessHandle [in, optional]
线程所在地址空间的进程的handle。对于驱动线程,通常设为NULL。也可以设为NtCurrentProcess()指定为当前进程。
ClientId [out, optional]
对于驱动线程设为null。
StartRoutine [in]
函数指针,创建的系统线程的入口指针。此函数接受一个参数,就是StartContext。
StartContext [in, optional]
线程执行时传给StartRoutine的参数。
返回值
PsCreateSystemThread成功返回 STATUS_SUCCESS。
例子1:
NTSTATUS lstatus;
lstatus = PsCreateSystemThread( &hThread,
0,
NULL, //或者THREAD_ALL_ACCESS
NtCurrentProcess(),
NULL,
(PKSTART_ROUTINE)ThreadProc,
NULL );
if (!NT_SUCCESS(lstatus))
{
;
}
NTSTATUS
ThreadProc()
{
DbgPrint("CreateThread Successfully");
//创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。
PsTerminateSystemThread(STATUS_SUCCESS);
}
2.提供一种方式来通知线程终止并等待终止发生。
typedef struct _DEVICE_EXTENSION {
...
KEVENT evKill;//在设备扩展中声明一个KEVENT对象
PKTHREAD thread;
};
NTSTATUS StartThread(PDEVICE_EXTENSION pdx)
{
NTSTATUS status;
HANDLE hthread;
KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);
status = PsCreateSystemThread(&hthread, //创建新线程
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE) ThreadProc,
pdx);
if (!NT_SUCCESS(status))
return status;
ObReferenceObjectByHandle(hthread, //为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。
THREAD_ALL_ACCESS, //调用ObReferenceObjectByHandle获得这个地址。
NULL,
KernelMode,
(PVOID*) &pdx->thread,
NULL);
ZwClose(hthread); //现在可以关闭线程句柄了,因为已经得到thread
return STATUS_SUCCESS;
}
VOID StopThread(PDEVICE_EXTENSION pdx)
{
KeSetEvent(&pdx->evKill, 0, FALSE);
KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);
ObDereferenceObject(pdx->thread);
}
VOID ThreadProc(PDEVICE_EXTENSION pdx)
{
...
KeWaitForXxx(<at least pdx->evKill>);
...
PsTerminateSystemThread(STATUS_SUCCESS);
}