kernel.hacks

секреты кернел хакинга

крис касперски ака мыщъх, no-email

кому не хотелось хакнуть ядро LINUX'а? каждый уважающий себя Линуксоид должен попробовать это сделать! ведь LINUX, в отличии от Windows, настоящий полигон для хакерства, таящий в себе неожиданные возможности. взять хотя бы лого, появляющееся на экране. пришла пора взять в руки GIMP и что-нибудь нарисовать

«Хаками» (hacks) называются всякие хитрости, забавные шутки и оригинальные приемы, в то время как под «хакерством» (hacking) традиционно понимается взлом программ или сетевые атаки. Вроде бы похожие термины, а какая разница!

Эта статья открывает целый цикл публикаций, рассказывающих о том, что крутого можно сделать с ядром. И начнем мы с изменения логотипа.

Обычно, при загрузке LINUX'а появляется характерный пингвин, которым уже никого не удивишь, и который ужасно раздражает. Хочется чего-нибудь новенько. Как изменить стандартное лого на что-то свое? Есть несколько путей.

kernel.hacks_image_0.jpg

Рисунок 1 стандартное лого

Начнем с компиляции ядра. За отображение лого ответственны следующие файлы: /usr/src/linux/drivers/video/* и /usr/src/linux/include/linux/linux_logo.h. Всякий раз, когда ядро загружается в отладочном (debug) или молчаливом (quiet) режиме, эти файлы — в откомпилированном виде, конечно — получают управление и выводят изображение на экран.

Само лого обитает в файле linux_logo.h, где оно хранится в виде обыкновенного массива данных, кусочек которого для наглядности приведен ниже:

unsigned char linux_logo_bw[] __initdata = {

0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F,

0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,

0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,

0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF,

Листинг 1 фрагментфайла linux_logo.h, содержащий logo

Изменять его можно как вручную, так и автоматически. Ручной режим мы трогать не будем, поскольку ничего интересного в нем нет (так, сплошная рутина), гораздо проще запустить специальную утилиту и она все сделает сама. В отличии от мира Windows, погруженного в корпоративный мрак, в котором бродят зубастые монстры, под LINUX народ не зажимает исходники и мы легко можем проанализировать, что делает та или иная программа и нужно ли это нам. Вмешательство в ядро всегда чревато фатальными последствиями. Один неверный шаг — и система отказывается закружатся или уничтожает все данные жесткого диска под чистую. Поэтому, перед всякой установкой потенциально небезопасной программы необходимо пролистать ее исходный текст и посмотреть какие именно файлы она изменяет. Остается зарезервировать их на дискету, CD-R/RW диск или карту FLASH-памяти (в просторечии «свисток»). А загрузиться можно и с Live CD!

Мы будем использовать утилиту logo, которую можно скачать с демократичного бельгийского сервера: http://members.chello.be/cr26864/Linux/fbdev/logo.tar.bz2. Распаковав архив, мы обнаружим три Си-файла и один makefile. Двоичных файлов, увы, нет и их приходится компилировать самостоятельно. Поддерживаются две версию ядер — с номерами 2.2 и 2.4. В версии 2.6 все сильно по другому и к ней нужен свой подход, о котором мы чуть позже и поговорим, а пока вернемся к нашей текущей задаче.

Анализ показывает, что утилита logo фактически состоит из двух частей: конвертора входного изображения, сосредоточенного в файле pnmtologo.c, и непосредственного самого патчера ядра, сосредоточенного в файлах logo_2_2.c и logo_2_4.c (каждый для своей версии ядра). Строго говоря, logo_2_4.c включает в себя экстрактор текущего лого и патчер, а logo_2_2.c только экстрактор лого старого формата, но это уже детали. Само же logo в обоих случаях представляет собой обыкновенный PCX-файл с глубиной цветности не более 256 цветов и общей площадью не более чем 786432 пикселей (что соответствует разрешению 1024×768).

Конвертор нам совершенно неинтересен (кстати говоря, вместо него можно воспользоваться плагином для редактора GIMP: http://registry.gimp.org/detailview.phtml?plugin=Linux+Logo), а вот к экстрактору/патчеру мы присмотримся повнимательнее.

Ниже приведен ключевой фрагмент файла logo_2_4.c:

/*

* Extract all Linux logos from the Linux kernel sources (2.4.x version)

* (C) Copyright 2000-2001 by Geert Uytterhoeven geert@linux-m68k.org

* ————————————————————————–

* This file is subject to the terms and conditions of the GNU General Public

* License. See the file COPYING in the main directory of the Linux

* distribution for more details.

* ————————————————————————–

*/

static void write_logo(const char *filename, const unsigned char *data,

const unsigned char *red, const unsigned char *green,

const unsigned char *blue)

{

FILE *stream; int i, j, d;

stream = fopen(filename, «w»);

if (!stream) { perror(«file open error: »);exit(1);}

fputs(«P3\n80 80\n255\n», stream);

for (i = 0; i < 80*80; i += 4

{

for (j = 0; j < 4; j++)

{

d = data[i+j]-32;

fprintf(stream, « %3d %3d %3d», red[d], green[d], blue[d]);

} fputc('\n', stream);

} fclose(stream);

}

static void write_logo_bw(const char *filename, const unsigned char *data)

{

FILE *stream; int i, j, d;

stream = fopen(filename, «w»);

if (!stream) {perror(«file open error: »);exit(1);

fputs(«P1\n80 80\n», stream);

for (i = 0; i < 80*80/8; i += 4)

{

for (j = 0; j < 4; j++)

{

d = data[i+j];

fprintf(stream, « %1d %1d %1d %1d %1d %1d %1d %1d»,

(d » 7) & 1, (d » 6) & 1, (d » 5) & 1, (d » 4) & 1,

(d » 3) & 1, (d » 2) & 1, (d » 1) & 1, d & 1);

} fputc('\n', stream);

} fclose(stream);

}

static struct entry{unsigned char red; unsigned char green; unsigned char blue;} palette16[16] = {

{ 0, 0, 0, },{ 0, 0, 170, },{ 0, 170, 0, },{ 0, 170, 170, },

{ 170, 0, 0, },{ 170, 0, 170, },{ 170, 85, 0, },{ 170, 170, 170,},

{ 85, 85, 85, },{ 85, 85, 255, },{ 85, 255, 85, },{ 85, 255, 255, },

{ 255, 85, 85, },{ 255, 85, 255, },{ 255, 255, 85, },{ 255, 255, 255 },

};

static void write_logo16(const char *filename, const unsigned char *data)

{

FILE *stream; int i, j, d;

stream = fopen(filename, «w»);

if (!stream) { perror(«file open error: »); exit(1); }

fputs(«P3\n80 80\n255\n», stream);

for (i = 0; i < 80*80/2; i += 2)

{

for (j = 0; j < 2; j++)

{

d = data[i+j] » 4;

fprintf(stream, « %3d %3d %3d», palette16[d].red,

palette16[d].green, palette16[d].blue);

d = data[i+j] & 15;

fprintf(stream, « %3d %3d %3d», palette16[d].red,

palette16[d].green, palette16[d].blue);

} fputc('\n', stream);

} fclose(stream);

}

int main(int argc, char *argv[])

{

/* generic */

write_logo(«logo_2_4.ppm»,linux_logo,linux_logo_red,linux_logo_green,linux_logo_blue);

write_logo_bw(«logo_bw_2_4.pbm», linux_logo_bw);

write_logo16(«logo16_2_4.ppm», linux_logo16);

/* mac */

write_logo(«mac_2_4.ppm», mac_logo, mac_logo_red, mac_logo_green,mac_logo_blue);

/* mips */

write_logo(«mips_2_4.ppm», mips_logo, mips_logo_red, mips_logo_green,mips_logo_blue);

/* mips64 */

write_logo(«mips.ppm»,mips64_logo,mips64_logo_red,mips64_logo_green,mips64_logo_blue);

/* sparc */

write_logo(«sparc_2_4.ppm»,sparc_logo,sparc_logo_red,sparc_logo_green,sparc_logo_blue;

/* sparc64 */

write_logo(«sparc.ppm»,sparc_logo,sparc_logo_red,sparc_logo_green,sparc_logo_blue);

return 0;

}

Листинг 2 ключевой фрагмент файла logo_2_4.c, меняющего лого

Алгоритм работы понять нетрудно. Как мы видим, в процессе изменения лого модифицируются файлы logo_2_4.ppm, logo_bw_2_4.pbm и logo16_2_4.ppm, которые мы и должны сохранить на «спасательную» дискету перед запуском утилиты. Подробнее об этом хаке можно почитать с статье «HOWTO Linux Logo Hack» (http://gentoo-wiki.com/HOWTO_Linux_Logo_Hack).

А вот другой способ изменения лого, подходящий для старых ядер 2.2.x, которые все еще встречаются в природе. Сначала забэкапим оригинальный файл /usr/include/linux/linux_logo.h (впрочем, если бэкапа не будет, его всегда можно скачать из сети), затем подготавливаем свое собственное лого в формате .xpm с разрешением 80х80 пикселей и палитрой _ровно_ из 214 цветов (в этом нам опять-таки поможет GIMP), натравливаем на нее утилиту boot_logo-1.01 (http://lug.umbc.edu/~mabzug1/boot_logo-1.01), представляющую собой обыкновенный перловый скрипт, запущенный следующим образом «./boot_logo‑1.01 your_image.xpm > linux_logo.h» и, если все пройдет без ошибок, в текущей директории образуется файл linux_logo.h, который нам предстоит скопировать в каталог: /usr/include/linux. Теперь необходимо перекомпилировать ядро и перезагрузится. Если мы не повиснем, на экране высветиться новое лого, которое может выглядеть, например, так, как показано на рис 2. При возникновении трудностей обращайтесь к http://lug.umbc.edu/~mabzug1/boot_logo.html.

Рисунок 2 видоизмененное лого

С ядром 2.6 все намного проще. Создаем изображение в формате png любого разумного размера и пропускаем его через штатную утилиту pngtopnm, запущенную со следующими ключами командной строки: «./pngtopnm logo.png | pnmtoplainpnm > logo_linux_clut224.ppm», а затем полученный файл перебрасываем на место постоянной дислокации утилитой cp: «./cp logo_linux_clut224.ppm /usr/src/linux/drivers/video/logo/».

Остается настроить ядро, для чего можно воспользоваться интерактивным конфигуратором. Среди прочих полезных (и не очень) пунктов в нем будет «Bootuplogo» и «Standard 224-colorLinuxlogo». Вот их-то и необходимо взвести.

Device Drivers →

Graphics Support →

[*] Support for frame buffer devices

[*] VESA VGA graphics support

Console display driver support →

[*] Video mode selection support

<*> Framebuffer Console support

[*]Select compiled-in fonts

[*]VGA 8×16 font

Logo configuration→

[*]Bootup logo

[*] Standard 224-color Linux logo

Рисунок 3 интерактивное конфигурирование лого в kernel 2.6

После всего перекомпилируем ядро, запустив make, и настоим конфигурационный файл /boot/grub/menu.lst, добавив ключ 'vga=0x318' и kernel (hd0,0)/vmlinuzroot=/dev/sda3 vga=0x318. Перезагрузимся. Новое лого торжественно появится на экране, сияющее всеми своими 224-цветами. Красиво? Скорееаляповато. Настоящие хакеры признают только текстовой терминал и консольный режим с ANSI-псвевдрографикой, а GUI облагают матом и прогоняют прочь.

Большой популярностью пользуются ASCII-лого, которые можно установить с помощью Linux_logo программы (http://www.deater.net/weave/vmwprod/linux_logo/). Там же на сервере находится коллекция готовых образцов, два из которых приведены ниже.

kernel.hacks_image_2.jpg

Рисунок 4 нестандартное ASCII-лого

Рисунок 5 еще один пример ASCII-лого

Вот мы и хакнули LINUX, причем не одним, а сразу несколькими вариантами. Простор для творчества здесь поистине безграничен и поиск по ключевым словам «linuxlogo» в Интернете выдает огромное количество ресурсов, один интереснее другого. Так что налетайте!