zoukankan      html  css  js  c++  java
  • 《Windows内核安全与驱动开发》 4.4 线程与事件

    《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

     

    《Windows内核安全与驱动开发》 4.4 线程与事件

    一、开辟一个线程,参数为(打印内容+打印次数),利用线程实现打印。(申请堆内存防止栈清空)

    #include <ntifs.h>
    
    typedef struct {
        int num;
        UNICODE_STRING str;
    }MyContext, * PMyContext;
    
    static KEVENT event; // 全局变量中定义一个事件
    
    /*
        函数作用:线程函数,探究Event的作用
        参数1 context - 线程参数
    */
    void MyThradProc(IN PVOID context) {
        PMyContext p = (PMyContext)context;
    
        //
        // 将内容打印到日志中
        //
        DbgPrint("num is %wZ", p->str);
        DbgPrint("这是在次线程中");
        //
        // 激活该事件
        //
        KeSetEvent(&event, 0, FALSE);
        PsTerminateSystemThread(STATUS_SUCCESS);
    
    }
    
    void TestEvent() {
        HANDLE ThreadHandle; // 线程数组
        MyContext p;    // 线程参数数组
        NTSTATUS status;     // 状态
    
        //
        // 初始化时间,让主线程等待
        //
        KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    
        //
        // 为线程参数数组开辟内存
        //
        RtlInitUnicodeString(&p.str, L"hello world!");
    
        DbgPrint("这是在主线程中··
    ");
        DbgPrint("字符串为 :%wZ
    ", &p.str);
        //
        // 开辟线程
        //    
        status = PsCreateSystemThread(&ThreadHandle, 0, NULL, NULL, NULL, MyThradProc, (PVOID)&p);
    
        if (!NT_SUCCESS(status)) {
            return ;
        }
    
        //
        // 等待各个线程结束之后再退出
        //
        KeWaitForSingleObject(&event, Executive, KernelMode, 0, 0);
    }
    
    //提供一个卸载函数,让程序能卸载,如果没有这个函数,驱动将不能卸载。
    VOID UnDriver(PDRIVER_OBJECT driver)
    {
        KdPrint(("卸载驱动成功"));
    }
    //入口函数,相当于main。
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
    {
        TestEvent();
        driver->DriverUnload = UnDriver;
    
        return STATUS_SUCCESS;
    }

    二、实现一个线程挂起函数

    /
        // 线程睡眠
        //
        #define DELAY_ONE_MICROSECOND (-10)
        #define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000);
        VOID  MySleep(LONG msec) {
            LARGE_INTEGER my_interval;
            my_interval.QuadPart = DELAY_ONE_MILLISECOND;
            my_interval.QuadPart *= msec;
            KeDelayExecutionThread(KernelMode, 0, &my_interval);
        }

    三、利用Event事件来实现线程同步(可以利用栈内存来作为线程参数,线程完成之后,主线程才结束释放栈内存)

    #include <ntifs.h>
    
    typedef struct {
        int num;
        UNICODE_STRING str;
    }MyContext, * PMyContext;
    
    static KEVENT event; // 全局变量中定义一个事件
    
    /*
        函数作用:线程函数,探究Event的作用
        参数1 context - 线程参数
    */
    void MyThradProc(IN PVOID context) {
        PMyContext p = (PMyContext)context;
    
        //
        // 将内容打印到日志中
        //
        DbgPrint("num is %wZ", p->str);
        DbgPrint("这是在次线程中");
        //
        // 激活该事件
        //
        KeSetEvent(&event, 0, FALSE);
        PsTerminateSystemThread(STATUS_SUCCESS);
    
    }
    
    void TestEvent() {
        HANDLE ThreadHandle; // 线程数组
        MyContext p;    // 线程参数数组
        NTSTATUS status;     // 状态
    
        //
        // 初始化时间,让主线程等待
        //
        KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    
        //
        // 为线程参数数组开辟内存
        //
        RtlInitUnicodeString(&p.str, L"hello world!");
    
        DbgPrint("这是在主线程中··
    ");
        DbgPrint("字符串为 :%wZ
    ", &p.str);
        //
        // 开辟线程
        //    
        status = PsCreateSystemThread(&ThreadHandle, 0, NULL, NULL, NULL, MyThradProc, (PVOID)&p);
    
        if (!NT_SUCCESS(status)) {
            return ;
        }
    
        //
        // 等待各个线程结束之后再退出
        //
        KeWaitForSingleObject(&event, Executive, KernelMode, 0, 0);
    }
    
    //提供一个卸载函数,让程序能卸载,如果没有这个函数,驱动将不能卸载。
    VOID UnDriver(PDRIVER_OBJECT driver)
    {
        KdPrint(("卸载驱动成功"));
    }
    //入口函数,相当于main。
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
    {
        TestEvent();
        driver->DriverUnload = UnDriver;
    
        return STATUS_SUCCESS;
    }
  • 相关阅读:
    C#中的String.Format()方法
    JQuery中的each方法
    [开发笔记]-使用jquery获取url及url参数的方法
    ThinkPHP3.2.3学习笔记3---视图
    PHP命名空间namespace使用小结
    ThinkPHP3.2.3学习笔记2---模型
    PHP中的连贯操作
    关于新技术的学习问题
    ThinkPHP3.2.3学习笔记1---控制器
    WinXP下如何安装及御载MySQL服务
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12002615.html
Copyright © 2011-2022 走看看