网上很多文章都有关于SSDT的完整的实现,但是没有关于Shadow SSDT的完整实现,目前最好的文章是《shadow ssdt学习笔记 by zhuwg》,我这里的程序也很多参考了他的文章,在这里谢谢了。我这里给出一个hook shadow ssdt的完整实现的驱动和3层的代码。

这里主要是hook 了NtUserFindWindowEx,NtUserBuildHwndList,NtUserQueryWindow,NtUserGetForegroundWindow,NtUserWindowFromPoint来防止其他应用程序通过FindWindow,EnumWindow,WindowFromPoint,GetForegroundWindow这些函数来枚举我们的窗口,不过这个程序对于GetWindowText这个东西无法防护,如果有朋友在驱动层实现了对该函数的保护,是否能一起交流呢。

关于hook的流程,看了上面zhuwg的文章,大家应该很好的了解了。下面的代码也很简单。大家随便看看吧,通信方面,随便使用了METHOD_NEITHER方法,这个方法不好,有问题,不过懒得改了,懂驱动的应该很容易改为BUFFERED模式吧。

在这里谢谢给了很多帮助的各位牛人,特别是NetRoc,很细心的帮我测试。。

代码:
#include <ntddk.h>
#include <windef.h>
#include <stdio.h>
#include <string.h>
#include "HookShadowSSDT.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);
PVOID GetInfoTable(ULONG ATableType);
HANDLE GetCsrPid();
VOID InitCallNumber();


NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, OUT PEPROCESS * pEProcess);
                                               

///////////////声明Native API///////////////////////////////////////

typedef NTSTATUS (*NTUSERFINDWINDOWEX)(
           IN HWND hwndParent, 
           IN HWND hwndChild, 
           IN PUNICODE_STRING pstrClassName OPTIONAL, 
           IN PUNICODE_STRING pstrWindowName OPTIONAL, 
           IN DWORD dwType);

typedef NTSTATUS (*NTUSERBUILDHWNDLIST)(
           IN HDESK hdesk,
           IN HWND hwndNext, 
           IN ULONG fEnumChildren, 
           IN DWORD idThread, 
           IN UINT cHwndMax, 
           OUT HWND *phwndFirst, 
           OUT ULONG *pcHwndNeeded);

typedef UINT_PTR (*NTUSERQUERYWINDOW)(
              IN ULONG WindowHandle,
          IN ULONG TypeInformation);

typedef ULONG (*NTUSERGETFOREGROUNDWINDOW)(VOID);

typedef HWND (*NTUSERWINDOWFROMPOINT)(LONG, LONG);


NTSTATUS ZwQuerySystemInformation( 
    IN ULONG SystemInformationClass, 
    IN PVOID SystemInformation, 
    IN ULONG SystemInformationLength, 
    OUT PULONG ReturnLength);

NTSTATUS ZwDuplicateObject(
                 IN HANDLE                 SourceProcessHandle,
                 IN PHANDLE                 SourceHandle,
                 IN HANDLE                 TargetProcessHandle,
                 OUT PHANDLE               TargetHandle,
                 IN ACCESS_MASK             DesiredAccess OPTIONAL,
                 IN BOOLEAN                 InheritHandle,
                 IN ULONG                   Options );

NTSTATUS ZwQueryObject(
        IN HANDLE                ObjectHandle,
        IN ULONG                 ObjectInformationClass,
        OUT PVOID                ObjectInformation,
        IN ULONG                 ObjectInformationLength,
        OUT PULONG               ReturnLength OPTIONAL);


NTSTATUS PsLookupProcessByProcessId(
     IN ULONG               ulProcId, 
     OUT PEPROCESS *        pEProcess);


NTSTATUS KeAttachProcess(PEPROCESS pPeb);
NTSTATUS KeDetachProcess();

NTSTATUS MyNtUserFindWindowEx(
     IN HWND hwndParent, 
     IN HWND hwndChild, 
     IN PUNICODE_STRING pstrClassName OPTIONAL, 
     IN PUNICODE_STRING pstrWindowName OPTIONAL, 
     IN DWORD dwType);

NTSTATUS MyNtUserBuildHwndList(
     IN HDESK hdesk, 
     IN HWND hwndNext, 
     IN ULONG fEnumChildren, 
     IN DWORD idThread, 
     IN UINT cHwndMax,
     OUT HWND *phwndFirst, 
     OUT ULONG* pcHwndNeeded);

UINT_PTR MyNtUserQueryWindow(
     IN ULONG WindowHandle,
     IN ULONG TypeInformation);

ULONG MyNtUserGetForegroundWindow(VOID);

HWND MyNtUserWindowFromPoint(LONG x, LONG y);


__declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);

////////////////////定义所用到的全局变量///////////////
__declspec(dllimport)  ServiceDescriptorTableEntry KeServiceDescriptorTable;

unsigned long OldCr0;
UNICODE_STRING DeviceNameString;
UNICODE_STRING LinkDeviceNameString;

NTUSERFINDWINDOWEX          g_OriginalNtUserFindWindowEx;
NTUSERBUILDHWNDLIST         g_OriginalNtUserBuildHwndList;
NTUSERQUERYWINDOW           g_OriginalNtUserQueryWindow;
NTUSERGETFOREGROUNDWINDOW   g_OriginalNtUserGetForegroundWindow;
NTUSERWINDOWFROMPOINT       g_OriginalNtUserWindowFromPoint;

PEPROCESS crsEProc;

CCHAR     outBuf[1024];                        //输入缓冲区大小

HANDLE ProcessIdToProtect = (HANDLE)0;        //保护的句柄

ULONG NtUserFindWindowEx_callnumber = 0;          //NtUserFindWindowEx的服号
ULONG NtUserGetForegroundWindow_callnumber = 0;
ULONG NtUserQueryWindow_callnumber = 0;
ULONG NtUserBuildHwndList_callnumber = 0;
ULONG NtUserWindowFromPoint_callnumber = 0;
ULONG LastForegroundWindow;

unsigned int getAddressOfShadowTable()
{
    unsigned int i;
    unsigned char *p;
    unsigned int dwordatbyte;

    p = (unsigned char*) KeAddSystemServiceTable;

    for(i = 0; i < 4096; i++, p++)
    {
        __try
        {
            dwordatbyte = *(unsigned int*)p;
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            return 0;
        }

        if(MmIsAddressValid((PVOID)dwordatbyte))
        {
            if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0)
            {
                if((PVOID)dwordatbyte == &KeServiceDescriptorTable)
                {
                    continue;
                }

                return dwordatbyte;
            }
        }
    }

    return 0;
}

ULONG getShadowTable()
{
    KeServiceDescriptorTableShadow = (PServiceDescriptorTableEntry) getAddressOfShadowTable();

    if(KeServiceDescriptorTableShadow == NULL)
    {
        DbgPrint("hooker.sys: Couldnt find shadowtable!");
        
        return FALSE;
    }
    else
    {
        DbgPrint("hooker.sys: Shadowtable has been found!");
        
        DbgPrint("hooker.sys: Shadowtable entries: %d", KeServiceDescriptorTableShadow[1].NumberOfServices);
        return TRUE;
    }
} 

//根据操作系统来确定具体函数的服务号 
VOID InitCallNumber()
{
  ULONG majorVersion, minorVersion;
  PsGetVersion( &majorVersion, &minorVersion, NULL, NULL );
    if ( majorVersion == 5 && minorVersion == 2 )
    {
    DbgPrint("comint32: Running on Windows 2003");
      NtUserFindWindowEx_callnumber = 0x179;
    NtUserGetForegroundWindow_callnumber = 0x193;
    NtUserBuildHwndList_callnumber = 0x137;
    NtUserQueryWindow_callnumber = 0x1E1;
    NtUserWindowFromPoint_callnumber = 0x24C;

  }
  else if ( majorVersion == 5 && minorVersion == 1 )
  {
    DbgPrint("comint32: Running on Windows XP");
      NtUserFindWindowEx_callnumber = 0x17A;
    NtUserGetForegroundWindow_callnumber = 0x194;
    NtUserBuildHwndList_callnumber = 0x138;
    NtUserQueryWindow_callnumber = 0x1E3;
    NtUserWindowFromPoint_callnumber = 0x250;
  }
  else if ( majorVersion == 5 && minorVersion == 0 )
  {
    DbgPrint("comint32: Running on Windows 2000");
    NtUserFindWindowEx_callnumber = 0x170;
    NtUserGetForegroundWindow_callnumber = 0x189;
    NtUserBuildHwndList_callnumber = 0x12E;
    NtUserQueryWindow_callnumber = 0x1D2;
    NtUserWindowFromPoint_callnumber = 0x238;
  }
}

PVOID GetInfoTable(ULONG ATableType)
{
  ULONG mSize = 0x4000;
  PVOID mPtr = NULL;
  NTSTATUS St;
  do
  {
     mPtr = ExAllocatePool(PagedPool, mSize);
     memset(mPtr, 0, mSize);
     if (mPtr)
     {
        St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL);
     } else return NULL;
     if (St == STATUS_INFO_LENGTH_MISMATCH)
     {
        ExFreePool(mPtr);
        mSize = mSize * 2;
     }
  } while (St == STATUS_INFO_LENGTH_MISMATCH);
  if (St == STATUS_SUCCESS) return mPtr;
  ExFreePool(mPtr);
  return NULL;
}

HANDLE GetCsrPid()
{
  HANDLE Process, hObject;
  HANDLE CsrId = (HANDLE)0;
  OBJECT_ATTRIBUTES obj;
  CLIENT_ID cid;
  UCHAR Buff[0x100];
  POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
  PSYSTEM_HANDLE_INFORMATION_EX Handles;
  ULONG r;

  Handles = GetInfoTable(SystemHandleInformation);

  if (!Handles) return CsrId;

  for (r = 0; r < Handles->NumberOfHandles; r++)
  {
    if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
    {
      InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

      cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
      cid.UniqueThread = 0;

      if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
      {
        if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
        {
          if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
          {
            if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
            {
              CsrId = (HANDLE)Handles->Information[r].ProcessId;
            } 
          }

          ZwClose(hObject);
        }

        ZwClose(Process);
      }
    }
  }

  ExFreePool(Handles);
  return CsrId;
}

BOOLEAN Sleep(ULONG MillionSecond)
{
  NTSTATUS st;
  LARGE_INTEGER DelayTime;
  DelayTime = RtlConvertLongToLargeInteger(-10000*MillionSecond);
  st=KeDelayExecutionThread( KernelMode, FALSE, &DelayTime );
  return (NT_SUCCESS(st));
}

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
  NTSTATUS status;
  PDEVICE_OBJECT   deviceObject;
 
   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;
    }
 
  //获得shadow的地址
  getShadowTable();
  //根据不同的系统获得不同的函数服务号
  InitCallNumber();

  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;

  status = PsLookupProcessByProcessId((ULONG)GetCsrPid(), &crsEProc);
  if (!NT_SUCCESS( status ))
  {
  DbgPrint("PsLookupProcessByProcessId() error\n");
  return status;
  }
  KeAttachProcess(crsEProc);

  __try
  {
    if ((KeServiceDescriptorTableShadow!=NULL) \
      && (NtUserFindWindowEx_callnumber!=0) && (NtUserGetForegroundWindow_callnumber!=0) \
      && (NtUserBuildHwndList_callnumber!=0) && (NtUserQueryWindow_callnumber!=0) \
      && (NtUserWindowFromPoint_callnumber!=0)) 
    {
    g_OriginalNtUserFindWindowEx     = (NTUSERFINDWINDOWEX)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserFindWindowEx_callnumber];
    g_OriginalNtUserQueryWindow=(NTUSERQUERYWINDOW)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserQueryWindow_callnumber];            
    g_OriginalNtUserBuildHwndList=(NTUSERBUILDHWNDLIST)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserBuildHwndList_callnumber];
        g_OriginalNtUserGetForegroundWindow=(NTUSERGETFOREGROUNDWINDOW)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserGetForegroundWindow_callnumber];
        g_OriginalNtUserWindowFromPoint = (NTUSERWINDOWFROMPOINT)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserWindowFromPoint_callnumber];  
    }
    else
    KeServiceDescriptorTableShadow=NULL;
    

    _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
    }
    if ((KeServiceDescriptorTableShadow!=NULL) && (NtUserFindWindowEx_callnumber!=0) && (NtUserGetForegroundWindow_callnumber!=0) && (NtUserBuildHwndList_callnumber!=0) && (NtUserQueryWindow_callnumber!=0))
    {
    (NTUSERFINDWINDOWEX)(KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserFindWindowEx_callnumber]) = MyNtUserFindWindowEx;
        (NTUSERQUERYWINDOW)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserQueryWindow_callnumber]  = MyNtUserQueryWindow;
    (NTUSERBUILDHWNDLIST)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserBuildHwndList_callnumber] = MyNtUserBuildHwndList;
        (NTUSERGETFOREGROUNDWINDOW)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserGetForegroundWindow_callnumber] = MyNtUserGetForegroundWindow;
        (NTUSERWINDOWFROMPOINT)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserWindowFromPoint_callnumber] = MyNtUserWindowFromPoint;
    }

    _asm 
    {
    MOV    EAX, CR0        //move CR0 register into EAX
    OR     EAX, 10000H        //enable WP bit     
    MOV    CR0, EAX        //write register back        
    STI                    //enable interrupt
    }
  }
  __finally
  {
      KeDetachProcess(); 
  }

  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;
DWORD dd;
  
  irpStack = IoGetCurrentIrpStackLocation(Irp);
  outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  inputLength=irpStack->Parameters.DeviceIoControl.InputBufferLength;
  controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
  
  DbgPrint("IN CONTROL\r\n");
  switch(controlCode)
  {
  case IO_PROTECT:
    ProcessIdToProtect = (HANDLE)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
    DbgPrint("IO_PROTECT:%d", ProcessIdToProtect);
    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;
  NTSTATUS status;

  status = PsLookupProcessByProcessId((ULONG)GetCsrPid(), &crsEProc);
  if (!NT_SUCCESS( status ))
  {
    DbgPrint("PsLookupProcessByProcessId() error\n");
    return ;
  }
  KeAttachProcess(crsEProc);

//////////////////////UnHook ZwQuerySystemInformation/////////////////////////////////////////////////
 
  __try
  {
    _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
    }

    if ((KeServiceDescriptorTableShadow!=NULL) && (NtUserFindWindowEx_callnumber!=0) && (NtUserGetForegroundWindow_callnumber!=0) && (NtUserBuildHwndList_callnumber!=0) && (NtUserQueryWindow_callnumber!=0)) 
    {
    (NTUSERFINDWINDOWEX)(KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserFindWindowEx_callnumber]) = g_OriginalNtUserFindWindowEx;
    (NTUSERQUERYWINDOW)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserQueryWindow_callnumber]    = g_OriginalNtUserQueryWindow;            
    (NTUSERBUILDHWNDLIST)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserBuildHwndList_callnumber]  = g_OriginalNtUserBuildHwndList;
    (NTUSERGETFOREGROUNDWINDOW)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserGetForegroundWindow_callnumber]    = g_OriginalNtUserGetForegroundWindow;
    (NTUSERWINDOWFROMPOINT)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserWindowFromPoint_callnumber] = g_OriginalNtUserWindowFromPoint;
    }

    _asm 
    {
    MOV    EAX, CR0        //move CR0 register into EAX
    OR     EAX, 10000H     //enable WP bit     
    MOV    CR0, EAX        //write register back        
    STI                    //enable interrupt
    }
    }
  __finally
   {
   KeDetachProcess();
   Sleep(50);
   }
  
    deviceObject= DriverObject->DeviceObject;
    IoDeleteSymbolicLink(&LinkDeviceNameString);
    ASSERT(!deviceObject->AttachedDevice);
    if ( deviceObject != NULL )
    {
        IoDeleteDevice( deviceObject );
    }
}

NTSTATUS MyNtUserFindWindowEx(
     IN HWND hwndParent, 
     IN HWND hwndChild, 
     IN PUNICODE_STRING pstrClassName OPTIONAL, 
     IN PUNICODE_STRING pstrWindowName OPTIONAL, 
     IN DWORD dwType)
{
  ULONG result;

  result = g_OriginalNtUserFindWindowEx(hwndParent, hwndChild, pstrClassName, pstrWindowName, dwType);

  if (PsGetCurrentProcessId()!=ProcessIdToProtect)
  {
    ULONG ProcessID;
    
    ProcessID = g_OriginalNtUserQueryWindow(result, 0);
    DbgPrint("ProcessID:%d", ProcessID);
    if (ProcessID==(ULONG)ProcessIdToProtect)
      return 0;
  }
  return result;
}

NTSTATUS MyNtUserBuildHwndList(IN HDESK hdesk, IN HWND hwndNext, IN ULONG fEnumChildren, IN DWORD idThread, IN UINT cHwndMax, OUT HWND *phwndFirst, OUT ULONG* pcHwndNeeded)
{
  NTSTATUS result;

  if (PsGetCurrentProcessId()!=ProcessIdToProtect)
  {
    ULONG ProcessID;
    
    if (fEnumChildren==1)
    {
            ProcessID = g_OriginalNtUserQueryWindow((ULONG)hwndNext, 0);
      if (ProcessID==(ULONG)ProcessIdToProtect)
        return STATUS_UNSUCCESSFUL;
    }
    result = g_OriginalNtUserBuildHwndList(hdesk,hwndNext,fEnumChildren,idThread,cHwndMax,phwndFirst,pcHwndNeeded);

    if (result==STATUS_SUCCESS)
    {
      ULONG i=0;
      ULONG j;

      while (i<*pcHwndNeeded)
      {
        ProcessID=g_OriginalNtUserQueryWindow((ULONG)phwndFirst[i],0);
        if (ProcessID==(ULONG)ProcessIdToProtect)
        {
          for (j=i; j<(*pcHwndNeeded)-1; j++)          
            phwndFirst[j]=phwndFirst[j+1]; 

          phwndFirst[*pcHwndNeeded-1]=0; 

          (*pcHwndNeeded)--;
          continue; 
        }
                i++;        
      }
      
    }
    return result;
  }
  return g_OriginalNtUserBuildHwndList(hdesk,hwndNext,fEnumChildren,idThread,cHwndMax,phwndFirst,pcHwndNeeded);
}

ULONG MyNtUserGetForegroundWindow(VOID)
{
  ULONG result;

  result= g_OriginalNtUserGetForegroundWindow();  

  if (PsGetCurrentProcessId()!=ProcessIdToProtect)
  {
    ULONG ProcessID;
    
    ProcessID=g_OriginalNtUserQueryWindow(result, 0);
    if (ProcessID == (ULONG)ProcessIdToProtect)
      result=LastForegroundWindow;
    else
            LastForegroundWindow=result;
  }  
  return result;
}

UINT_PTR MyNtUserQueryWindow(IN ULONG WindowHandle,IN ULONG TypeInformation)
{
  ULONG WindowHandleProcessID;

  if (PsGetCurrentProcessId()!=ProcessIdToProtect)
  {
    WindowHandleProcessID = g_OriginalNtUserQueryWindow(WindowHandle,0);
    if (WindowHandleProcessID==(ULONG)ProcessIdToProtect)
      return 0;
  }
  return g_OriginalNtUserQueryWindow(WindowHandle,TypeInformation);
}

HWND MyNtUserWindowFromPoint(LONG x, LONG y)
{
  return 0;
}
上传的附件 HookShadowSSDT.rar