首页
社区
课程
招聘
[原创]Hook Shadow SSDT
发表于: 2008-6-2 23:21 96761

[原创]Hook Shadow SSDT

2008-6-2 23:21
96761
网上很多文章都有关于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;
}




[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 8
支持
分享
最新回复 (70)
雪    币: 354
活跃值: (10)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
nice。。。
2008-6-2 23:43
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
3
gooooooooooooooooooood
2008-6-3 08:50
0
雪    币: 564
活跃值: (42)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
4
VERY NICE
2008-6-3 09:24
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
5
if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0)
这个处理的好,充分利用两者的特点。

还有找csrss.exe的句柄用的办法都很不错。

好文,学习。
2008-6-3 10:20
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
6
目前qq三国游戏中,也采用了类似的手法,hook shadow ssdt。保护常规的API函数。
他们是:
    GetDC
    GetDCEx
    WindowFromPoint
    GetForegroundWindow
    FindWindowEx
    EnumWindows
    EnumChildWindows

此文已被编入rootkit专题中。
2008-6-3 10:29
0
雪    币: 266
活跃值: (50)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
7
恩,其实这也是外挂的保护技术,但是有一个没办法解决,就是GetWindowText这个函数,这个函数在03和xp下的表现是不同的,据《window编程启示录》那里写的,在如果是本进程,则为发送WM_GETTEXT消息,如果为其他进程,则是其他的做法。

具体这部分内容,在csdn的读书频道上有。
地址如下:http://book.csdn.net/bookfiles/472/10047216533.shtml
2008-6-3 12:53
0
雪    币: 381
活跃值: (140)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
8
只能说学习,帮顶了。。。
2008-6-4 12:31
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
9
METHOD_NEITHER方法,这个方法不好

不用这么说,,其实只要按照规范使用,一样很好
建议参考那篇详细的4种io通信解说  搜索1下论坛即可
2008-6-7 22:25
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
问一个初级问题,我装了Visual 2005与ddk开发工具包,怎样设置环境可以成功编译,期待中......
2008-6-8 00:53
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
11
楼上的
直接进入ddk环境 执行build就可以了
2008-6-8 06:27
0
雪    币: 257
活跃值: (56)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
搜藏了。
拿回电脑后慢慢看。
2008-6-8 20:36
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
NICE JOB
2008-6-9 13:18
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
非常感谢“11楼”
2008-6-14 11:23
0
雪    币: 415
活跃值: (34)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
好强大,没的说了。正好有用。
2008-6-15 02:51
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
好文章,学习~
2008-6-15 10:04
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
好   好文  学习了
2008-6-20 17:35
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
多谢LZ了。
2008-6-24 11:08
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
谢谢楼主, 但在我机子上测试了一下,运行都正常,只是ring3程序关闭时候会蓝屏.
2008-8-15 13:21
0
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
找到原因了,是我把驱动部分误操作后再编译,因此安装后的驱动有错.
重新编译正确的版本 就好了.
2008-8-15 14:00
0
雪    币: 147
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
Handles->Information[r].ObjectTypeNumber == 21

21是XP下的,2K和2K3下这个值是多少?
2008-9-9 22:16
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
MCY
22
很高深啊,学习了。
2008-9-10 11:48
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
非常感谢,太THANKS了
2008-9-27 23:04
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
卡巴2009的主动怎么过啊 ?这个貌似过不了卡巴2009
2008-9-28 14:46
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
是哦,卡巴2009的过不了,
2008-9-29 11:21
0
游客
登录 | 注册 方可回帖
返回
//