之前做了向内核添加系统调用的实验,突发奇想,想能不能添加异常处理程序,发现其实也比较简单,和添加系统调用差不多,下面是我做的实验的基本步骤, 与大家分享:
=============================================================
异常向量号范围:0-31,其中0-19已经被使用,20-31被保留
任务:为异常向量号22添加异常处理程序,初步设置为与int3有相同的功能
1、编辑/usr/src/linux-source-3.2.0/arch/x86/kernel/traps.c
void __init early_trap_init(void)
{
set_intr_gate_ist(1, &debug, DEBUG_STACK);
/* int3 can be called from all */
set_system_intr_gate_ist(3, &int3, DEBUG_STACK);
set_system_intr_gate_ist(22, &int22, DEBUG_STACK); //新增系统中断门, 不能设置为陷阱门和任务门了
set_intr_gate(14, &page_fault);
load_idt(&idt_descr);
}
2、编辑/usr/src/linux-source-3.2.0/arch/x86/include/asm/traps.h
..........
asmlinkage void int3(void);
asmlinkage void int22(void); //新增声明
3、编辑/usr/src/linux-source-3.2.0/arch/x86/kernel/entry_32.s
ENTRY(int3)
......
END(int3)
//仿照int3,新增int22 异常处理程序
ENTRY(int22)
RING0_INT_FRAME
pushl_cfi $-1 # mark this as an int
SAVE_ALL
TRACE_IRQS_OFF
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer,即SAVE_ALL保存的寄存器组指针
call do_int22
jmp ret_from_exception
CFI_ENDPROC
END(int22)
4、编辑/usr/src/linux-source-3.2.0/arch/x86/kernel/traps.c
//仿照do_int3,新增do_int22 异常服务程序
//这里完全借鉴了int3的处理逻辑
dotraplinkage void __kprobes do_int22(struct pt_regs *regs, long error_code)
{
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
if (kgdb_ll_trap(DIE_INT3, "int22", regs, error_code, 3, SIGTRAP)
== NOTIFY_STOP)
return;
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
#ifdef CONFIG_KPROBES
if (notify_die(DIE_INT3, "int22", regs, error_code, 3, SIGTRAP)
== NOTIFY_STOP)
return;
#else
if (notify_die(DIE_TRAP, "int22", regs, error_code, 3, SIGTRAP)
== NOTIFY_STOP)
return;
#endif
preempt_conditional_sti(regs);
do_trap(22, SIGTRAP, "int22", regs, error_code, NULL); //先借用,以后再修改
preempt_conditional_cli(regs);
}
5、编写应用程序测试
================测试程序 1=================
int
main(){
asm("int $22"); //插入一条 int $22 汇编指令
}
编译运行结果:Trace/breakpoint trap
================测试程序 2=================
#include
#include
void sigtrap_handler(int signo){
printf("catch SITTRAP, signo = %d\n",signo);
}
int
main(){
signal(SIGTRAP,sigtrap_handler);
asm("int $22");
}
编译运行结果:catch SITTRAP, signo = 5
阅读(1884) | 评论(0) | 转发(3) |