Compare commits
7 Commits
labs/cours
...
labs/06
| Author | SHA1 | Date | |
|---|---|---|---|
| b559db2cc1 | |||
| 8fe6e0ba63 | |||
| f57aa67887 | |||
| eb85d6dd9a | |||
| 68c5f8388b | |||
| 0fff8ca9d1 | |||
| a2ac5eedcc |
@ -2,3 +2,12 @@
|
|||||||
|
|
||||||
## Подпрограммы, программные прерывания и особые случаи
|
## Подпрограммы, программные прерывания и особые случаи
|
||||||
|
|
||||||
|
### АХТУНГ
|
||||||
|
|
||||||
|
**НАСТОЯТЕЛЬНО РЕКОМЕНДУЮ НЕ ЗАГРУЖАТЬ КОД ИЗ ЭТОЙ ЛАБЫ**. Дело в том, что Linux считает прерывания его личной заботой и поэтому как правило сам отвечает за их обработку. Для того, чтобы сделать прикол из лабы с подменой таблицы векоторов прерываний необходимо написать модуль ядра.
|
||||||
|
|
||||||
|
Для тех, кто в танке, это означает следующее: **ЕСЛИ Я ОШИБСЯ ХОТЬ ГДЕ-ТО (А Я ВЕРОЯТНЕЕ ВСЕГО ГДЕ-ТО ОШИБСЯ), ВАШЕЙ СИСТЕМЕ МОЖЕТ ПРИЙТИ ПИЗДА. И ОЧЕНЬ БЫСТРО**
|
||||||
|
|
||||||
|
## Теперь для смелых
|
||||||
|
|
||||||
|
Милицын препод лояльный, поэтому было принято решение не грохать в лоб системную таблицу, а расширить ее своими прерываниями. Делается это в основном при помощи `request_irq`, в который передается куча инфы о прерывании
|
||||||
|
|||||||
69
06-subroutines-interruptions/fuck-system.c
Normal file
69
06-subroutines-interruptions/fuck-system.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit unfuck_system(void)
|
||||||
|
{
|
||||||
|
pr_info("start to unfuck system");
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(fuck_system);
|
||||||
|
module_exit(unfuck_system);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
8
06-subroutines-interruptions/low-level-asm.asm
Normal file
8
06-subroutines-interruptions/low-level-asm.asm
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
global store_idt
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
store_idt: ; rdi - указатель
|
||||||
|
sidt [rdi]
|
||||||
|
ret
|
||||||
|
int3
|
||||||
Reference in New Issue
Block a user