Чтение памяти ядра с использованием модуля - PullRequest
4 голосов
/ 07 июля 2011

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

До сих пор я использую GDB для этой цели. Есть ли способ, чтобы я мог сделать это с помощью модуля ядра. Я новичок в программировании модуля ядра. Нужны советы экспертов здесь.

1 Ответ

10 голосов
/ 07 июля 2011

Позвольте мне сначала сказать, что чтение произвольной памяти ядра - дело сложное!И есть много способов сделать это, которые различаются по степени сложности и гибкости.

1) Жесткий код адреса.

Найдите его в файле System.map версии вашего ядра.:

# grep sys_call_table /boot/System.map-2.6.18-238.12.1.el5
c06254e0 R sys_call_table

С этим жестко закодируйте адрес:

unsigned long *syscall_table = (unsigned long *)0xc06254e0;

Затем, предположив, что вы #include <linux/syscalls.h>, вы можете использовать определения __NR_syscall, чтобы получить адреса этихСистемные вызовы в коде:

syscall_table[__NR_close]

Это самый простой метод, но, безусловно, наименее гибкий.Этот модуль будет работать только на этом конкретном ядре.Если вы внедрите его в другое ядро, вы можете получить ООП ядра.

2) Сканирование методом перебора для таблицы

Посмотрите на это:

http://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/

Он использует метод грубой силы диапазона адресов памяти ядра, чтобы найти sys_call_stable.Как есть, он работает только на 32-битной системе (64-битная имеет другой диапазон адресов памяти для ядра).

Этот метод несколько гибкий, но может помешать работе при изменении семантики ядра.

3) Динамический поиск по времени загрузки System.map

Вы можете прочитать файл System.map вашего ядра при загрузке модуля.Я демонстрирую это в модуле tpe-lkm , который я написал.Проект размещен на github.

Посмотрите на find_symbol_address_from_file () из этого файла:

https://github.com/cormander/tpe-lkm/blob/master/symbols.c

Очень гибкий, так как вы можете найти любой символ, который выхочу, но чтение файлов из пространства ядра - это большое «нет, нет».Не спрашивайте меня почему, но люди всегда говорят мне это.Вы также рискуете, что System.map, на который он смотрит, недопустим и может вызвать ООП ядра.Кроме того, код ... грязный.

4) Используйте kallsyms_on_each_symbol ()

Начиная примерно с версии ядра 2.6.30, ядро ​​экспортирует kallsyms_on_each_symbol ().Мы можем поблагодарить ребят из ksplice за это.При этом вы не можете найти таблицу sys_call_table (по какой-то причине ее там нет), но вы можете найти большинство других символов.

Очень гибкий, очень стабильный метод поиска адресов символов, но несколько сложныйчтобы понять;)

Я демонстрирую это в своем проекте tpe-lkm .Посмотрите на функции find_symbol_callback () и find_symbol_address () в этом файле:

https://github.com/cormander/tpe-lkm/blob/master/symbols.c

...