为什么要写这篇文章呢?
作为一名白帽黑客,如果想要学习ROOTKIT攻防技术,就必须要有能力进行驱动开发!
本文章仅提供学习,切勿将其用于不法手段!
在Windows操作系统的64位环境中,进行ROOTKIT攻防,就必须要学会Windows驱动开发!
Windows驱动开发,是掌握Rootkit技术的硬性基础之一!
不会Windows环境下的驱动开发,你就难以透彻理解ROOTKIT攻防技术的真相!
接上一篇文章,我们主要来讲解一下,KMDF项目开发中的一些代码内容编写!
接下来,我们来讲解下,相应的源文件(queue.c)中的代码内容 ^ _ ^ 请看下文!
/*++
Module Name: 模块名称(通常是文件名)
queue.c 用于处理队列相关的事件
Abstract: 文件的抽象描述(概括文件的主要内容)
This file contains the queue entry points and callbacks.
说明 queue.c 文件包含队列的入口点和回调函数(Entry Points,队列的初始化函数(例如,队列创建、配置等);Callbacks,队列的事件回调函数(例如I/O请求处理、取消请求处理等))
Environment: 开发环境或运行环境
Kernel-mode Driver Framework 表示该驱动程序是基于内核模式驱动框架(KMDF)开发的
--*/
#include "driver.h" //驱动的主要头文件(通常包含驱动所需的函数声明、宏定义和数据结构)
#include "queue.tmh" //WPP(Windows Software Trace Preprocessor)相关的跟踪文件,用于调试和日志记录
#ifdef ALLOC_PRAGMA //检查是否定义了ALLOC_PRAGMA宏
#pragma alloc_text (PAGE, KMDFDriver1QueueInitialize) //将KMDFDriver1QueueInitialize函数放置在可分页的内存段中(PAGE,是KMDF中用于分页内存的宏。为了优化内存使用,当函数不运行时,可以将其从内存中换出)
#endif
//KMDF(Kernel-Mode Driver Framework)驱动程序中的队列初始化函数(主要功能是:配置默认的 I/O队列 、设置队列的回调函数(例如,设备控制请求处理和停止请求处理)、创建队列对象)
NTSTATUS
KMDFDriver1QueueInitialize(
_In_ WDFDEVICE Device //_In_ 指示参数 Device 是输入参数,WDFDEVICE 表示参数 Device 是框架设备对象的句柄
)
/*++
Routine Description:
The I/O dispatch callbacks for the frameworks device object
are configured in this function.
A single default I/O Queue is configured for parallel request
processing, and a driver context memory allocation is created
to hold our structure QUEUE_CONTEXT.
Arguments:
Device - Handle to a framework device object.
Return Value:
VOID
--*/
{
WDFQUEUE queue; //队列对象句柄
NTSTATUS status; //用于存储函数调用的返回状态
WDF_IO_QUEUE_CONFIG queueConfig; //队列配置结构
PAGED_CODE(); //确保函数在分页内存中运行(如果函数在非分页内存中运行,会触发断言)
//
// Configure a default queue so that requests that are not
// configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
// other queues get dispatched here.
//
//初始化队列配置(初始化队列配置,指定队列的调度类型为并行调度(WdfIoQueueDispatchParallel)(并行调度,允许多个请求被同时进行处理))
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
&queueConfig, //队列配置结构
WdfIoQueueDispatchParallel //并行调度代码( 值:2 )
);
//设置队列回调函数
queueConfig.EvtIoDeviceControl = KMDFDriver1EvtIoDeviceControl; //设备控制请求的回调函数
queueConfig.EvtIoStop = KMDFDriver1EvtIoStop; //停止请求的回调函数
//创建队列对象(调用 WdfIoQueueCreate 创建队列对象)
status = WdfIoQueueCreate(
Device, //设备对象句柄
&queueConfig, //队列配置结构
WDF_NO_OBJECT_ATTRIBUTES, //指定队列对象的属性(这里为默认属性)
&queue //返回创建的队列对象句柄
);
if(!NT_SUCCESS(status)) { //检查队列创建状态(如果队列创建失败,记录错误日志并返回错误状态)
//TraceEvents,是WPP提供的宏,用于记录日志;
//TraceEvents 函数参数 TRACE_LEVEL_ERROR,日志级别,表示错误信息;
//TraceEvents 函数参数 TRACE_QUEUE,日志类别,通常用于标识日志的来源(这里是队列相关);
///TraceEvents 函数参数 "WdfIoQueueCreate failed %!STATUS!" 是日志消息格式字符串(“% !STATUS!”是WPP的格式化占位符,用于将 NTSTATUS 类型的值转换为可读的字符串)
//TraceEvents 函数参数 status 是 NTSTATUS 类型的变量,表示函数调用的返回状态
TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status); //记录错误日志(使用WPP(Windows Software Trace Preprocessor)工具将错误信息输出到调试器或日志文件中)
return status; //返回函数执行的状态码
}
return status; //返回状态码,表示函数执行结果
}
//回调函数(驱动程序中处理设备控制请求(IRP_MJ_DEVICE_CONTROL)的回调函数,主要功能是:处理设备控制请求(IOCTL)、记录请求的相关信息(如队列、请求句柄、缓冲区长度、控制代码等)、完成请求并返回成功状态)
VOID
KMDFDriver1EvtIoDeviceControl(
_In_ WDFQUEUE Queue, //_In_ 指示参数是输入参数,WDFQUEUE Queue 请求关联的队列对象句柄
_In_ WDFREQUEST Request, //_In_ 指示参数是输入参数,WDFREQUEST Request 请求对象句柄
_In_ size_t OutputBufferLength, //_In_ 指示参数是输入参数,OutputBufferLength 输出缓冲区的长度(字节数)
_In_ size_t InputBufferLength, //_In_ 指示参数是输入参数,InputBufferLength 输入缓冲区的长度(字节数)
_In_ ULONG IoControlCode //_In_ 指示参数是输入参数,IoControlCode 设备控制代码(IOCTL)
)
/*++
Routine Description:
This event is invoked when the framework receives IRP_MJ_DEVICE_CONTROL request.
Arguments:
Queue - Handle to the framework queue object that is associated with the
I/O request.
Request - Handle to a framework request object.
OutputBufferLength - Size of the output buffer in bytes
InputBufferLength - Size of the input buffer in bytes
IoControlCode - I/O control code.
Return Value:
VOID
--*/
{
//日志记录(/TraceEvents,是WPP提供的宏,用于记录日志)
TraceEvents(
TRACE_LEVEL_INFORMATION, //日志级别,表示一般信息
TRACE_QUEUE, //日志类别,通常用于标识日志的来源(这里是队列相关)
"%!FUNC! Queue 0x%p, Request 0x%p OutputBufferLength %d InputBufferLength %d IoControlCode %d", //日志消息格式字符串,其中“%!FUNC!”是WPP的格式化占位符,表示当前函数名
Queue, //队列对象句柄的指针地址
Request, //请求对象句柄的指针地址
(int) OutputBufferLength, //输出缓冲区的长度
(int) InputBufferLength, //输入缓冲区的长度
IoControlCode //设备控制代码
);
WdfRequestComplete(Request, STATUS_SUCCESS); //完成请求(完成请求并返回状态,参数 Request 是请求对象句柄;参数 STATUS_SUCCESS 表示请求成功完成)
return; //函数返回(无返回值)
}
//回调函数(KMDF(Kernel-Mode Driver Framework)驱动程序中处理停止请求(EvtIoStop)的回调函数(主要功能是:(在设备离开工作状态(D0)之前,处理队列中的 I / O 请求)、(根据 ActionFlags 的值,决定如何处理请求(例如,完成、取消、重新排队))、记录请求的相关信息(例如,队列、请求句柄、操作标志等)))
VOID
KMDFDriver1EvtIoStop(
_In_ WDFQUEUE Queue, //_In_ 指示参数是输入参数,请求关联的队列对象句柄
_In_ WDFREQUEST Request, //_In_ 指示参数是输入参数,请求对象句柄
_In_ ULONG ActionFlags //_In_ 指示参数是输入参数,操作标志(表示回调函数被调用的原因以及请求是否可取消)
)
/*++
Routine Description:
This event is invoked for a power-managed queue before the device leaves the working state (D0).
Arguments:
Queue - Handle to the framework queue object that is associated with the
I/O request.
Request - Handle to a framework request object.
ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS-typed flags
that identify the reason that the callback function is being called
and whether the request is cancelable.
Return Value:
VOID
--*/
{
//日志记录(/TraceEvents,是WPP提供的宏,用于记录日志)
TraceEvents(
TRACE_LEVEL_INFORMATION, //日志级别,表示一般信息
TRACE_QUEUE, //日志类别,通常用于标识日志的来源(这里是队列相关)
"%!FUNC! Queue 0x%p, Request 0x%p ActionFlags %d", //日志消息格式字符串,其中“%!FUNC!”是WPP的格式化占位符,表示当前函数名
Queue, //队列对象句柄的指针地址
Request, //请求对象句柄的指针地址
ActionFlags //操作标志的值
);
//
// In most cases, the EvtIoStop callback function completes, cancels, or postpones
// further processing of the I/O request.
//
// Typically, the driver uses the following rules:
//
// - If the driver owns the I/O request, it calls WdfRequestUnmarkCancelable
// (if the request is cancelable) and either calls WdfRequestStopAcknowledge
// with a Requeue value of TRUE, or it calls WdfRequestComplete with a
// completion status value of STATUS_SUCCESS or STATUS_CANCELLED.
//
// Before it can call these methods safely, the driver must make sure that
// its implementation of EvtIoStop has exclusive access to the request.
//
// In order to do that, the driver must synchronize access to the request
// to prevent other threads from manipulating the request concurrently.
// The synchronization method you choose will depend on your driver's design.
//
// For example, if the request is held in a shared context, the EvtIoStop callback
// might acquire an internal driver lock, take the request from the shared context,
// and then release the lock. At this point, the EvtIoStop callback owns the request
// and can safely complete or requeue the request.
//
// - If the driver has forwarded the I/O request to an I/O target, it either calls
// WdfRequestCancelSentRequest to attempt to cancel the request, or it postpones
// further processing of the request and calls WdfRequestStopAcknowledge with
// a Requeue value of FALSE.
//
// A driver might choose to take no action in EvtIoStop for requests that are
// guaranteed to complete in a small amount of time.
//
// In this case, the framework waits until the specified request is complete
// before moving the device (or system) to a lower power state or removing the device.
// Potentially, this inaction can prevent a system from entering its hibernation state
// or another low system power state. In extreme cases, it can cause the system
// to crash with bugcheck code 9F.
//
return; //函数返回(无返回值)
}
我在上面的代码中,增加了相应的注释,有助于学习Windows驱动开发的小白们能够理解每一行代码的用途!毕竟,学习 从 阅读 开始 !嘿嘿
(未完待续)