@ -1,22 +1,61 @@
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <asm/desc.h>
typedef struct {
uint16_t size ;
uint64_t adress ;
} Fuck_IDT_register ;
// Смотрим у производителя процессора номер прерывания
// деления на ноль (я сижу на x86-64, а этот номер зависит от архитектуры процессора)
# define ZERODIV_NR 0x00
extern void store_idt ( Fuck_IDT_registe r * storage ) ;
extern void store_idt ( struct desc_pt r * storage ) ;
static void example_handler ( void )
{
pr_warn ( " entered the handler " ) ;
return ;
}
static int __init fuck_system ( void )
{
pr_info ( " start to fuck system " ) ;
struct desc_ptr newidtr ;
gate_desc * oldint , * newint ;
Fuck_IDT_registe r idt_ register ;
store_idt ( & idt_register ) ;
pr_info ( " idt register stored " ) ;
struct desc_ptr newidtreg ;
struct desc_pt r old idtreg;
gate_desc * oldidt , * newidt ;
pr_info ( " nessesary variables created " ) ;
// Выделяем память под 256 прерываний
unsigned long new_page = __get_free_page ( GFP_KERNEL ) ;
if ( ! new_page )
{
return - ENOMEM ;
}
pr_info ( " new page allocated " ) ;
store_idt ( & oldidtreg ) ;
pr_info ( " IDT register stored " ) ;
newidtreg . address = new_page ;
newidtreg . size = oldidtreg . size ;
newidt = ( gate_desc * ) newidtreg . address ;
memcpy ( newidt , oldidt , newidtreg . size ) ;
pr_info ( " IDT register saved in backup " ) ;
pack_gate (
( newidt + ZERODIV_NR ) ,
GATE_INTERRUPT ,
( unsigned long ) example_handler ,
0 ,
0 ,
__KERNEL_CS
) ;
pr_info ( " packed new gate " ) ;
load_idt ( & newidtreg ) ;
pr_info ( " loaded new interrupts " ) ;
int x = 1 / 0 ; // триггерим прерывание деления на ноль
pr_info ( " return from interrupt " ) ;
load_idt ( & oldidtreg ) ;
free_page ( new_page ) ;
pr_info ( " Unloaded everything " ) ;
return 0 ;
}