声明:
内容都是书中或baidu的,很多在论坛都有出现,只是觉得有阅读和收藏整理以方便自己使用的必要。另外就是方便自己以后回头看看自己曾经走过的坎坷之路,仅此而已。
实模式
IVT: 中断向量表
从0地址开始,共256个,结构就是个地址表,每个占4字节,保存的是中断向量处理函数,存储方式仍为高高低低
2-3 Seg
0-1 offset jmp Seg:offset
Seg:offset 中断处理函数
处理步骤:
1) 把EFLAGES压栈
2) CS栈
3) IP压栈(指向中断处理结束后要执行的下一条OpCode)
4) 清楚IF和TF标志位.
5) 根据中断向量(索引)找到对应的IVT数据项
6) 报IVT中的段地址和偏移地址分别加载到CS和IP寄存器
IRET返回过程
1) 栈顶16位数值pop到IP 前面压栈对应的弹出
2) 栈顶16位数值pop到CS
3) 栈顶16位数值pop到EFLAGS
读中断信息
Int 21
AH = Dos中断功能号 0x35
AL = 中断向量
返回值放在ES:段,BX:偏移
写中断向量表
Int 21
AH = Dos中断功能号 0x25
Al = 中断向量
Push DS
DS = 要改写的段地址
DX = 要改写的Offset
Pop DS
保护模式
Idtr 中断描述表基值为的基地址
Idtrl 界限(长度)
kd> r idtr
idtr=8003f400
中断描述符表,每个表大小是8byte,因为兼容的关系处理函数地址被分割在低2byte和高2byte,共32位,16位应该就是用低16位就好了吧,哈哈。
kd> dw 8003f400
8003f400 e36c 0008 8e00 8053 e4e4 0008 8e00 8053
8003f410 112e 0058 8500 0000 e8b4 0008 ee00 8053
第三个中断描述符为 8053 ee00 0008 e8b4
中断处理函数地址为:8053e8b4 选择子为8 属性为ee00
kd> u 8053e8b4
nt!KiTrap03:
8053e8b4 6a00 push 0
8053e8b6 66c74424020000 mov word ptr [esp+2],0
8053e8bd 55 push ebp
可以通过修改中断描述表内容或修改描述符表对应函数地址中的某些东东来实现hook
http://bbs.pediy.com/showthread.php?p=417908#post417908
这篇对IDT的描述太详细了,以至于没看明白,hook的的思路也是修改描述表的offset来实现修改中断处理函数。
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;
// load idt_info
__asm [B][COLOR="Red"]sidt [/COLOR][/B]idt_info //不知道s是那个单词缩写,set还是... 而r-read 如:rdmsr
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase); //取高2和低2byte
关键代码
修改IDT处理函数
// remember we disable interrupts while we patch the table
__asm cli
idt_entries[NT_INT_TIMER].LowOffset = (unsigned short)my_interrupt_hook;
idt_entries[NT_INT_TIMER].HiOffset = (unsigned short)((unsigned long)my_interrupt_hook >> 16);
__asm sti
恢复IDT
__asm cli
idt_entries[NT_INT_TIMER].LowOffset = (unsigned short) old_ISR_pointer;
idt_entries[NT_INT_TIMER].HiOffset = (unsigned short)((unsigned long)old_ISR_pointer >> 16);
__asm sti
处理时感觉需要增加修改Cr0内存属性操作。
全局和局部描述符表格式和IDT的格式类似
GDT : 长度(界限)
BaseAddr GDT描述符表的地址
kd> r gdtr
gdtr=8003f000
kd> dw 8003f000
8003f000 0000 0000 0000 0000 ffff 0000 9a00 00cf
8003f010 ffff 0000 9200 00cf ffff 0000 fa00 00cf
8003f020 ffff 0000 f200 00cf 20ab 2000 8b04 8000
kd> r ldtr
ldtr=00000000
[招生]科锐逆向工程师培训46期预科班将于 2023年02月09日 正式开班