为什么要写这篇文章呢?
作为一名白帽黑客,如果想要学习ROOTKIT攻防技术,就必须要有能力进行驱动开发!
本文章仅提供学习,切勿将其用于不法手段!
在Windows操作系统的64位环境中,进行ROOTKIT攻防,就必须要学会Windows驱动开发!
Windows驱动开发,是掌握Rootkit技术的硬性基础之一!
不会Windows环境下的驱动开发,你就难以透彻理解ROOTKIT攻防技术的真相!
接上一篇文章,我们主要来讲解一下,KMDF项目开发中的一些代码内容编写!
接下来,我们来讲解下,相应的源文件(driver.c)中的代码内容 ^ _ ^ 请看下文!
/*++
Module Name:
driver.c //驱动程序的主源文件
Abstract:
This file contains the driver entry points and callbacks. //文件的内容:包含驱动程序的入口点和回调函数
Environment:
Kernel-mode Driver Framework //内核模式驱动程序框架(KMDF)的环境
--*/
#include "driver.h" //驱动程序特定的声明和定义
#include "driver.tmh" //用于WPP(Windows软件跟踪预处理器)跟踪的消息定义
//用于控制函数代码的内存分配属性,特别是针对初始化代码和设备添加、驱动上下文清理等回调函数的内存分页属性
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry) //初始化代码
#pragma alloc_text (PAGE, KMDFDriver1EvtDeviceAdd) //设备添加
#pragma alloc_text (PAGE, KMDFDriver1EvtDriverContextCleanup) //驱动上下文清理
#endif
//驱动程序的入口点,当驱动程序被加载时,系统首先调用这个函数.
//负责初始化驱动程序,并指定其他必要的回调函数,如设备添加和驱动卸载等.
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject, //代表加载到内存中的函数驱动程序的实例,驱动程序必须在这个函数返回之前初始化DriverObject的成员
_In_ PUNICODE_STRING RegistryPath //代表注册表中驱动程序特定的路径,函数驱动程序可以使用这个路径在重启之间存储驱动程序相关数据,但不存储硬件实例特定数据
)
/*++
Routine Description:
DriverEntry initializes the driver and is the first routine called by the
system after the driver is loaded. DriverEntry specifies the other entry
points in the function driver, such as EvtDevice and DriverUnload.
Parameters Description:
DriverObject - represents the instance of the function driver that is loaded
into memory. DriverEntry must initialize members of DriverObject before it
returns to the caller. DriverObject is allocated by the system before the
driver is loaded, and it is released by the system after the system unloads
the function driver from memory.
RegistryPath - represents the driver specific path in the Registry.
The function driver can use the path to store driver related data between
reboots. The path does not store hardware instance specific data.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise.
--*/
{
WDF_DRIVER_CONFIG config; //初始化WDF_DRIVER_CONFIG结构
NTSTATUS status; //
WDF_OBJECT_ATTRIBUTES attributes; //初始化WDF_OBJECT_ATTRIBUTES结构
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING(DriverObject, RegistryPath); //初始化WPP跟踪,用于调试和诊断
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); //记录一个信息级别的跟踪事件,表示DriverEntry函数被调用
//
// Register a cleanup callback so that we can call WPP_CLEANUP when
// the framework driver object is deleted during driver unload.
//
//初始化WDF_OBJECT_ATTRIBUTES结构,并设置一个清理回调,以便在框架驱动程序对象在驱动卸载期间被删除时调用WPP_CLEANUP
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = KMDFDriver1EvtDriverContextCleanup;
//初始化驱动程序
WDF_DRIVER_CONFIG_INIT(&config,
KMDFDriver1EvtDeviceAdd
);
//创建驱动程序对象
status = WdfDriverCreate(DriverObject,
RegistryPath,
&attributes,
&config,
WDF_NO_HANDLE
);
//错误检查机制,如果驱动程序对象创建失败
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status); //将记录一个错误级别的跟踪事件
WPP_CLEANUP(DriverObject); //执行清理操作
return status; //返回错误状态
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); //用于记录跟踪事件的实用工具(帮助了解驱动程序的行为和状态)
return status; //返回驱动程序对象的创建成功状态
}
//事件回调函数(在即插即用(Plug and Play, PnP)管理器向框架发出AddDevice请求时被触发)
//函数用途:代表新设备实例来创建并初始化一个设备对象
NTSTATUS
KMDFDriver1EvtDeviceAdd(
_In_ WDFDRIVER Driver,
_Inout_ PWDFDEVICE_INIT DeviceInit
)
/*++
Routine Description:
EvtDeviceAdd is called by the framework in response to AddDevice
call from the PnP manager. We create and initialize a device object to
represent a new instance of the device.
Arguments:
Driver - Handle to a framework driver object created in DriverEntry
DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
Return Value:
NTSTATUS
--*/
{
NTSTATUS status; //状态码
UNREFERENCED_PARAMETER(Driver); //消除编译器对未使用参数的警告(参数Driver,在当前函数体内并未被使用)
PAGED_CODE(); //指示随后的代码可以分页(如果驱动程序支持分页,分页上存储的代码数据,在内存不足时可以被系统换出到磁盘,并释放内存空间)
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); //记录函数入口的跟踪事件
status = KMDFDriver1CreateDevice(DeviceInit); //调用自定义函数来创建和初始化设备
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); //记录函数出口的跟踪事件
return status; //返回设备创建函数的状态码(设备添加操作是否成功)
}
//清理回调函数(当驱动程序对象即将被卸载或销毁时,这个函数会被框架(Framework)调用,以便释放DriverEntry函数中分配的所有资源)
//函数用途:确保清理过程不会出现资源泄漏、悬挂的句柄或其他潜在问题!
VOID
KMDFDriver1EvtDriverContextCleanup(
_In_ WDFOBJECT DriverObject
)
/*++
Routine Description:
Free all the resources allocated in DriverEntry.
Arguments:
DriverObject - handle to a WDF Driver object.
Return Value:
VOID.
--*/
{
UNREFERENCED_PARAMETER(DriverObject); //消除编译器对未使用参数的警告(参数DriverObject,在当前函数体内并未被使用)
PAGED_CODE(); //指示随后的代码可以分页(如果驱动程序支持分页,分页上存储的代码数据,在内存不足时可以被系统换出到磁盘,并释放内存空间)
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); //记录函数入口的跟踪事件
//
// Stop WPP Tracing
//
WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject)); // 停止Windows软件跟踪预处理器(Windows Software Trace Preprocessor,WPP)的跟踪(这里需要将DriverObject转换为WDFDRIVER类型,然后使用WdfDriverWdmGetDriverObject函数获取底层的WDM驱动程序对象,以便WPP_CLEANUP可以正确地停止跟踪)
}
我在上面的代码中,增加了相应的注释,有助于学习Windows驱动开发的小白们能够理解每一行代码的用途!毕竟,学习 从 阅读 开始 !嘿嘿
(未完待续)