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

多核 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. #pragma pack(pop)

  41. 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. void PageProtectOn()
  7. {
  8.         //恢复内存保护
  9.         __asm
  10.         {
  11.                 mov eax, cr0
  12.                 or eax, 10000h
  13.                 mov cr0, eax
  14.                 sti
  15.         }
  16. }

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


  28. void GetIdt(ULONG uCPU)
  29. {
  30.         IDTR idtr;
  31.         __asm SIDT idtr


  32.         PIDTENTRY pIdtEntry = NULL;
  33.         pIdtEntry = (PIDTENTRY)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);

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

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


  40. ULONG GetInterruptFuncAddress(ULONG InterruptIndex)
  41. {
  42.         IDTR idtr;
  43.         PIDTENTRY pIdtEntry;

  44.         __asm SIDT idtr;

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

  46.         return MAKELONG(pIdtEntry[InterruptIndex].LowOffset, pIdtEntry[InterruptIndex].HigOffset);
  47. }

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

  52. __declspec(naked) void NewInterruptFun3()
  53. {
  54.         __asm
  55.         {
  56.                 pushad
  57.                 pushfd
  58.                 push fs

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

  65.                 pop fs
  66.                 popfd
  67.                 popad

  68.                 jmp g_OrgInterruptFunc3
  69.         }
  70. }


  71. void HookInterrupt(ULONG uCPU, ULONG InterruptIndex, ULONG NewInterruptFunc)
  72. {
  73.         IDTR idtr;
  74.         __asm SIDT idtr


  75.         PIDTENTRY pIdtEntry = NULL;
  76.         pIdtEntry = (PIDTENTRY)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);

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

  78.         PageProtectOff();

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

  81.         PageProtectOn();
  82. }


  83. VOID HookIdtDpc(
  84.                   IN struct _KDPC  *Dpc,
  85.                   IN PVOID  DeferredContext,
  86.                   IN PVOID  SystemArgument1,
  87.                   IN PVOID  SystemArgument2
  88.                   )
  89. {
  90.         HookInterrupt(g_CurrentCpuAffinity, (ULONG)SystemArgument1, (ULONG)SystemArgument2);
  91.         KeSetEvent(&g_Event, IO_NO_INCREMENT, FALSE);
  92. }


  93. void HandleIdtByDpc(ULONG InterruptIndex, ULONG NewInterruptFunc)
  94. {
  95.         KAFFINITY CpuAffinity;
  96.         ULONG uCpuCount = 0;
  97.         ULONG i = 0;
  98.         KDPC Dpc;

  99.         CpuAffinity = KeQueryActiveProcessors();

  100.         for (i = 0; i < sizeof(KAFFINITY); i++)
  101.         {
  102.                 if ((CpuAffinity >> i) & 1)
  103.                 {
  104.                         uCpuCount++;
  105.                 }
  106.         }

  107.         if (uCpuCount == 1)
  108.         {
  109.                 KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
  110.                 HookInterrupt(0, InterruptIndex, NewInterruptFunc);
  111.                 KeLowerIrql(OldIrql);
  112.         }
  113.         else
  114.         {
  115.                 for (i = 0; i < sizeof(KAFFINITY); i++)
  116.                 {
  117.                         if ((CpuAffinity >> i) & 1)
  118.                         {
  119.                                 g_CurrentCpuAffinity = i;
  120.                                 KeInitializeEvent(&g_Event, NotificationEvent, FALSE);
  121.                                 KeInitializeDpc(&Dpc, HookIdtDpc, NULL);
  122.                                 KeSetTargetProcessorDpc(&Dpc, (CCHAR)i);
  123.                                 KeSetImportanceDpc(&Dpc, HighImportance);
  124.                                 KeInsertQueueDpc(&Dpc, (PVOID)InterruptIndex, (PVOID)NewInterruptFunc);

  125.                                 if (KeWaitForSingleObject(&g_Event, (KWAIT_REASON)0, 0, 0, 0) == STATUS_SUCCESS)
  126.                                 {
  127.                                         continue;
  128.                                 }
  129.                         }
  130.                 }
  131.         }
  132. }




  133. #pragma INITCODE
  134. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  135. {
  136.     NTSTATUS status = STATUS_SUCCESS;

  137.         g_OrgInterruptFunc3 = GetInterruptFuncAddress(3);
  138.        
  139.         HandleIdtByDpc(3, (ULONG)NewInterruptFun3);

  140.     DriverObject->DriverUnload = DriverUnload;
  141.     return status;
  142. }

  143. #pragma PAGEDCODE
  144. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  145. {
  146.   
  147.         HandleIdtByDpc(3, g_OrgInterruptFunc3);
  148.     KdPrint(("DriverEntry unLoading...\n"));
  149.   
  150. }
复制代码

返回列表