Jesses

集中精神
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Hook Shadow SSDT(转)

Posted on 2010-01-14 10:36  Jesses  阅读(2743)  评论(0编辑  收藏  举报
标 题: 【原创】Hook Shadow SSDT
作 者: sislcb
时 间: 2008-06-02,23:21
链 接: http://bbs.pediy.com/showthread.php?t=65931

网上很多文章都有关于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, 00, 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;
}