频道栏目
首页 > 资讯 > 安全编程 > 正文

驱动笔记6:在内核中创建线程

09-01-11        来源:[db:作者]  
收藏   我要投稿


文章作者: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);
}

    上述代码在虚拟机中的运行效果如下图所示。



相关TAG标签
上一篇:获取和重设IIS匿名用户的密码
下一篇:驱动笔记5:获取系统时间和启动毫秒数
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站