Поиграем с туксом в прятки Крис Касперски ака мыщъх Хакер, номер #077, стр. 077-102-6 Чтение/запись в/из /dev/kmem // чтение данных из /dev/kmem static inline int rkm(int fd, int offset, void *buf, int size) { if (lseek(fd, offset, 0) != offset) return 0; if (read(fd, buf, size) != size) return 0; return size; } // запись данных в /dev/kmem static inline int wkm(int fd, int offset, void *buf, int size) { if (lseek(fd, offset, 0) != offset) return 0; if (write(fd, buf, size) != size) return 0; return size; } Остается только найти во всем этом мусоре таблицу системных вызовов. Да как же мы ее найдем, если никакой символьной информации у нас нет?! Без паники! Нам помогут центральный процессор и машинный код обработчика прерывания INT 80h, которое этими системными вызовами, собственно говоря, и заведует. Его дизассемблерный листинг в общем случае выглядит так: Фрагмент дизассемблерного листинга обработчика прерывания INT 80h 0xc0106bc8 <system_call>: push %eax [snip] 0xc0106bf2 <system_call+42>: jne 0xc0106c48 <tracesys> 0xc0106bf4 <system_call+44>: call *0xc01e0f18(,%eax,4) 0xc0106bfb <system_call+51>: mov %eax,0x18(%esp,1) 0xc0106bff <system_call+55>: nop Смотри, по адресу 0C0106BF4h расположена команда CALL, непосредственным аргументом которой является... указатель на таблицу системных вызовов! Адрес команды CALL может меняться от одного ядра к другому, или это даже может быть совсем не CALL – в некоторых ядрах указатель на таблицу системных вызовов передается через промежуточный регистр командой MOV. Короче, нам нужна команда, одним из аргументов который является непосредственный операнд X > 0C000000h. Естественно, чтобы его найти, потребуется написать простенький дизассемблер (звучит страшнее, чем выглядит) или скачать готовый движок из Сети. А как найти адрес обработчика INT 80h в файле /dev/kmem? Просто спроси об этом процессор — он скажет. Команда SIDT возвращает содержимое таблицы дескрипторов прерываний (Interrupt Descriptor Table), восьмидесятый'h элемент с краю и есть наш обработчик! |