每日总结-第三十二天-windows内核编程1

2020-05-12  本文已影响0人  SamiraG

碎碎念

买了书要看完呀==毕竟书很贵,网速慢真的很痛苦==软件装了好久都没装上。

环境准备

内核入口函数

NTSTATUS DriverEntry{
    PDRIVER_OBJECT DriverObject;  // 当前驱动所对应的驱动对象指针
    PUNICODE_STRING RegistryPath;  // 当前驱动所对应的注册表位置
}
typedef struct _UNICODE_STRING{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;  // 不要求以'\0'结束
} UNICODE_STRING, *PUNICODE_STRING;
// RegistryPath表示注册表的位置,但是表示方式是内核级别的表示方式,而不是用户态的表示方式
typedef LONG NTSTATUS; // 返回值实际上为LONG类型
# define STATUS_SUCCESS ((NTSTATUS)0x00000000L) //返回STATUS_SUCCESS则表示成功

内核驱动作为windows服务运行,在执行具体代码之前,驱动SYS文件首先会被映射到内核地址空间,作为内核的一个驱动模块,接着系统对这个驱动模块执行导入表初始化、修正重定位表中对应的数据偏移等操作,最后系统会调用该驱动模式的DriverEntry入口函数,如果这个入口函数返回STATUS_SUCCESS,系统认为这个驱动初始化成功;如果这个入口函数返回其他值,系统认为驱动初始化失败,系统执行一系列的清理工作,并把驱动模块从内核空间中移除。

helloworld

#include "ntddk.h"
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
    if(DriverObject != NULL)
    {
        DbgPrint("[%ws]Driver Upload, Driver Object Address:%p", __FUNCTIONW__, DriverObject);
    }
    return;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    DbgPrint("[%ws]Hello Kernel World\n", __FUNCTIONW__);
    if(RegistryPath != NULL)
    {
        // Register不是'\0'结尾,所以不能直接使用%ws打印
        DbgPrint("[%ws]Driver RegistryPath:%wZ\n", __FUNCTIONW__, RegistryPath);
    }
    if(DriverObject != NULL)
    {
        DbgPrint("[%ws]Driver Object Address:%p\n", __FUNCTIONW__, DriverObject);
        DriverObject->DriverUnload = DriverUnload;
    }
    return STATUS_SUCCESS;
}

当一个内核驱动被要求停止时,DriverObject->DriverUnload指向的函数就会被调用,在这个函数里面可以执行一些清理相关的工作。但是DriverUnload也不是必须的,如果开发者没有提供DriverUnload函数则该驱动不支持停止,这个特性会被很多安全软件利用,刻意不提供DriverUnload函数,防止服务被恶意中止。

一些概念

上下文Context

上下文泛指CPU在执行代码时,该代码所处的环境与状态,通俗来讲,这些环境状态包含(不仅限):当前代码所属线程、中断请求级别、CPU寄存器各状态等。

上一篇下一篇

猜你喜欢

热点阅读