遍历所有驱动的名_根据本驱动对象的成员(DriverObject->DriverSection)_对应LDR_DATA_TABLE_ENTRY结构体_双向链表使用

#include"ntddk.h"
typedef struct _LDR_DATA_TABLE_ENTRY {
	LIST_ENTRY InLoadOrderLinks;//这个成员把系统所有加载(可能是停止没被卸载)已经读取到内存中 我们关系第一个  我们要遍历链表 双链表 不管中间哪个节点都可以遍历整个链表 本驱动的驱动对象就是一个节点
	LIST_ENTRY InMemoryOrderLinks;//系统已经启动 没有被初始化 没有调用DriverEntry这个历程的时候 通过这个链表进程串接起来
	LIST_ENTRY InInitializationOrderLinks;//已经调用DriverEntry这个函数的所有驱动程序
	PVOID DllBase;
	PVOID EntryPoint;//驱动的进入点 DriverEntry
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;//驱动的满路径
	UNICODE_STRING BaseDllName;//不带路径的驱动名字
	ULONG Flags;
	USHORT LoadCount;
	USHORT TlsIndex;
	union {
		LIST_ENTRY HashLinks;
		struct {
			PVOID SectionPointer;
			ULONG CheckSum;
		};
	};
	union {
		struct {
			ULONG TimeDateStamp;
		};
		struct {
			PVOID LoadedImports;
		};
	};
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;//系统所有程序 驱动对象里都有这个结构 是驱动对象的成员qudongduixiang1->DriverSection(PVOID DriverSection) 这个结构体在什么时候有的 io管理器在加载我们驱动的时候 调用DriverEntry这个历程的时候 把我们驱动对象也加入到系统的一个全局链表中 
//就是为了方便io管理器进行维护或者方便对象管理器进行维护 为了查找方便 这个全局链表呢 把系统所有驱动程序串起来就是连接起来

VOID xiezai1(PDRIVER_OBJECT qudongduixiang1)
{
	KdPrint(("驱动卸载历程\n"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT qudongduixiang1, PUNICODE_STRING zhucebiao1)//遍历驱动名字
{
	LDR_DATA_TABLE_ENTRY*jiegouti1, *linshi1;
	jiegouti1 = (LDR_DATA_TABLE_ENTRY*)qudongduixiang1->DriverSection;
	PLIST_ENTRY shuangxiangxunhuanlianbiao;
	shuangxiangxunhuanlianbiao = jiegouti1->InLoadOrderLinks.Flink;	//PLIST_ENTRY 双循环链表 循环起来的 首尾是相接的 //Flink 代表前一个节点
	while (shuangxiangxunhuanlianbiao != &jiegouti1->InLoadOrderLinks)
	{
		linshi1 = (LDR_DATA_TABLE_ENTRY*)shuangxiangxunhuanlianbiao;//双向循环链表存放的结构体就是LDR_DATA_TABLE_ENTRY* 这个内核链表的特性
		KdPrint(("驱动名%wZ\n", &linshi1->FullDllName));//注意加取地址
		shuangxiangxunhuanlianbiao=shuangxiangxunhuanlianbiao->Flink;
	}
	qudongduixiang1->DriverUnload = xiezai1;
	return STATUS_SUCCESS;
}

 

要获取底层硬盘驱动对象并向其发送IRP_MJ_READ请求,可以使用下面的示例代码: ``` #include <ntddk.h&gt; NTSTATUS ReadSector(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { // 获取IRP的输入输出缓冲区 PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp); PVOID inputBuffer = Irp-&gt;AssociatedIrp.SystemBuffer; PVOID outputBuffer = Irp-&gt;UserBuffer; // 分配一个MDL描述符并锁定输入缓冲区 PMDL mdl = IoAllocateMdl(inputBuffer, irpStack-&gt;Parameters.Read.Length, FALSE, FALSE, NULL); MmBuildMdlForNonPagedPool(mdl); MmProbeAndLockPages(mdl, KernelMode, IoReadAccess); // 构造IRP并发送给底层驱动 PIRP readIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, outputBuffer, irpStack-&gt;Parameters.Read.Length, &irpStack-&gt;Parameters.Read.StartingOffset, NULL, NULL); NTSTATUS status = IoCallDriver(DeviceObject, readIrp); // 解锁并释放MDL MmUnlockPages(mdl); IoFreeMdl(mdl); return status; } NTSTATUS DispatchReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { // 获取IRP的输入输出缓冲区 PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp); PVOID inputBuffer = Irp-&gt;AssociatedIrp.SystemBuffer; PVOID outputBuffer = Irp-&gt;UserBuffer; // 如果是读请求,则调用ReadSector函数发送IRP_MJ_READ请求 if (irpStack-&gt;MajorFunction == IRP_MJ_READ) { return ReadSector(DeviceObject, Irp, NULL); } // 如果是写请求,则直接返回成功 if (irpStack-&gt;MajorFunction == IRP_MJ_WRITE) { Irp-&gt;IoStatus.Status = STATUS_SUCCESS; Irp-&gt;IoStatus.Information = irpStack-&gt;Parameters.Write.Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } // 其他请求则返回未实现 Irp-&gt;IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp-&gt;IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NOT_IMPLEMENTED; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { // 创建设备对象 PDEVICE_OBJECT deviceObject; UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDisk"); UNICODE_STRING symbolicLinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\MyDisk"); NTSTATUS status = IoCreateDevice(DriverObject, 0, &deviceName, FILE_DEVICE_DISK, 0, FALSE, &deviceObject); if (!NT_SUCCESS(status)) { return status; } // 创建符号链接 status = IoCreateSymbolicLink(&symbolicLinkName, &deviceName); if (!NT_SUCCESS(status)) { IoDeleteDevice(deviceObject); return status; } // 设置IRP处理函数 for (ULONG i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject-&gt;MajorFunction[i] = DispatchReadWrite; } // 获取底层硬盘驱动对象 WCHAR diskName[] = L"\\Device\\Harddisk0\\Partition1"; UNICODE_STRING diskNameUnicode = RTL_CONSTANT_STRING(diskName); PDEVICE_OBJECT diskObject = IoGetDeviceObjectByDeviceName(&diskNameUnicode); // 发送IRP_MJ_READ请求 PVOID buffer = ExAllocatePoolWithTag(NonPagedPool, 512, 'MyD'); if (buffer != NULL) { LARGE_INTEGER offset = { 0 }; PIRP readIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, diskObject, buffer, 512, &offset, NULL, NULL); if (readIrp != NULL) { status = IoCallDriver(diskObject, readIrp); if (NT_SUCCESS(status)) { DbgPrint("Read sector successfully!\n"); } else { DbgPrint("Read sector failed with status 0x%X\n", status); } } else { DbgPrint("Failed to build IRP\n"); } ExFreePoolWithTag(buffer, 'MyD'); } else { DbgPrint("Failed to allocate buffer\n"); } return STATUS_SUCCESS; } ``` 在这个示例中,我们首先创建了一个设备对象并设置了IRP处理函数为DispatchReadWrite。这个函数会根据IRP的MajorFunction字段来判断是否是读请求或写请求,如果是读请求则调用ReadSector函数发送IRP_MJ_READ请求,如果是写请求则直接返回成功。如果是其他请求则返回未实现。 在DriverEntry函数中,我们获取了底层硬盘驱动对象,并发送了一个IRP_MJ_READ请求来读取磁盘扇区。注意,这里的硬盘驱动对象是通过设备获取的,因此需要知道硬盘的设备才能获取到正确的对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值