IDT系列:(一)初探IDT,InterruptDescriptorTable,中断描述符表

更新时间:2023-05-12 13:18:54 阅读: 评论:0

IDT系列:(⼀)初探IDT,InterruptDescriptorTable,中断描
述符表
IDT,Interrupt Descriptor Table,中断描述符表是CPU⽤来处理中断和程序异常的。
⼀、有关IDT的基本知识
1、中断时⼀种机制,⽤来处理硬件需要向CPU输⼊信息的情况。⽐如⿏标,键盘等。
2、中断和异常的产⽣是随机的,在CPU正常运⾏过程中随时可能产⽣。CPU的中断处理机制
3、中断可以由硬件产⽣(称为外部中断),也可以由软件产⽣(称为内部中断),在程序中写⼊int n指令可以产⽣n号中断和异常(n从0-ffh)。
4、同时CPU的中断异常机制还是重要特性的⽀持原理,⽐如程序调试,程序运⾏过程中的异常处理(如零除数异常、内存分页错误等)。
5、早期的操作系统甚⾄是通过中断来进⾏内核调⽤的。int指令是⼀种c从ring3 进⼊ring 0的⽅法。⽐如windows在xp版本之前使⽤的int
2e。在x86 CPU提供了synter指令后,这种⽅式才被放弃。
6、每⼀种中断对应⼀个中断号。CPU执⾏中断指令时,会去IDT表中查找对应的中断服务程序(interrupt rvice routine ,ISR)。
ISR(为了表述⽅便后⾯⽤ISR n表⽰n号中断的处理程序),x86CPU最⼤可以⽀持256种中断。
7、中断是CPU的机制,不管运⾏的是什么操作系统,只有是运⾏于x86架构,IDT结构式必然存在的。IDT表中的ISRs应该有操作系统提供。
8、异常分为错误(Faults)、陷阱(Traps)和终⽌(Aborts)三种,其区别是“错误”允许产⽣错误的程序继续允许,“陷阱”也可以,但
是“错误”产⽣于指令执⾏后,⽽“陷阱”需要在产⽣异常的指令执⾏后,因此从“错误”中返回时继续执⾏产⽣错误的指令,⽽从“陷阱返”回时应当从产⽣异常的指令后开始执⾏。终⽌产⽣时,处理程序不能得到精确的异常产⽣的代码位置,程序不能继续进⾏,硬件错误会产⽣“终⽌”。例如page faults就是⼀个faults,mov [eax], ecx,产⽣了⼀个分页错误,表⾯[eax]内存是⽆效,需要先进⾏分页处理从新映射物理内存然后才能继续进⾏mov操作;⽽断点是⼀个Trap。
9、Intel指定或保留了前32个中断号的作⽤,操作系统可以指定其余的中断号的作⽤。
10、中断的过程中可以产⽣新的中断。中断时有优先级的,⾼优先级的中断可以“中断”低优先级的中断。有的ISR不能被中断,可以使⽤STI (t interrupt-enable flag) and CLI(clear interrupt-enable flag)设置IF标志来启动和关闭中断。
(更详细的内容可以参考)
⼆、IDT表的结构
中断处理过程是有CPU直接调⽤的,CPU有专门的寄存器IDTR来保存IDT在内存中的位置,本⽂写为IDTR.ba。IDTR有48为,前32为是IDT在内存中的位置(线性地址),后16为是IDT的⼤⼩,本⽂写为IDT.limit。程序可以使⽤LIDT和SIDT指令来读写IDTR。
IDT是⼀个最⼤为256项的表,每个表项为8字节。称为中断门。CPU通过IDT.ba+n*8来寻找门。
根据中断号对应的异常类型不同(Faults/Traps/Aborts)8个字节的意义也不同。
如上图所⽰IDT门中的最后两个byte是ISR在内存中的⾼16位,最开始前两个字节是ISR在内存中地址的低16位。
三、使⽤WinDbg观察、调试IDT
使⽤Vmware配置好内核调试环境[]。
WinDbg有⽀持查看IDT的扩展命令!idt
!idt –a 命令可以看到所有中断处理函数的地址。
r idtr 参看idtr寄存器中保存的idt表地址。
idt每个表项有8bytes,两个dword⼤。
(注意.reload /i 加载符号⽂件)
kd> !idt -a
Dumping IDT:
00: 8053f19c nt!KiTrap00
01: 8053f314 nt!KiTrap01
02: Task Selector = 0x0058
03: 8053f6e4 nt!KiTrap03
04: 8053f864 nt!KiTrap04
05: 8053f9c0 nt!KiTrap05
06: 8053fb34 nt!KiTrap06
07: 8054019c nt!KiTrap07
08: Task Selector = 0x0050
09: 805405c0 nt!KiTrap09
0a: 805406e0 nt!KiTrap0A
0b: 80540820 nt!KiTrap0B
0c: 80540a7c nt!KiTrap0C
0d: 80540d60 nt!KiTrap0D
0e: 80541450 nt!KiTrap0E
… …
kd> r idtr
idtr=8003f400
kd> db idtr
8003f400  9c f1 08 00 00 8e 53 80-14 f3 08 00 00 8e 53 80  ......S.......S.
8003f410  3e 11 58 00 00 85 00 00-e4 f6 08 00 00 ee 53 80  >.X...........S.
8003f420  64 f8 08 00 00 ee 53 80-c0 f9 08 00 00 8e 53 80  d.....S.......S.
8003f430  34 fb 08 00 00 8e 53 80-9c 01 08 00 00 8e 54 80  4.....S.......T.
8003f440  98 11 50 00 00 85 00 00-c0 05 08 00 00 8e 54 80  ..P...........T.
8003f450  e0 06 08 00 00 8e 54 80-20 08 08 00 00 8e 54 80  ......T. .....T.
8003f460  7c 0a 08 00 00 8e 54 80-60 0d 08 00 00 8e 54 80  |.....T.`.....T.
8003f470  50 14 08 00 00 8e 54 80-80 17 08 00 00 8e 54 80  P.....T.......T.
可以看到,这个时候IDT的基地址是在803f400处。
注意观察其中3号中断门 e4 f6 08 00 00 ee 53 80 ISR 3
int 3是trap门,按照之前说的ISR地址构造⽅法,得到8053f6e4的中断服务程序地址。
好,我们观察了IDT表(知道了IDT表的结构,⾃⼰写⼀个!idt WinDbg扩展也是很简单的事情),但是,使⽤windbg调试IDT表式不可能的。WinDbg的⼯作就要依赖于debuggee系统的中断向量,如果在ISR 3⾥写个int 3,那么BSOD是绝对的。Windbg和Debuggee系统是通过com⼝连接的,当Debuggee系统中产⽣了int3中断,系统⾸先进⼊到ISR 3中。在ISR 3中判断存在内核调试器,然后通过com⼝和WinDbg通⾏。这个处理过程本⾝就依赖于Debuggee系统的ISR。如果在ISR 3中⼜存在⼀个int 3那么就⽆限递归了。
(待续)

本文发布于:2023-05-12 13:18:54,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/599874.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:中断   错误   继续   处理   程序   内存   地址
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图