中断门
中断门知识点
前期准备
int 32的计算: 80b98100 - 80b98000 = 100(16进制) / 8 = 20 => 32(10进制)
填充中断门描述符, 函数地址是: 00401080;
0040ee00`000810801
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42kd> r idtr
idtr=80b98000
kd> dq 80b98000 L30
ReadVirtual: 80b98000 not properly sign extended
80b98000 83e58e00`00085210 83e58e00`0008557c
80b98010 00008500`00580000 83e5ee00`00085fc0
80b98020 83e5ee00`00086338 83e58e00`00086688
80b98030 83e58e00`000869ec 83e58e00`000876f8
80b98040 00008500`00500000 83e58e00`00087d3c
80b98050 83e58e00`00088050 83e58e00`00088380
80b98060 83e58e00`000887f0 83e58e00`00088cfc
80b98070 83e58e00`000899b8 83e58e00`00089e40
80b98080 83e58e00`0008a154 83e58e00`0008a488
80b98090 00008500`00a00000 83e58e00`0008a7e4
80b980a0 83e58e00`00089e40 83e58e00`00089e40
80b980b0 83e58e00`00089e40 83e58e00`00089e40
80b980c0 83e58e00`00089e40 83e58e00`00089e40
80b980d0 83e58e00`00089e40 83e58e00`00089e40
80b980e0 83e58e00`00089e40 83e58e00`00089e40
80b980f0 83e58e00`00089e40 83e58e00`0008abb0
80b98100 00000000`00080000 00000000`00080000
kd> eq 80b98100 0040ee00`00081080
kd> dq 80b98000 L30
ReadVirtual: 80b98000 not properly sign extended
80b98000 83e58e00`00085210 83e58e00`0008557c
80b98010 00008500`00580000 83e5ee00`00085fc0
80b98020 83e5ee00`00086338 83e58e00`00086688
80b98030 83e58e00`000869ec 83e58e00`000876f8
80b98040 00008500`00500000 83e58e00`00087d3c
80b98050 83e58e00`00088050 83e58e00`00088380
80b98060 83e58e00`000887f0 83e58e00`00088cfc
80b98070 83e58e00`000899b8 83e58e00`00089e40
80b98080 83e58e00`0008a154 83e58e00`0008a488
80b98090 00008500`00a00000 83e58e00`0008a7e4
80b980a0 83e58e00`00089e40 83e58e00`00089e40
80b980b0 83e58e00`00089e40 83e58e00`00089e40
80b980c0 83e58e00`00089e40 83e58e00`00089e40
80b980d0 83e58e00`00089e40 83e58e00`00089e40
80b980e0 83e58e00`00089e40 83e58e00`00089e40
80b980f0 83e58e00`00089e40 83e58e00`0008abb0
80b98100 0040ee00`00081080 00000000`00080000中断门0环堆栈压了五个值, eip, cs, eflags, esp, ss, 3环堆栈无内容;
3环寄存器:
EAX = 00000000 EBX = 7FFD5000 ECX = BFBDF6C4 EDX = 005F0178 ESI = 0012FE3C EDI = 0012FF08 EIP = 004011A7 ESP =0012FE3C
EBP = 0012FF08 EFL = 00000246
CS = 001B DS = 0023 ES = 0023 SS = 0023 FS = 003B GS = 0000
0环寄存器:
eax=00000000 ebx=7ffd5000 ecx=bfbdf6c4 edx=005f0178 esi=0012fe3c edi=0012ff08
eip=00401080 esp=94e63c9c
ebp=0012ff08 iopl=0 nv up di pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000046
1 | kd> dds 94e63c9c |
代码实验
1 | // 10_11_InterruptGate(中断门).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 |
IDT和GDT的关联
1 | kd> dq 80b98800 |
- 在IDT中, int3中的3代表的是索引;
- 83e5ee00
00085fc0
(int 3)中段选择子0008表示去查找GDT中00cf9b00`0000ffff;
IDT描述符
5.11 页码123
- D位(第11位)是指默认操作数, 32位下为1, 16位下为0;
3环获取GDT和IDT的指令
获取GDT/获取IDT: sgdt/sidt(3环下调用);
获取到gdt的值为
ff 03 00 88 b9 80
; 其中前两个字节为表的长度, 后四个字节为表的地址;修改GDT/修改IDT: lgdt/lidt(0环下才能调用);
补充
iretd中的
d
描述宽度用的; 16位(iret)、32位(iretd)、64位(iretq);
作业
- 返回一定要用iretd吗? 使用retf;
- iretd 解除阻塞;
- retf 没有解除阻塞;
- sti 解除阻塞, 并且给eflags.IF = 1;
1 | // InterruptGate_retf.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 |
- 构建陷阱门自己调用;
- TYPE位为f, 0040ee00`00081080;
中断门和陷阱门的区别
1.
进入中断门会清除eflag VM NT IF TF 位
进入陷阱门会清除eflag VM NT TF 位
2.
由于中断门会清除IF位,导致一些中断触发会悬挂,陷阱门则不会
int3_hook
步骤
- 第一步:添加一个代码段在0x48位置
- 第二步:计算代码段0x48的base
目标地址 - int 3偏移= base
写回0x48位置 - 第三步:修改int 3中断门的段选择子为0x48
- Hook函数编写
由于有缓存的存在, 可以执行一会, 那么我们在这要做二次跳转
jmp 0x48: xxx地址 - 当调到xxx地址后, 通过调用打印函数, 确定调用成功
- jmp回int 3原本的偏移
base:401080 - 83e44fc0(int 3) = 7C5B C0C0
段描述:00cf9b00`0000ffff
修改gdtr 0x48位置
eq 80b98848 7Ccf9b5B`C0C0ffff
修改int 3段选择子为48
eq 80b98018 83e7ee00`0048dfc0
83e11c60
代码实验
1 | // 09_24_int3_hook.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 |