使用系统线程,在驱动中停止,等待很容易使整个系统陷入"停顿",最后可能只能重启电脑.但一个单独的线程长期等待也不至于会对系统造成致命的影响.有些任务需要长期不断执行,为这些内容启动一个特殊的线程来执行是最好的方法.在驱动中生成线程一般是系统进程,系统线程所在的进程名是 "System" ,创建线程内核API是:
NTSTATUS
PsCreateSystemThread(
_Out_ PHANDLE ThreadHandle,//返回的线程句柄指针
_In_ ULONG DesiredAccess,//设置为0
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,//填NULL
_In_opt_ HANDLE ProcessHandle,//填NULL
_Out_opt_ PCLIENT_ID ClientId,//填NULL
_In_ PKSTART_ROUTINE StartRoutine,//用于该线程启动时执行的函数
_In_opt_ _When_(return >= 0, __drv_aliasesMem) PVOID StartContext//传入该函数的参数指针
);
PKSTART_ROUTINE 的原型如下:
VOID
KSTART_ROUTINE (
_In_ PVOID StartContext//StartContext就是PsCreateSystemThread传入的参数
);
需要注意的是,线程的结束应该在线程中自己调用 PsTerminateSystemThread 来完成
得到的线程句柄需要使用 ZwClose 来关闭,注意,关闭句柄并不结束线程
使用的代码:
#include
//全局静态字符串,用来打印,指向 WCHAR 数组应该也可以
UNICODE_STRING str = RTL_CONSTANT_STRING(L"cycle print");
//线程执行函数
VOID misakathreadproc(PVOID StartContext){
PUNICODE_STRING str = (PUNICODE_STRING)StartContext;
KdPrint(("oh:%wZ\r\n",str));
//结束自己
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID DriverUnload(PDRIVER_OBJECT driver){
DbgPrint("misaka: uninstall driver\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path){
//线程句柄
HANDLE thread = NULL;
NTSTATUS status;
//创建线程
status = PsCreateSystemThread(&thread, 0, NULL, NULL, NULL, misakathreadproc,(PVOID)&str);
if (!NT_SUCCESS(status)){
//错误
}
ZwClose(thread);
KdPrint(("misaka:thread create success\r\n"));
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
输出结果,第二行是线程执行的:
misaka:thread create success
oh:cycle print
misaka: uninstall driver