《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;
}
原文地址:https://www.cnblogs.com/onetrainee/p/12002615.html