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;
    }
  • 相关阅读:
    Java的类演进过程
    P112、面试题16:反转链表
    P107、面试题15:链表中倒数第K个结点
    Java对象相关元素的初始化过程
    P102、面试题14:调整数组顺序使奇数位于偶数前面
    P99、面试题13:在o(1)时间删除链表结点
    面试常考的数据结构Java实现
    Linux命令面试常考的简单汇总
    操作系统与进程基础知识
    python--process
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12002615.html
Copyright © 2011-2022 走看看