1 Analiza wywołania i przebiegu przerwań w systemie LinuxŁukasz Mozgowoj - Mateusz Leśniak -
2 Czym jest przerwanie ? W systemie Linux, jest to sygnał wysłany procesorowi: Przez sterownik przerwań jakiegoś urządzenia - hardware interrupt Przez sam procesor z powodu błędów w wykonywanym kodzie (błędne instrukcje, odwoływanie się do pamięci w sposób niedopuszczalny, wywołania systemowe itp.) - exception
3 PIC - Programmable Interrupt ControllerObsługa przerwań PIC - Programmable Interrupt Controller
4 Schemat obsługi przerwań
5 Obsługa przerwań dla klawiaturyTop Half Bottom Half irqreturn_t irq_keyboard_handler(int irq, void * data) { scancode = inb(0x0060); //Schedule tasklet_schedule(&task); long curTime = current_kernel_time().tv_nsec; inTime[interrupt_count % 64] = curTime; ++interrupt_count; return IRQ_NONE; } static void read_char(unsigned long data) { if (!(scancode & 0x80)) { handlingTime = current_kernel_time().tv_nsec-((long *)data) [tasklet_invoke_count % 64]; printk(KERN_INFO "MODULE 1: %ld\n", handlingTime); if ((scancode & 0x7F) == 0x48) buffer_add_string("${UP}"); else if ((scancode & 0x7F) == 0x4b) buffer_add_string("${LEFT}"); else if ((scancode & 0x7F) == 0x4d) buffer_add_string("${RIGHT}"); else if ((scancode & 0x7F) == 0x50) buffer_add_string("${DOWN}"); else if (upper == false) { if ((scancode & 0x7F) == 0x01) buffer_add_string("${ESC}"); else buffer_add_char(keymap[scancode & 0x7F]); } else buffer_add_char(keymap_upper[scancode & 0x7F]); } ++tasklet_invoke_count; DECLARE_TASKLET(task, read_char, (unsigned long) &inTime);
6 create_proc_read_entry("keylogger1", 0, NULL, read_buffer, NULL);void buffer_add_char(char c) { buffer[end] = c; end = (end + 1) % BUFFER_SIZE; if(!buffer_is_empty() && end == start){ start = (start + 1) % BUFFER_SIZE; } else { empty = NO; } char buffer_get(void){ if(!buffer_is_empty()){ char ret = buffer[start]; if(start == end){ empty = YES; return ret; return 0; int read_buffer(char *page, char **start, off_t offset, int count, int *eof, void *data) char tmp_buffer[BUFFER_SIZE+1]; int i = -1; while(!buffer_is_empty()){ tmp_buffer[++i] = buffer_get(); tmp_buffer[++i] = 0; return sprintf(page, "%s\n", tmp_buffer); Ring buffer /proc/keylogger create_proc_read_entry("keylogger1", 0, NULL, read_buffer, NULL);
7 Eksperymenty 1. Załadowanie modułu dla obsługi przerwań klawiatury:- Przyciskanie klawisza w losowych odstępach czasu - Przytrzymanie klawisza wciśniętego przez pewien czas 2 .Załadowanie modułu dla obsługi karty sieciowej - Bez próby wywłaszczania przez klawiaturę - Z próbą wywłaszczania przez klawiaturę 3. Załadowanie dwóch modułów dla obsługi klawiatury w trybie IRQF_SHARED
8 Odczytywanie wyników ping_regex = re.compile("^\[\s*\d+\.\d+\] ping : \d+$") module1_regex = re.compile("^\[\s*\d+\.\d+\] MODULE 1: \d+$") module2_regex = re.compile("^\[\s*\d+\.\d+\] MODULE 2: \d+$") if __name__ == '__main__': dmesg_data = exec_process(['dmesg'], True) regex = None if(len(sys.argv) != 2): print "usage: ./dmesg_reader
9 Losowe wciskanie klawisza
10 Przytrzymany jeden klawisz
11 Klawiatura + włączony ping
12 Ping
13 Wywłaszczany ping
14 Dwa handlery klawiatury
15 Pytania ?