【原创】Hook Shadow SSDT

来源:互联网 发布:mac 命令行 修复系统 编辑:程序博客网 时间:2024/06/05 09:06
标 题: 【原创】Hook Shadow SSDT
作 者: sislcb
时 间: 2008-06-02,23:21:04
链 接: 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, 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;}

上传的附件文件类型: rarHookShadowSSDT.rar (466.2 KB, 4722 次下载)
原创粉丝点击