首页
社区
课程
招聘
[原创][有码]键盘过滤中关于IOAPIC重定位表的学习笔记
发表于: 2011-6-10 18:09 17583

[原创][有码]键盘过滤中关于IOAPIC重定位表的学习笔记

2011-6-10 18:09
17583
#define IOAPIC_REGSEL_PHYSICAL_ADDRESS  0xfec00000
#define IOAPIC_WIN_PHYSICAL_ADDRESS  \
  IOAPIC_REGSEL_PHYSICAL_ADDRESS + 0x10
[COLOR="SeaGreen"]//根据中断描述表来定义个中断门的结构[/COLOR]
typedef struct _INTGATE
{
  USHORT  OffsetLow;
  USHORT  Selector;
  UCHAR  Reserved;        [COLOR="SeaGreen"]//这个与是保留值,需要设置成NULL[/COLOR]
  UCHAR  Attributes;
  USHORT  OffsetHigh;
}INTGATE,*PINTGATE;
NTSTATUS
InsertNewInterruptRoutine(PVOID pNewRoutine,PULONG pulInterruptVectorNumber)
{
  NTSTATUS ReturnStatus;
  ULONG ulInterruptVectorNumber;
  PVOID pInterruptTableAddress;
  PINTGATE pstNewIntGate;
  [COLOR="SeaGreen"]//检测参数的合法性[/COLOR]
  if(!MmIsAddressValid(pNewRoutine))
    return STATUS_INVALID_PARAMETER;
  [COLOR="SeaGreen"]//获取idt表的地址[/COLOR]
  ReturnStatus = GetIdtServiceTableAddress(&pInterruptTableAddress);
  if(!NT_SUCCESS(ReturnStatus))
    return ReturnStatus;
  [COLOR="SeaGreen"]//枚举idt表[/COLOR]
  for(ulInterruptVectorNumber=1;ulInterruptVectorNumber<INT_VECTOR_MAX_COUNT+1;ulInterruptVectorNumber++)
  {
    [COLOR="SeaGreen"]//判断中断门是否已经存在[/COLOR]
    if(!IsInterruptVectorExisted(pInterruptTableAddress,ulInterruptVectorNumber))
      break;
  }
  if(ulInterruptVectorNumber > INT_VECTOR_MAX_COUNT)
    return STATUS_UNSUCCESSFUL;
  [COLOR="SeaGreen"]//保存中断向量号[/COLOR]
  *pulInterruptVectorNumber = ulInterruptVectorNumber;
  [COLOR="SeaGreen"]//填写中断门结构[/COLOR]
  pstNewIntGate = &((PINTGATE)pInterruptTableAddress)[ulInterruptVectorNumber];
  pstNewIntGate->Reserved = NULL;
  pstNewIntGate->Selector = 8;      [COLOR="SeaGreen"]//在内核中的段选择子[/COLOR]
  pstNewIntGate->Attributes = 0x80 | 0x08 | 0x06;
  pstNewIntGate->OffsetLow = (USHORT)pNewRoutine;
  pstNewIntGate->OffsetHigh = (USHORT)((ULONG)pNewRoutine >> sizeof(USHORT)*8);
  return STATUS_SUCCESS;
}


BOOLEAN                  [COLOR="SeaGreen"]//判断中断门是否存在[/COLOR]
IsInterruptVectorExisted(PVOID pIdtAddress,ULONG ulInterruptVectorNumber)
{
  PINTGATE pstIntGate;
  [COLOR="YellowGreen"][COLOR="SeaGreen"]//检测idt地址是否有效[/COLOR][/COLOR]
  if(!MmIsAddressValid(pIdtAddress))
    return STATUS_INVALID_PARAMETER;
  pstIntGate = &((PINTGATE)pIdtAddress)[ulInterruptVectorNumber];
  [COLOR="SeaGreen"]//判断中断门的P位,也就是判断该调用们是否有效[/COLOR]
  if(pstIntGate->Attributes & 0x80)
    return TRUE;
  return FALSE;
}


[COLOR="SeaGreen"]//获取IDT表的地址[/COLOR]
NTSTATUS
GetIdtServiceTableAddress(PVOID pIdtServiceTableAddressPointer)
{
  USHORT wSelectorAndOffset[3];
  ULONG ulUshortSize;
  ulUshortSize = sizeof(USHORT);
  __asm
  {
    pushad;
    pushfd;
    sidt [wSelectorAndOffset];
    lea esi,dword ptr [wSelectorAndOffset];
    add esi,[ulUshortSize];                        [COLOR="SeaGreen"]//将指针移到段内偏移值上[/COLOR]
    mov ebx,[pIdtServiceTableAddressPointer];
    mov eax,dword ptr [esi];
    mov dword ptr [ebx],eax;
    popfd;
    popad;
  }
  if(!(*(PULONG)pIdtServiceTableAddressPointer))              [COLOR="SeaGreen"]//如果获取失败的话,就返回不成功[/COLOR]
    return STATUS_UNSUCCESSFUL;
  return STATUS_SUCCESS;
}
NTSTATUS
ChangeInterruptVectorNumber(ULONG ulIrqVectorNumber,ULONG ulNewNumber,PULONG pulPerviousNumber)
{
  PHYSICAL_ADDRESS TempPhysicalAddress;
  PUCHAR  pIoRegSelAddress;
  PULONG  pIoWinAddress;
  [COLOR="SeaGreen"]//检查指针地址是否合法[/COLOR]
  if(!MmIsAddressValid(pulPerviousNumber))
    return STATUS_INVALID_PARAMETER;
  RtlZeroMemory(&TempPhysicalAddress,sizeof(TempPhysicalAddress));
  TempPhysicalAddress.LowPart = IOAPIC_REGSEL_PHYSICAL_ADDRESS;
  pIoRegSelAddress = (PUCHAR)MmMapIoSpace(TempPhysicalAddress,0x10+sizeof(ULONG),MmNonCached);
  [COLOR="SeaGreen"]//如果映射失败的话,就返回[/COLOR]
  if(!MmIsAddressValid(pIoRegSelAddress))
    return STATUS_UNSUCCESSFUL
  pIoWinAddress = (PULONG)(pIoRegSelAddress + 0x10);          [COLOR="SeaGreen"]//IOWIN的映射地址[/COLOR]
  [COLOR="SeaGreen"]//指定获取IRQ1的项,参考intel手册[/COLOR]
  *pIoRegSelAddress = 0x10 + (UCHAR)ulIrqVectorNumber * sizeof(UCHAR)*2;
  [COLOR="SeaGreen"]//保存原来的向量号[/COLOR]
  __asm
  {
    mov eax,[pIoWinAddress];
    movzx eax,byte ptr [eax];
    push eax;
    mov eax,[pulPerviousNumber];
    pop dword ptr [eax];
  }
  [COLOR="SeaGreen"]//设置新的中断向量号[/COLOR]
  __asm
  {
    mov eax,[pIoWinAddress];
    mov ecx,[ulNewNumber];
    mov byte ptr [eax],cl;
  }
  [COLOR="SeaGreen"]//解除地址映射[/COLOR]
  MmUnmapIoSpace(pIoRegSelAddress,0x10+sizeof(ULONG));
  return STATUS_SUCCESS;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (15)
雪    币: 248
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
虽然现在还没接触,但以后就说不定啦,谢谢楼主啦,收藏个
2011-6-10 18:33
0
雪    币: 44
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错......................................
2011-6-10 18:39
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
代码非常好看,排版也不错啊
2011-6-10 19:33
0
雪    币: 216
活跃值: (144)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
5
多谢,就为了让大家看得舒服点~
2011-6-10 19:37
0
雪    币: 88
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这么巧,我也在做这方面的工作,不过增加中断部分用的IoConnectInterrupt,还要考虑X64的部分。另外付Intel和AMD的芯片资料吧

。。。。AMD的传不上去。。。

给个名字大家去找吧:AMD-8111™ HyperTransport™ I/O Hub
上传的附件:
2011-6-10 19:51
0
雪    币: 216
活跃值: (144)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
7
感谢stonerhes兄提供的资料,其实俺在《寒江独钓》的光盘中也找到这个资料,就是忘记了
上传,反倒AMD的资料就没有了~~,想问问,网上的那个向intel公司免费申请intel手册还有效吗?
2011-6-10 19:59
0
雪    币: 88
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
AMD的有点大传不上去,Intel的手册貌似现在申请有点困难了
2011-6-10 20:05
0
雪    币: 216
活跃值: (144)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
9
怪不得发了两封邮件都没有回应啦~~~
2011-6-10 20:13
0
雪    币: 122
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
good 学习!
2011-6-11 11:18
0
雪    币: 2314
活跃值: (2205)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
11
好文章, 有时间学习一下.
2011-6-27 21:26
0
雪    币: 12
活跃值: (220)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
任何语言都无法表达我对君的敬佩和羡慕之情,都是多余的!已经到了五体投地,无以复加的程度。
读君之文,犹如醍醐灌顶,拨云见日。配以代码,更是游刃有余,得心应手。穷谢!!!!!
2011-8-19 17:29
0
雪    币: 12
活跃值: (220)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
任何语言都无法表达我对君的敬佩和羡慕之情,都是多余的!已经到了五体投地,无以复加的程度。
读君之文,犹如醍醐灌顶,拨云见日。配以代码,更是游刃有余,得心应手。穷谢!!!!!
2011-8-19 17:31
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
14
任何语言都无法表达我对君的敬佩和羡慕之情,都是多余的!已经到了五体投地,无以复加的程度。
读君之文,犹如醍醐灌顶,拨云见日。配以代码,更是游刃有余,得心应手
2011-8-19 18:19
0
雪    币: 1157
活跃值: (847)
能力值: ( LV8,RANK:150 )
在线值:
发帖
回帖
粉丝
15
但是大家都没有说 为什么IRQ1对应的就是IOAPIC中的第二项啊,这个事CPU中固定的吗?就是说

IRQ0 -- > 重定位表中的第一项
IRQ1 -- > 重定位表中的第二项
.......

不知道是不是这样!然后大家就直接说了,键盘的中断请求为IRQ1,所以取的是 重定位表中的第二项
2011-8-20 14:50
0
雪    币: 57
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
关于键盘的端口可以通过io hook 转向, 就是usb 键盘在bios转向到port 64 60
另外对于多个cpu 每个都有apic ,
2011-8-20 17:51
0
游客
登录 | 注册 方可回帖
返回
//