白帽黑客系列教程之Windows驱动开发(64位环境)入门教程(七)

news/2025/2/25 22:51:03

为什么要写这篇文章呢?

作为一名白帽黑客,如果想要学习ROOTKIT攻防技术,就必须要有能力进行驱动开发

本文章仅提供学习,切勿将其用于不法手段!

在Windows操作系统的64位环境中,进行ROOTKIT攻防,就必须要学会Windows驱动开发

Windows驱动开发,是掌握Rootkit技术的硬性基础之一!

不会Windows环境下的驱动开发,你就难以透彻理解ROOTKIT攻防技术的真相!

接上一篇文章,我们主要来讲解一下,KMDF项目开发中的一些代码内容编写!

接下来,我们来讲解下,相应的源文件(device.c)中的代码内容  ^ _ ^  请看下文!

/*++


Module Name: 文件名和功能描述

    device.c - Device handling events for example driver. ( device.c 是KMDF驱动程序中设备处理文件,device.c 用于处理设备相关的事件,device.c 用于处理示例驱动程序的设备事件 )

Abstract: 文件内容的简要说明

   This file contains the device entry points and callbacks. ( device.c 包含设备的入口点和回调函数;Entry Points 是驱动程序的入口函数(例如:设备创建、初始化等);Callbacks 是驱动程序的事件回调函数(例如:设备插入、移除、I/O请求处理等) )
    
Environment: 开发或运行环境

    Kernel-mode Driver Framework 当前驱动程序是基于内核模式驱动框架(KMDF)开发的

--*/

#include "driver.h"   //驱动的主要头文件,通常包含驱动所需的函数声明、宏定义和数据结构
#include "device.tmh" //WPP(Windows Software Trace Preprocessor)相关的跟踪文件,用于调试和日志记录

//检查是否定义了ALLOC_PRAGMA宏
#ifdef ALLOC_PRAGMA                                 
#pragma alloc_text (PAGE, KMDFDriver1CreateDevice)  //将KMDFDriver1CreateDevice函数放置在可分页的内存段中(PAGE)(这是为了优化内存使用,当函数不运行时,可以将其从内存中换出,PAGE是KMDF中用于分页内存的宏)
#endif

//KMDF驱动程序中的设备创建函数(用于创建设备对象、初始化设备上下文、创建设备接口,并初始化I/O包和队列)

NTSTATUS
KMDFDriver1CreateDevice(
    _Inout_ PWDFDEVICE_INIT DeviceInit //_Inout_ 指示参数 DeviceInit 既是输入也是输出,PWDFDEVICE_INIT 表示参数 DeviceInit 是一个指向设备初始化结构的指针(框架会在设备创建成功后释放该结构)
    )
/*++

Routine Description: 函数的功能描述

    Worker routine called to create a device and its software resources. 这是一个工作例程(worker routine),用于创建设备及其软件资源(在KMDF驱动程序中,这通常是设备创建函数的一部分,负责初始化设备对象和相关资源)

Arguments: 函数的参数说明

    DeviceInit - Pointer to an opaque init structure. Memory for this
                    structure will be freed by the framework when the WdfDeviceCreate
                    succeeds. So don't access the structure after that point.

    DeviceInit:参数名称,指向一个不透明的初始化结构(PWDFDEVICE_INIT)。

                opaque init structure:表示该结构的具体内容对开发者是隐藏的,只能通过框架提供的API进行操作。

                Memory for this structure will be freed by the framework when the WdfDeviceCreate succeeds:

                当 WdfDeviceCreate 成功时,框架会释放该结构的内存。

                因此,在调用 WdfDeviceCreate 后,不应再访问该结构。

Return Value: 函数的返回值

    NTSTATUS  返回类型,表示函数执行的状态(NTSTATUS 是Windows内核开发中常用的状态码类型,用于指示成功或失败)

--*/
{
    WDF_OBJECT_ATTRIBUTES deviceAttributes; //设备对象的属性
    PDEVICE_CONTEXT deviceContext;          //指向设备上下文的指针 
    WDFDEVICE device;                       //设备对象句柄
    NTSTATUS status;                        //用于存储函数调用的返回状态

    PAGED_CODE(); //分页内存检查(确保函数在分页内存中运行,如果函数在非分页内存中运行,会触发断言)

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); //初始化设备属性(初始化设备对象的属性,并指定设备上下文类型为 DEVICE_CONTEXT(自定义的数据结构,通常在 device.h 中定义))

    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); //创建设备对象(调用 WdfDeviceCreate 创建设备对象,如果创建设备对象成功,device 将包含新创建设备的句柄)

    if (NT_SUCCESS(status)) { //检查设备创建状态(如果创建设备对象成功)
        //
        // Get a pointer to the device context structure that we just associated
        // with the device object. We define this structure in the device.h
        // header file. DeviceGetContext is an inline function generated by
        // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.
        // This function will do the type checking and return the device context.
        // If you pass a wrong object handle it will return NULL and assert if
        // run under framework verifier mode.
        //
        deviceContext = DeviceGetContext(device); //获取设备上下文(使用 DeviceGetContext 获取设备上下文,它是一个由 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME 宏生成的函数,用于类型检查和获取上下文)

        //
        // Initialize the context.
        //
        deviceContext->PrivateDeviceData = 0; //初始化设备上下文(初始化设备上下文中的私有数据,这里将 PrivateDeviceData 设置为 0)

        //
        // Create a device interface so that applications can find and talk
        // to us.
        //
        //创建设备接口(调用 WdfDeviceCreateDeviceInterface 创建设备接口)

        status = WdfDeviceCreateDeviceInterface(
            device,                         //设备对象句柄
            &GUID_DEVINTERFACE_KMDFDriver1, //设备接口的GUID(用于标识设备)
            NULL // ReferenceString           引用字符串,通常为 NULL
            );

        if (NT_SUCCESS(status)) { //检查设备接口创建状态(如果设备接口创建成功,继续初始化I/O包和队列)
            //
            // Initialize the I/O Package and any Queues
            //
            status = KMDFDriver1QueueInitialize(device); //初始化I/O包和队列(调用 KMDFDriver1QueueInitialize 初始化I/O包和队列,它是自定义函数,在 queue.c 中定义实现)
        }
    }

    return status; //返回状态码,表示函数执行结果
}
 

我在上面的代码中,增加了相应的注释,有助于学习Windows驱动开发的小白们能够理解每一行代码的用途!毕竟,学习 从 阅读 开始 !嘿嘿

(未完待续)


http://www.niftyadmin.cn/n/5866003.html

相关文章

Typora的Github主题美化

[!note] Typora的Github主题进行一些自己喜欢的修改,主要包括:字体、代码块、表格样式 美化前: 美化后: 一、字体更换 之前便看上了「中文网字计划」的「朱雀仿宋」字体,于是一直想更换字体,奈何自己拖延症…

gitlab初次登录为什么登不上去

今天又写了一次gitlab安装后,第一次登录的问题。 gitlab工作笔记_gitlab默认用户名密码-CSDN博客 因为又掉这个坑里了。 # 为什么第一次登录这么难? 第一是因为gitlab启动的时间很长,有时候以为装错了。 第二是初始密码,如果…

vue 修改el-tree高亮样式

vue 修改el-tree高亮样式 ::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content, ::v-deep .el-tree-node > .el-tree-node__content:hover {background-color: #eff8ee !important;color: #009764; }

超详细介绍map(multimap)的使用

map类的介绍 map的声明如下,Key是map底层关键字的类型,T是map底层value的类型。set默认要求Key支持小于比较,如果不支持或者需要的情况下我们可以自行传入仿函数,map底层存储数据的内存是从空间申请来的。一般情况下,我…

手撕跳表/数据结构

昨天leetcode每日一题是跳表,之前学redis就没去写跳表,这次就逃不过了。 这里使用了len数组,来表示每个数字之间的间隔,方便复杂的查询功能。 主要问题有 为什么len数组记录的是数字之间的间隔,不是每一层从头到尾…

MFC学习笔记-1

一、编辑框和按钮 //.h文件private:CString str;//给窗口类加了一个变量(定义一个成员变量),关联到IDC_EDIT1中(要在实现中关联,源文件文件夹中)CString str2;//接收button2,和IDC_EDIT2绑定 p…

Spring DIIoC

一.IoC 1.简介 什么是IoC?IoC,全称 Inversion of Control,控制反转。IoC是Spring的核心思想,Spring是⼀个“控制反转”的容器。 如果我们需要一个对象,正常来说我们是通过new一个对象,这个时候我们依赖的…

记录一下_treafik使用Gateway-APi使用的细节参数

一、这里说一下treafik最大的容易走入圈套的地方。 1、treafik默认不是hostnetwork模式。为了暴露自己出来它有一个LB类型的SVC。 这里的External_ip为我的节点IP,因为使用了k3s自带的LB,这个SVC就很容易绕进去。 1、第一个这个LB的作用是为了暴露treafi…