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

多核下通过修改GDT隐藏IDT HOOK

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

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

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

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

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

  17. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);

  18. #define WORD USHORT
  19. #define DWORD ULONG
  20. #define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))

  21. #pragma pack(push)
  22. #pragma pack(1) // 1字节对齐
  23. typedef struct _IDTR //IDT基址
  24. {
  25.         USHORT IDT_limit; //范围占位
  26.         USHORT IDT_LOWbase;//基地址占位_IDT_ENTRY类型指针
  27.         USHORT IDT_HIGbase;
  28. }IDTR,*PIDTR;

  29. typedef struct _IDT_ENTRY
  30. {
  31.         USHORT LowOffset; //中断处理函数地址低位
  32.         USHORT selector; //选择符
  33.         UCHAR  reserved;
  34.         UCHAR  type:4;         //4位
  35.         UCHAR  always0:1;        //1位
  36.         UCHAR  dpl:2;                //2位
  37.         UCHAR  present:1;        //1位
  38.         USHORT HigOffset;//中断处理函数地址高位
  39. }IDTENTRY,*PIDTENTRY;//获取基址实际上是这个类型

  40. typedef struct _KGDTENTRY
  41. {
  42.         USHORT  LimitLow;
  43.         USHORT  BaseLow;
  44.         union {
  45.                 struct {
  46.                         UCHAR   BaseMid;
  47.                         UCHAR   Flags1;     // Declare as bytes to avoid alignment
  48.                         UCHAR   Flags2;     // Problems.
  49.                         UCHAR   BaseHi;
  50.                 } Bytes;
  51.                 struct {
  52.                         ULONG   BaseMid : 8;
  53.                         ULONG   Type : 5;
  54.                         ULONG   Dpl : 2;
  55.                         ULONG   Pres : 1;
  56.                         ULONG   LimitHi : 4;
  57.                         ULONG   Sys : 1;
  58.                         ULONG   Reserved_0 : 1;
  59.                         ULONG   Default_Big : 1;
  60.                         ULONG   Granularity : 1;
  61.                         ULONG   BaseHi : 8;
  62.                 } Bits;
  63.         } HighWord;
  64. } KGDTENTRY, *PKGDTENTRY;

  65. #pragma pack(pop)

  66. EXTERN_C NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
复制代码
Driver.cpp
  1. #include "Driver.h"

  2. //global

  3. KEVENT g_Event ;
  4. ULONG g_CurrentCpuAffinity = 0;
  5. ULONG g_OrgInterruptFunc3;
  6. ULONG g_uNewBase;
  7. USHORT g_FilterJmp[3];

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

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


  30. void GetIdt(ULONG uCPU)
  31. {
  32.         IDTR idtr;
  33.         __asm SIDT idtr


  34.         PIDTENTRY pIdtEntry = NULL;
  35.         pIdtEntry = (PIDTENTRY)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);

  36.         KdPrint(("pIdtEntry: %X\n", pIdtEntry));

  37.         for (ULONG uIndex = 0; uIndex <= idtr.IDT_limit / sizeof(IDTENTRY); uIndex++)
  38.         {
  39.                 KdPrint(("uCPU:%d---pIdtEntry[%d]: %X\n", uCPU, uIndex, MAKELONG(pIdtEntry[uIndex].LowOffset, pIdtEntry[uIndex].HigOffset)));
  40.         }
  41. }


  42. ULONG GetInterruptFuncAddress(ULONG InterruptIndex)
  43. {
  44.         IDTR idtr;
  45.         PIDTENTRY pIdtEntry;

  46.         __asm SIDT idtr;

  47.         pIdtEntry = (PIDTENTRY)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);

  48.         return MAKELONG(pIdtEntry[InterruptIndex].LowOffset, pIdtEntry[InterruptIndex].HigOffset);
  49. }

  50. VOID __stdcall FilterInterruptFunc3()
  51. {
  52.         KdPrint(("CurrentProcess:%s\n", PsGetProcessImageFileName(IoGetCurrentProcess())));
  53. }

  54. __declspec(naked) void NewInterruptFun3InOrigBase()
  55. {
  56.         __asm
  57.         {
  58.                 pushad
  59.                 pushfd
  60.                 push fs

  61.                 push 0x30
  62.                 pop fs
  63.                 mov ax, 0x23
  64.                 mov ds, ax
  65.                 mov es, ax
  66.                 call FilterInterruptFunc3

  67.                 pop fs
  68.                 popfd
  69.                 popad

  70.                 jmp g_OrgInterruptFunc3
  71.         }
  72. }

  73. __declspec(naked) void NewInterruptFun3()
  74. {
  75.         __asm
  76.         {
  77.                 jmp fword ptr [g_FilterJmp]
  78.         }
  79. }

  80. void HookInterrupt(ULONG uCPU, ULONG InterruptIndex, ULONG NewInterruptFunc)
  81. {
  82.         IDTR idtr;
  83.         __asm SIDT idtr


  84.         PIDTENTRY pIdtEntry = NULL;
  85.         pIdtEntry = (PIDTENTRY)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);

  86.         KdPrint(("uCPU:%d---pIdtEntry: %X\n", uCPU, pIdtEntry));

  87.         PageProtectOff();

  88.         pIdtEntry[InterruptIndex].LowOffset =(USHORT)((ULONG)NewInterruptFunc & 0xffff);
  89.         pIdtEntry[InterruptIndex].HigOffset = (USHORT)((ULONG)NewInterruptFunc >> 16);

  90.         PageProtectOn();
  91. }

  92. void HookInterruptFromGdt(ULONG uCPU, ULONG InterruptIndex, BOOLEAN bHook)
  93. {
  94.         IDTR idtr;

  95.         __asm SIDT idtr
  96.         PIDTENTRY pIdtEntry = NULL;
  97.         pIdtEntry = (PIDTENTRY)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);
  98.        

  99.         ULONG uGdtAddr = 0;
  100.         __asm
  101.         {
  102.                 push edx
  103.                 SGDT [esp - 2]
  104.                 pop edx
  105.                 mov uGdtAddr, edx
  106.         }
  107.         PKGDTENTRY pGdtEntry = (PKGDTENTRY)uGdtAddr;

  108.         KdPrint(("uCPU:%d---pIdtEntry:%X---pGdtEntry:%X\n", uCPU, pIdtEntry, pGdtEntry));

  109.         PageProtectOff();

  110.         if (bHook)
  111.         {
  112.                 pIdtEntry[InterruptIndex].selector = 0xa8;
  113.                 RtlCopyMemory(&pGdtEntry[21], &pGdtEntry[1], sizeof(KGDTENTRY));
  114.                 pGdtEntry[21].BaseLow = (USHORT) (g_uNewBase & 0xffff);
  115.                 pGdtEntry[21].HighWord.Bytes.BaseMid = (UCHAR)((g_uNewBase >> 16) & 0xff);
  116.                 pGdtEntry[21].HighWord.Bytes.BaseHi = (UCHAR)(g_uNewBase >> 24);
  117.         }
  118.         else
  119.         {
  120.                 pIdtEntry[InterruptIndex].selector = 0x8;
  121.                 memset(&pGdtEntry[21], 0, sizeof(KGDTENTRY));
  122.         }

  123.         PageProtectOn();

  124. }


  125. VOID HookIdtDpc(
  126.                   IN struct _KDPC  *Dpc,
  127.                   IN PVOID  DeferredContext,
  128.                   IN PVOID  SystemArgument1,
  129.                   IN PVOID  SystemArgument2
  130.                   )
  131. {
  132.         HookInterruptFromGdt(g_CurrentCpuAffinity, (ULONG)SystemArgument1, (BOOLEAN)SystemArgument2);
  133.         KeSetEvent(&g_Event, IO_NO_INCREMENT, FALSE);
  134. }


  135. void HandleIdtByDpc(ULONG InterruptIndex, BOOLEAN bHook)
  136. {
  137.         KAFFINITY CpuAffinity;
  138.         ULONG uCpuCount = 0;
  139.         ULONG i = 0;
  140.         KDPC Dpc;

  141.         CpuAffinity = KeQueryActiveProcessors();

  142.         for (i = 0; i < sizeof(KAFFINITY); i++)
  143.         {
  144.                 if ((CpuAffinity >> i) & 1)
  145.                 {
  146.                         uCpuCount++;
  147.                 }
  148.         }

  149.         if (uCpuCount == 1)
  150.         {
  151.                 KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
  152.                 HookInterruptFromGdt(0, InterruptIndex, bHook);
  153.                 KeLowerIrql(OldIrql);
  154.         }
  155.         else
  156.         {
  157.                 for (i = 0; i < sizeof(KAFFINITY); i++)
  158.                 {
  159.                         if ((CpuAffinity >> i) & 1)
  160.                         {
  161.                                 g_CurrentCpuAffinity = i;
  162.                                 KeInitializeEvent(&g_Event, NotificationEvent, FALSE);
  163.                                 KeInitializeDpc(&Dpc, HookIdtDpc, NULL);
  164.                                 KeSetTargetProcessorDpc(&Dpc, (CCHAR)i);
  165.                                 KeSetImportanceDpc(&Dpc, HighImportance);
  166.                                 KeInsertQueueDpc(&Dpc, (PVOID)InterruptIndex, (PVOID)bHook);

  167.                                 if (KeWaitForSingleObject(&g_Event, (KWAIT_REASON)0, 0, 0, 0) == STATUS_SUCCESS)
  168.                                 {
  169.                                         continue;
  170.                                 }
  171.                         }
  172.                 }
  173.         }
  174. }




  175. #pragma INITCODE
  176. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  177. {
  178.     NTSTATUS status = STATUS_SUCCESS;

  179.         g_OrgInterruptFunc3 = GetInterruptFuncAddress(3);
  180.         g_uNewBase = (ULONG)NewInterruptFun3 - g_OrgInterruptFunc3;

  181.         *(PULONG)g_FilterJmp = (ULONG)NewInterruptFun3InOrigBase;
  182.         g_FilterJmp[2] = 0x8;

  183.         HandleIdtByDpc(3, TRUE);

  184.     DriverObject->DriverUnload = DriverUnload;
  185.     return status;
  186. }

  187. #pragma PAGEDCODE
  188. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  189. {
  190.        
  191.         HandleIdtByDpc(3, FALSE);
  192.    
  193.         KdPrint(("DriverEntry unLoading...\n"));
  194.   
  195. }
复制代码

返回列表