更新时间:2009-1-11 3:17:46 收录:黑客天下 来源:hack4.com
文章作者:grayfox
作者主页:http://nokyo.blogbus.com
原始出处:http://nokyo.blogbus.com/logs/33484395.html
在ring3的编程中我们经常使用多线程来提高效率或满足一些特殊的要求,当然在内核中也是一样,我们经常需要使用几个线程来同步完成一些工作。
使用PsCreateSystemThread函数可以创建一个内核线程,它所属的进程名为system(PID=4),这个函数的第一个参数用来返回线程句柄,最后两个参数分别用于传入线程函数地址及参数。线程函数的格式与ring3的差不多,如下所示:VOID ThreadProc(IN PVOID context),这个VOID指针给了我们非常大的自由度。
在使用线程的时候,需要注意到一个同步的问题,比如我们把一个地址传递到线程函数中作一些处理,如果没有同步机制,可能等线程函数开始执行一些功能的时候而我们的调用函数已经结束了,这时候就会出现访问内存异常。
下面的代码我是从楚狂人的驱动教程中抄来的,使用KEVENT来同步,代码基本理解了,不过却没有达到设想的效果,暂时还不会内核调试,先搁下吧。
VOID
CreateThreadTest()
{
HANDLE hThread;
UNICODE_STRING ustrTest = RTL_CONSTANT_STRING(L"This is only a string for test!");
NTSTATUS status;
// 初始化事件
KeInitializeEvent(&kEvent, SynchronizationEvent, TRUE);
// 初始化字符串
RtlInitUnicodeString(&ustrTest, L"This is a string for test!");
status = PsCreateSystemThread(&hThread, 0, NULL, NULL, NULL, MyThreadFunc, (PVOID)&ustrTest);
if (!NT_SUCCESS(status))
{
KdPrint(("CreateThread Test Failed!"));
}
ZwClose(hThread);
// 等待事件
KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, 0);
}
// 线程函数
VOID
MyThreadFunc(
IN PVOID context
)
{
PUNICODE_STRING str = (PUNICODE_STRING)context;
KdPrint(("String In Thread : %wZ", str));
// 楚狂人的代码里面这里只有第一个参数,奇怪啊,DDK的帮助文档里面就是3个参数啊
KeSetEvent(&kEvent, 0, TRUE);
PsTerminateSystemThread(STATUS_SUCCESS);
}
上述代码在虚拟机中的运行效果如下图所示。