用Visual studio11在Windows8上开发内核枚举注册表

在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破。在Windows 95中,至少应用程序I/O操作是不受限制的,而在Windows NT中,我们的应用程序连这点权限都被剥夺了。在NT中几乎不太可能进入真正的ring0层。 
在Windows NT中,存在三种Device Driver:

  1.“Virtual device Driver” (VDD)。通过VDD,16位应用程序,如DOS 和Win16应用程序可以访问特定的I/O端口(注意,不是直接访问,而是要通过VDD来实现访问)。

  2.“GDI Driver”,提供显示和打印所需的GDI函数。

  3.“Kernel Mode Driver”,实现对特定硬件的操作,比如说CreateFile, CloseHandle (对于文件对象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”还是Windows NT中唯一可以对硬件中断和DMA进行操作的Driver。SCSI 小端口驱动和 网卡NDIS 驱动都是Kernel Mode Driver的一种特殊形式。

 

 

Visual studio11与Windows8带来格外不同的新体验

 

1.启动Vs11

用Visual studio11在Windows8上开发内核枚举注册表_第1张图片

2.看见满目的驱动开发模板

用Visual studio11在Windows8上开发内核枚举注册表_第2张图片

3.选择一个驱动模式,有内核模式与用户模式两种的驱动

用Visual studio11在Windows8上开发内核枚举注册表_第3张图片

 

4.创建一个驱动程序,KMDF DriverMVP

用Visual studio11在Windows8上开发内核枚举注册表_第4张图片

 

5.我们选择的是内核模式的驱动程序,下面是创建成功后的界面,分别是驱动程序本身,与驱动安装包

用Visual studio11在Windows8上开发内核枚举注册表_第5张图片

6.按下F5,选择驱动编译,

 

用Visual studio11在Windows8上开发内核枚举注册表_第6张图片


插入下列代码实现ring0层枚举注册表,请见代码分析




#include <ntddk.h>

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	DbgPrint("Driver Unload");
}

//自定义枚举注册表键值函数
NTSTATUS
MyRegEnumSubValue()  
{
	UNICODE_STRING RegUnicodeString;
	HANDLE hRegister;
	ULONG ulSize;
	NTSTATUS ntStatus;
	UNICODE_STRING uniKeyName;
	PKEY_VALUE_FULL_INFORMATION  pvbi;
	PKEY_FULL_INFORMATION pfi;
	ULONG i;
	OBJECT_ATTRIBUTES objectAttributes;
	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &RegUnicodeString,
		L"\\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN");
	
	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
        &RegUnicodeString,
        OBJ_CASE_INSENSITIVE,//对大小写敏感
        NULL,
        NULL );

	//打开注册表
    ntStatus = ZwOpenKey( &hRegister,
        KEY_ALL_ACCESS,
        &objectAttributes);
	
	if (NT_SUCCESS(ntStatus))
	{
		KdPrint(("Open register successfully\n"));
	}
	ZwQueryKey(hRegister,
		KeyFullInformation,
		NULL,
		0,
		&ulSize);
	
	pfi=(PKEY_FULL_INFORMATION)
		ExAllocatePool(PagedPool,ulSize);
	
	//查询注册表
	ZwQueryKey(hRegister,
		KeyFullInformation,
		pfi,
		ulSize,
		&ulSize);
	
	//开始循环枚举注册表
	for(i=0;i<pfi->Values;i++)
	{
		ZwEnumerateValueKey(hRegister,
			i,
			KeyValueFullInformation,
			NULL,
			0,
			&ulSize);
		
		pvbi =(PKEY_VALUE_FULL_INFORMATION )
			ExAllocatePool(PagedPool,ulSize);
		
		ZwEnumerateValueKey(hRegister,
			i,
			KeyValueFullInformation,
			pvbi,
			ulSize,
			&ulSize);
		
		uniKeyName.Length = uniKeyName.MaximumLength =
		(USHORT)pvbi->NameLength;
		
		uniKeyName.Buffer = pvbi->Name;
		
		//将键值输出
		DbgPrint("第%d个键值名称是:%wZ\n",i,&uniKeyName);
		
		//判断键值的类型
		if (pvbi->Type==REG_SZ)
		{
			DbgPrint("键值的类型是:REG_SZ\n");
		}
		else if (pvbi->Type==REG_MULTI_SZ)
		{
			DbgPrint("键值的类型是:REG_MULTI_SZ\n");	
		}
		else if (pvbi->Type==REG_DWORD)
		{
			KdPrint(("键值的类型是:REG_DWORD\n"));
		}
		else if (pvbi->Type==REG_BINARY)
		{
			KdPrint(("键值的类型是:REG_BINARY\n"));
		}
		
		ExFreePool(pvbi);
	}
	
	ExFreePool(pfi);
	ZwClose(hRegister);
	return STATUS_SUCCESS;
}

NTSTATUS 
DriverEntry( 
			IN PDRIVER_OBJECT  DriverObject, 
			IN PUNICODE_STRING  RegistryPath 
    )
{
	MyRegEnumSubValue();
	DriverObject->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}


你可能感兴趣的:(用Visual studio11在Windows8上开发内核枚举注册表)