HOOK PageFault
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/desc.h>
typedef struct desc_struct gate_desc;
struct desc_easy {
unsigned short a;
unsigned short b;
unsigned short c;
unsigned short d;
} __attribute__((packed)) ;
struct desc_ptr {
unsigned short size;
unsigned long address;
} __attribute__((packed)) ;
#define PGFAULT_INT 0x0E
static unsigned long isr_orig;
static unsigned long isr_new;
static gate_desc *PF_gate;
asmlinkage void my_function(void);
void stub(void)
{
__asm__
(
" pushal \n"
" pushl %es \n"
" pushl %ds \n"
" call my_function \n"
" popl %ds \n"
" popl %es \n"
" popal \n"
" jmp *isr_orig \n"
);
}
asmlinkage void my_function(void)
{
unsigned long add;
asm("movl %%cr2,%0":"=r"(add));
printk("PID: %d >> %08x\n",current->tgid,(unsigned int )add);
}
int pgfault_init( void )
{
struct desc_ptr idtr;
gate_desc *idt_table;
printk("+z+ pgfault_init\n");
//获取IDT指针
asm ("sidt %0" : "=m" (idtr));
//page_fault_gate地址
idt_table = ((gate_desc *) idtr.address);
PF_gate = &idt_table[PGFAULT_INT];
//保存原始的page_fault()地址
isr_orig = (PF_gate->a & 0xffff) | (PF_gate->b & 0xffff0000);
//把新的处理函数地址填充进去
isr_new = (unsigned long)stub;
((struct desc_easy *) PF_gate)->a = (unsigned short) (isr_new & 0x0000FFFF);
((struct desc_easy *) PF_gate)->d = (unsigned short) (isr_new >> 16);
return 0;
}
void pgfault_exit( void )
{
printk("+z+ pgfault_exit\n");
//还原以前的page_fault地址
((struct desc_easy *) PF_gate)->a = (unsigned short) (isr_orig & 0x0000FFFF);
((struct desc_easy *) PF_gate)->d = (unsigned short) (isr_orig >> 16);
}
MODULE_LICENSE("GPL");
module_init( pgfault_init);
module_exit( pgfault_exit);