首页
社区
课程
招聘
[原创]多核机器下添加新中断的方法
发表于: 2008-12-11 23:51 8623

[原创]多核机器下添加新中断的方法

2008-12-11 23:51
8623

【文章标题】: 多核情况下添加新中断的方法
【文章作者】: chimney
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
     中断向量表的修改应该都很熟悉了,combojiang大侠在他的rootkit hook系列文章里将的很详细了。但是combojiang文章
  中有关IDT的代码都是在单核机器中实现的,如果你有个双核的机子,你正好又学习了combojiang大大的文章,你就会发现出
  问题了。因为每个CPU 都有自己的中断向量表。在多核的机子上,如果你修改了CPU 1的中断向量表,如果应用程序不是运行
  在CPU 1上,而是在别的CPU上,这时候就会出现问题了。
     在多核的 CPU 上添加新中断,我想方法有两种。一种是让应用程序运行在修改中断向量表的那个CPUS上,另一个是将所有
  的CPU的中断向量表都修改,这样应用层就不用管自己运行在那个CPU上了,中断都不会导致系统的崩溃。
     让某个程序运行在某个CPU上,那就要设置程序的亲和性了,在应用层设置进程和线程的亲和性的函数是
  SetProcessAffinityMask/SetThreadAffinityMask。那么在内核呢?google了下,发现了diyhack 提到了个函数
  KeSetSystemAffinityThread。
  
     KeSetSystemAffinityThread是个内核导出的函数,但在DDK头文件中没有发现他的定义,帮助中也没有看见有文字介绍,
  于是就直奔WRK。在WRK中找到了这个函数。
  
  VOID
  KeSetSystemAffinityThread (
      __in KAFFINITY Affinity
      )
  
  /*++
  Routine Description:
      This function set the system affinity of the current thread
  Arguments:
      Affinity - Supplies the new of set of processors on which the thread can run.
  Return Value:
      None.
  --*/
  
     KeSetSystemAffinityThread 设置当前线程的系统亲和性。在wrk和google的帮助下,实现了在多核下修改IDT比较稳定的
  方法。
  
  #include "ntddk.h"
  #include "string.h"
  #include "stdio.h"
  #define ADDINT                0x22
  
  #define MAX_NUM_PROCESSER   8
  
  extern VOID KeSetSystemAffinityThread(KAFFINITY Affinity);   //函数声明下
  
  #pragma pack(1)
  typedef struct
  {
      unsigned short LowOffset;
      unsigned short selector;
      unsigned char unused_lo;
      unsigned char segment_type:4;                           //0x0E is an interrupt gate
      unsigned char system_segment_flag:1;
      unsigned char DPL:2;                                  // descriptor privilege level
      unsigned char P:1;                                  // present
      unsigned short HiOffset;
  } IDTENTRY;
  
  
  typedef struct
  {
      unsigned short IDTLimit;
      union
      {
          unsigned long IDTbase;
      };
  } IDTINFO;
  #pragma pack(1)
  
  IDTENTRY OldIdtEntry[MAX_NUM_PROCESSER]={ 0 };
  IDTINFO idt_info[MAX_NUM_PROCESSER]={ 0 };
  ULONG orgcr0;
  
  void __declspec (naked) InterruptHandler()  
  {
      _asm iretd
                 
  }
  
  VOID DisableWriteProtect(PULONG pOldAttr)
  {
          ULONG uAttr;
          _asm
          {
                  push eax
                  mov eax, cr0
                  mov uAttr, eax
                  and eax, 0FFFEFFFFh // CR0 16 BIT = 0
                  mov cr0, eax
                  pop eax
          };
          *pOldAttr = uAttr; //保存原有的 CRO 属性       
  }
  
  VOID EnableWriteProtect(ULONG uOldAttr )
  {
          _asm
          {
                  push eax
                  mov eax, uOldAttr //恢复原有 CR0 属性
                  mov cr0, eax
                  pop eax
          };       
  }
  
  VOID AddInterrupt(LONG dwIndex)
  {  
          IDTENTRY* idt_entries;  
          IDTINFO idt_infoTmp;
  
          __asm sidt idt_infoTmp;
  
          idt_info[dwIndex]=idt_infoTmp;
      idt_entries = (IDTENTRY*)idt_info[dwIndex].IDTbase;
  
          DbgPrint("idt_entries=%x",idt_entries);
  
      if ((idt_entries[ADDINT].LowOffset != 0) || (idt_entries[ADDINT].HiOffset != 0))
            return;
  
      DisableWriteProtect(&orgcr0);
      memcpy(&OldIdtEntry[dwIndex], &idt_entries[ADDINT], sizeof(IDTENTRY));
      idt_entries[ADDINT].LowOffset = (unsigned short)InterruptHandler;
      idt_entries[ADDINT].selector = 8;
      idt_entries[ADDINT].unused_lo = 0;
      idt_entries[ADDINT].segment_type = 0xE;
      idt_entries[ADDINT].system_segment_flag = 0;
      idt_entries[ADDINT].DPL = 3;
      idt_entries[ADDINT].P = 1;
      idt_entries[ADDINT].HiOffset = (unsigned short)((unsigned int) InterruptHandler>>16);
      EnableWriteProtect(orgcr0);
  
          return;
  }
  
  void RemoveInterrupt(LONG dwIndex)
  {
      IDTENTRY* idt_entries;
      idt_entries = (IDTENTRY*)idt_info[dwIndex].IDTbase;
  
      DbgPrint("idt_entries=%x",idt_entries);
         
      DisableWriteProtect(&orgcr0);
       memcpy(&idt_entries[ADDINT], &OldIdtEntry[dwIndex], sizeof(IDTENTRY));
      EnableWriteProtect(orgcr0);
  }
  
  void DriverUnload (IN PDRIVER_OBJECT pDriverObject)
  {
          KAFFINITY     ActiveProcessors, CurrentAffinity;
          LONG  dwTmp=0;
          ActiveProcessors=KeQueryActiveProcessors();
  
          DbgPrint("KeActiveProcessors=%d",ActiveProcessors);
  
           for (CurrentAffinity = 1; ActiveProcessors; CurrentAffinity <<= 1)
            {
                  if (ActiveProcessors & CurrentAffinity)
                   {
                      ActiveProcessors &= ~CurrentAffinity;
                      KeSetSystemAffinityThread(CurrentAffinity);
                      RemoveInterrupt(dwTmp);       
                      dwTmp++;
                  }
           }
  }
  
  NTSTATUS
  DriverEntry(
          IN PDRIVER_OBJECT                DriverObject,
          IN PUNICODE_STRING                RegistryPath
          )
  {
          NTSTATUS      status = STATUS_SUCCESS;
          KAFFINITY     ActiveProcessors, CurrentAffinity;
          LONG              dwTmp=0;
          ActiveProcessors=KeQueryActiveProcessors();
          DbgPrint("KeActiveProcessors=%d",ActiveProcessors);
          for (CurrentAffinity = 1; ActiveProcessors; CurrentAffinity <<= 1)
          {
                 if (ActiveProcessors & CurrentAffinity)
                   {
                    ActiveProcessors &= ~CurrentAffinity;
                    KeSetSystemAffinityThread(CurrentAffinity);
                      AddInterrupt(dwTmp);
                      dwTmp++;
                  }
          }       
          DriverObject->DriverUnload = DriverUnload;
          return status;
  }
  
--------------------------------------------------------------------------------

  如有错误之处,还请大家指出!酷睿双核 windows xp sp2 下测试通过
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年12月11日 23:45:32


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (8)
雪    币: 215
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好文,收藏先
2008-12-12 07:34
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
收下慢慢学习。
2008-12-12 09:02
0
雪    币: 200
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
现在多核的机器越来越多了,买本本想买个单核的都难。

下来收藏。。。

谢谢lz
2008-12-12 11:29
0
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
哈哈慢慢研究
2008-12-12 11:52
0
雪    币: 255
活跃值: (49)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
6
好帖 感谢lz分享 ^_^
2008-12-12 12:19
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
还是投DPC把所有CPU的IDT都hook了比较好用,呵呵```
不过还是顶下楼主```8错8错``
2008-12-12 13:21
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我水平有限,没看懂
2008-12-12 17:26
0
雪    币: 251
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
9
郁闷,想买个多核玩都没钱
2008-12-13 11:39
0
游客
登录 | 注册 方可回帖
返回
//