61 lines
1.5 KiB
C
61 lines
1.5 KiB
C
#include <linux/kernel.h>
|
||
#include <linux/module.h>
|
||
#include <linux/init.h>
|
||
#include <asm/desc.h>
|
||
|
||
// Смотрим у производителя процессора номер прерывания
|
||
// деления на ноль (я сижу на x86-64, а этот номер зависит от архитектуры процессора)
|
||
#define ZERODIV_NR 0x00
|
||
|
||
extern void store_idt(struct desc_ptr *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 newidtreg;
|
||
struct desc_ptr oldidtreg;
|
||
gate_desc *oldidt, *newidt;
|
||
// Выделяем память под 256 прерываний
|
||
unsigned long new_page = __get_free_page(GFP_KERNEL);
|
||
if (!new_page)
|
||
{
|
||
return -ENOMEM;
|
||
}
|
||
store_idt(&oldidtreg);
|
||
newidtreg.address = new_page;
|
||
newidtreg.size = oldidtreg.size;
|
||
newidt = (gate_desc *)newidtreg.address;
|
||
memcpy(newidt, oldidt, newidtreg.size);
|
||
|
||
pack_gate(
|
||
(newidt + ZERODIV_NR),
|
||
GATE_INTERRUPT,
|
||
(unsigned long) example_handler,
|
||
0,
|
||
0,
|
||
__KERNEL_CS
|
||
);
|
||
|
||
load_idt(&newidtreg);
|
||
int x = 1 / 0; // триггерим прерывание деления на ноль
|
||
load_idt(&oldidtreg);
|
||
free_page(new_page);
|
||
return 0;
|
||
}
|
||
|
||
static void __exit unfuck_system(void)
|
||
{
|
||
pr_info("start to unfuck system");
|
||
}
|
||
|
||
module_init(fuck_system);
|
||
module_exit(unfuck_system);
|
||
MODULE_LICENSE("GPL");
|