免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

通用shadow ssdt hook的详解以及代码的编写

Driver.h
  1. #ifdef __cplusplus
  2. extern "C"
  3. {
  4. #endif
  5. //#include <ntddk.h>
  6. #include <ntifs.h>
  7. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

  8. #ifdef __cplusplus
  9. }
  10. #endif

  11. #define PAGEDCODE code_seg("PAGE")
  12. #define LOCKEDCODE code_seg()
  13. #define INITCODE code_seg("INIT")

  14. #define PAGEDDATA data_seg("PAGE")
  15. #define LOCKEDDATA data_seg()
  16. #define INITDATA data_seg("INIT")

  17. #define arraysize(p) (sizeof(p)/sizeof((p)[0]))

  18. #pragma pack(1)
  19. typedef struct ServiceDescriptorEntry {
  20.         unsigned int *ServiceTableBase;
  21.         unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
  22.         unsigned int NumberOfServices;
  23.         unsigned char *ParamTableBase;
  24. } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
  25. #pragma pack()

  26. extern "C" PServiceDescriptorTableEntry_t KeServiceDescriptorTable;



  27. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);

  28. EXTERN_C NTKERNELAPI BOOLEAN KeAddSystemServiceTable (
  29.     IN PULONG_PTR Base,
  30.     IN PULONG Count OPTIONAL,
  31.     IN ULONG Limit,
  32.     IN PUCHAR Number,
  33.     IN ULONG Index
  34.     );

  35. typedef enum _SYSTEM_INFORMATION_CLASS {
  36.         SystemBasicInformation,
  37.         SystemProcessorInformation,             // obsolete...delete
  38.         SystemPerformanceInformation,
  39.         SystemTimeOfDayInformation,
  40.         SystemPathInformation,
  41.         SystemProcessInformation,
  42.         SystemCallCountInformation,
  43.         SystemDeviceInformation,
  44.         SystemProcessorPerformanceInformation,
  45.         SystemFlagsInformation,
  46.         SystemCallTimeInformation,
  47.         SystemModuleInformation,
  48.         SystemLocksInformation,
  49.         SystemStackTraceInformation,
  50.         SystemPagedPoolInformation,
  51.         SystemNonPagedPoolInformation,
  52.         SystemHandleInformation,
  53.         SystemObjectInformation,
  54.         SystemPageFileInformation,
  55.         SystemVdmInstemulInformation,
  56.         SystemVdmBopInformation,
  57.         SystemFileCacheInformation,
  58.         SystemPoolTagInformation,
  59.         SystemInterruptInformation,
  60.         SystemDpcBehaviorInformation,
  61.         SystemFullMemoryInformation,
  62.         SystemLoadGdiDriverInformation,
  63.         SystemUnloadGdiDriverInformation,
  64.         SystemTimeAdjustmentInformation,
  65.         SystemSummaryMemoryInformation,
  66.         SystemMirrorMemoryInformation,
  67.         SystemPerformanceTraceInformation,
  68.         SystemObsolete0,
  69.         SystemExceptionInformation,
  70.         SystemCrashDumpStateInformation,
  71.         SystemKernelDebuggerInformation,
  72.         SystemContextSwitchInformation,
  73.         SystemRegistryQuotaInformation,
  74.         SystemExtendServiceTableInformation,
  75.         SystemPrioritySeperation,
  76.         SystemVerifierAddDriverInformation,
  77.         SystemVerifierRemoveDriverInformation,
  78.         SystemProcessorIdleInformation,
  79.         SystemLegacyDriverInformation,
  80.         SystemCurrentTimeZoneInformation,
  81.         SystemLookasideInformation,
  82.         SystemTimeSlipNotification,
  83.         SystemSessionCreate,
  84.         SystemSessionDetach,
  85.         SystemSessionInformation,
  86.         SystemRangeStartInformation,
  87.         SystemVerifierInformation,
  88.         SystemVerifierThunkExtend,
  89.         SystemSessionProcessInformation,
  90.         SystemLoadGdiDriverInSystemSpace,
  91.         SystemNumaProcessorMap,
  92.         SystemPrefetcherInformation,
  93.         SystemExtendedProcessInformation,
  94.         SystemRecommendedSharedDataAlignment,
  95.         SystemComPlusPackage,
  96.         SystemNumaAvailableMemory,
  97.         SystemProcessorPowerInformation,
  98.         SystemEmulationBasicInformation,
  99.         SystemEmulationProcessorInformation,
  100.         SystemExtendedHandleInformation,
  101.         SystemLostDelayedWriteInformation,
  102.         SystemBigPoolInformation,
  103.         SystemSessionPoolTagInformation,
  104.         SystemSessionMappedViewInformation,
  105.         SystemHotpatchInformation,
  106.         SystemObjectSecurityMode,
  107.         SystemWatchdogTimerHandler,
  108.         SystemWatchdogTimerInformation,
  109.         SystemLogicalProcessorInformation,
  110.         SystemWow64SharedInformation,
  111.         SystemRegisterFirmwareTableInformationHandler,
  112.         SystemFirmwareTableInformation,
  113.         SystemModuleInformationEx,
  114.         SystemVerifierTriageInformation,
  115.         SystemSuperfetchInformation,
  116.         SystemMemoryListInformation,
  117.         SystemFileCacheInformationEx,
  118.         MaxSystemInfoClass  // MaxSystemInfoClass should always be the last enum
  119. } SYSTEM_INFORMATION_CLASS;

  120. //


  121. EXTERN_C NTSYSAPI NTSTATUS ZwQuerySystemInformation (
  122.                                                   __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
  123.                                                   __out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
  124.                                                   __in ULONG SystemInformationLength,
  125.                                                   __out_opt PULONG ReturnLength
  126.                                                   );

  127. EXTERN_C NTKERNELAPI NTSTATUS NtOpenProcess (
  128.                            __out PHANDLE ProcessHandle,
  129.                            __in ACCESS_MASK DesiredAccess,
  130.                            __in POBJECT_ATTRIBUTES ObjectAttributes,
  131.                            __in_opt PCLIENT_ID ClientId
  132.                            );



  133. typedef struct _SYSTEM_THREADS {
  134.         LARGE_INTEGER   KernelTime;
  135.         LARGE_INTEGER   UserTime;
  136.         LARGE_INTEGER   CreateTime;
  137.         ULONG           WaitTime;
  138.         PVOID           StartAddress;
  139.         CLIENT_ID       ClientIs;
  140.         KPRIORITY       Priority;
  141.         KPRIORITY       BasePriority;
  142.         ULONG           ContextSwitchCount;
  143.         ULONG           ThreadState;
  144.         KWAIT_REASON    WaitReason;
  145. }SYSTEM_THREADS;

  146. typedef struct _SYSTEM_PROCESSES {
  147.         ULONG           NextEntryDelta;
  148.         ULONG           ThreadCount;
  149.         ULONG           Reserved[6];
  150.         LARGE_INTEGER   CreateTime;
  151.         LARGE_INTEGER   UserTime;
  152.         LARGE_INTEGER   KernelTime;
  153.         UNICODE_STRING ProcessName;
  154.         KPRIORITY       BasePriority;
  155.         ULONG           ProcessId;
  156.         ULONG           InheritedFromProcessId;
  157.         ULONG           HandleCount;
  158.         ULONG           Reserved2[2];
  159.         VM_COUNTERS     VmCounters;
  160.         IO_COUNTERS     IoCounters; //windows 2000 only
  161.         struct _SYSTEM_THREADS Threads[1];
  162. }SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;


  163. PVOID GetShadowTable();
  164. PKAPC_STATE AttachToCsrss();

  165. typedef HANDLE HWND;
  166. typedef HWND (*pNtUserFindWindowEx)(
  167.                                                 IN HWND hwndParent,
  168.                                                 IN HWND hwndChild,
  169.                                                 IN PUNICODE_STRING pstrClassName,
  170.                                                 IN PUNICODE_STRING pstrWindowName);

  171. HWND MyNtUserFindWindowEx(
  172.                                                 IN HWND hwndParent,
  173.                                                 IN HWND hwndChild,
  174.                                                 IN PUNICODE_STRING pstrClassName,
  175.                                                 IN PUNICODE_STRING pstrWindowName);

  176. #define ProbeAndReadUnicodeString(Source) \
  177.         (((Source) >= (UNICODE_STRING * const)MM_USER_PROBE_ADDRESS) ? \
  178.         (*( UNICODE_STRING * const)MM_USER_PROBE_ADDRESS) : (*( UNICODE_STRING *)(Source)))
复制代码
Driver.cpp
  1. #include "Driver.h"

  2. pNtUserFindWindowEx g_pfnNtUserFindWindowEx = NULL;
  3. PServiceDescriptorTableEntry_t KeServiceDescriptorTableShadow = NULL;
  4. PKAPC_STATE g_pKapcState;

  5. void PageProtectOn()
  6. {
  7.         //恢复内存保护
  8.         __asm
  9.         {
  10.                 mov eax, cr0
  11.                         or eax, 10000h
  12.                         mov cr0, eax
  13.                         sti
  14.         }
  15. }

  16. void PageProtectOff()
  17. {
  18.         //去掉内存保护
  19.         __asm
  20.         {
  21.                 cli
  22.                         mov eax, cr0
  23.                         and eax, not 10000h
  24.                         mov cr0, eax
  25.         }
  26. }


  27. PVOID GetShadowTable()
  28. {
  29.        
  30.         PUCHAR pKeAddSystemAddr = (PUCHAR)KeAddSystemServiceTable;

  31.         for (ULONG i = 0; i < 4096; i++, pKeAddSystemAddr++)
  32.         {
  33.                 PUCHAR p = (PUCHAR)*(PULONG)pKeAddSystemAddr;

  34.                 if (MmIsAddressValid(p))
  35.                 {
  36.                         __try
  37.                         {
  38.                                         if (p == (PUCHAR)KeServiceDescriptorTable)
  39.                                         {
  40.                                                 continue;
  41.                                         }
  42.                                         else
  43.                                         {
  44.                                                 return p;
  45.                                         }       
  46.                         }
  47.                         __except(EXCEPTION_EXECUTE_HANDLER)
  48.                         {
  49.                                 return NULL;
  50.                         }
  51.                 }
  52.         }

  53.         return NULL;
  54. }


  55. #pragma PAGEDCODE
  56. PKAPC_STATE AttachToCsrss()
  57. {
  58.         PVOID pBuffer = NULL;
  59.         ULONG uBufferSize = 1000 * sizeof(SYSTEM_PROCESSES);
  60.         ULONG uRetLength = 0;
  61.         NTSTATUS status;
  62.         UNICODE_STRING usstrCsrss;

  63.         PKAPC_STATE pApcState = NULL;

  64.         RtlInitUnicodeString(&usstrCsrss, L"csrss.exe");

  65.         do
  66.         {
  67.                 if (pBuffer != NULL)
  68.                 {
  69.                         ExFreePool(pBuffer);
  70.                         pBuffer = NULL;
  71.                 }
  72.                 pBuffer = ExAllocatePoolWithTag(PagedPool, uBufferSize, '0123');
  73.                 if (pBuffer == NULL)
  74.                 {
  75.                         return NULL;
  76.                 }
  77.                 status =  ZwQuerySystemInformation(SystemProcessInformation, pBuffer, uBufferSize, &uRetLength);
  78.                 if (status != STATUS_SUCCESS && status != STATUS_INFO_LENGTH_MISMATCH)
  79.                 {
  80.                         break;
  81.                 }
  82.                
  83.                 uBufferSize = uBufferSize * 2;

  84.         } while (status != STATUS_SUCCESS && uBufferSize < 1000000);
  85.        

  86.         if (status == STATUS_SUCCESS)
  87.         {
  88.                 PSYSTEM_PROCESSES pSyeInfo = (PSYSTEM_PROCESSES)pBuffer;
  89.                 do
  90.                 {
  91.                         if (RtlCompareUnicodeString(&pSyeInfo->ProcessName, &usstrCsrss, TRUE) == 0)
  92.                         {
  93.                                 KdPrint(("find %wZ\n", &pSyeInfo->ProcessName));
  94.                                 ULONG uPID = pSyeInfo->ProcessId;
  95.                                 HANDLE hProcess = NULL;
  96.                                 OBJECT_ATTRIBUTES ObjectAttributes;
  97.                                 InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
  98.                                 CLIENT_ID ClientId;
  99.                                 ClientId.UniqueProcess = (HANDLE)uPID;
  100.                                 ClientId.UniqueThread = 0;
  101.                                 status = NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId);
  102.                                
  103.                                 if (status == STATUS_SUCCESS)
  104.                                 {
  105.                                         PEPROCESS pEprocess = NULL;
  106.                                         status = ObReferenceObjectByHandle(hProcess, PROCESS_ALL_ACCESS, NULL, KernelMode, (PVOID *)&pEprocess, NULL);

  107.                                         if (status == STATUS_SUCCESS)
  108.                                         {
  109.                                                 pApcState = (PKAPC_STATE)ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), 'APC');
  110.                                                
  111.                                                 if (pApcState)
  112.                                                 {
  113.                                                         KeStackAttachProcess(pEprocess, pApcState);
  114.                                                 }

  115.                                                 ObDereferenceObject(pEprocess);
  116.                                         }
  117.                                         ZwClose(hProcess);
  118.                                 }

  119.                         }

  120.                         pSyeInfo = (PSYSTEM_PROCESSES) ((ULONG)pSyeInfo + pSyeInfo->NextEntryDelta);

  121.                 } while (pSyeInfo->NextEntryDelta && pApcState == NULL);
  122.         }

  123.         if (pBuffer != NULL)
  124.         {
  125.                 ExFreePool(pBuffer);
  126.         }

  127.         return pApcState;
  128.        
  129. }




  130. #pragma PAGEDCODE
  131. ULONG GetSSSDTAddr(ULONG uIndex)
  132. {
  133.         //ULONG u_index;

  134.         //for (u_index = 0; u_index < KeServiceDescriptorTableShadow->NumberOfServices; u_index++)
  135.         //{
  136.         //        KdPrint(("KeServiceDescriptorTableShadow[%d]:%X\n", u_index, KeServiceDescriptorTableShadow->ServiceTableBase[u_index]));
  137.         //}

  138.         if (KeServiceDescriptorTableShadow == NULL)
  139.         {
  140.                 return 0;
  141.         }

  142.         ULONG uAddr = (ULONG)KeServiceDescriptorTableShadow->ServiceTableBase[uIndex];

  143.         return uAddr;
  144. }


  145. BOOLEAN HookSSSDT(ULONG uIndex, ULONG uNewAddr)
  146. {
  147.         if (uNewAddr == 0)
  148.         {
  149.                 return FALSE;
  150.         }

  151.         PageProtectOff();
  152.         KeServiceDescriptorTableShadow->ServiceTableBase[uIndex] = uNewAddr;
  153.         PageProtectOn();

  154.         return TRUE;
  155. }


  156. BOOLEAN UnHookSSSDT(ULONG uIndex, ULONG uOldAddr)
  157. {
  158.         if (uOldAddr == 0)
  159.         {
  160.                 return FALSE;
  161.         }

  162.         PageProtectOff();
  163.         KeServiceDescriptorTableShadow->ServiceTableBase[uIndex] = uOldAddr;
  164.         PageProtectOn();

  165.         return TRUE;
  166. }


  167. HWND MyNtUserFindWindowEx(
  168.                                                   IN HWND hwndParent,
  169.                                                   IN HWND hwndChild,
  170.                                                   IN PUNICODE_STRING pstrClassName,
  171.                                                   IN PUNICODE_STRING pstrWindowName)
  172. {
  173.         UNICODE_STRING strClassName;
  174.         UNICODE_STRING strWindowName;

  175.         __try
  176.         {
  177.                 strClassName = ProbeAndReadUnicodeString(pstrClassName);
  178.                 strWindowName = ProbeAndReadUnicodeString(pstrWindowName);

  179.                 ProbeForRead(strClassName.Buffer, strClassName.Length, sizeof(WCHAR));
  180.                 ProbeForRead(strWindowName.Buffer, strWindowName.Length, sizeof(WCHAR));

  181.                 KdPrint(("ClassName %wZ --- WindowName %wZ\n", &strClassName, &strWindowName));
  182.         }
  183.         __except(EXCEPTION_EXECUTE_HANDLER)
  184.         {

  185.         }

  186.         return g_pfnNtUserFindWindowEx(hwndParent, hwndChild, pstrClassName, pstrWindowName);
  187. }



  188. #pragma INITCODE
  189. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  190. {
  191.   NTSTATUS status = STATUS_SUCCESS;
  192.   KeServiceDescriptorTableShadow = (PServiceDescriptorTableEntry_t)GetShadowTable();
  193.   KeServiceDescriptorTableShadow += 1;
  194.   g_pKapcState = AttachToCsrss();
  195.   if (g_pKapcState != NULL)
  196.   {
  197.           ULONG uAddr = GetSSSDTAddr(378);
  198.           if (uAddr)
  199.           {
  200.                   g_pfnNtUserFindWindowEx = (pNtUserFindWindowEx)uAddr;
  201.                   KdPrint(("NtUserFindWindowEx: 0x%08X\n", uAddr));
  202.                   HookSSSDT(378, (ULONG)MyNtUserFindWindowEx);
  203.           }
  204.           
  205.   }
  206.   DriverObject->DriverUnload = DriverUnload;
  207.   return status;
  208. }

  209. #pragma PAGEDCODE
  210. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  211. {
  212.   
  213.   UnHookSSSDT(378, (ULONG)g_pfnNtUserFindWindowEx);
  214.   if (g_pKapcState != NULL)
  215.   {
  216.           KeUnstackDetachProcess(g_pKapcState);
  217.           ExFreePool(g_pKapcState);
  218.   }

  219.   KdPrint(("DriverEntry unLoading...\n"));
  220.   
  221. }
复制代码

返回列表