Код: Выделить всё
$ cat /proc/kallsyms | wc -l
112100
Все системные вызовы, в том числе и нужные нам, в ядре косвенно вызываются через sys_call_table. Первая сложность проекта состоит в том, что начиная с ядра Linux 2.6 его авторы исключили имя таблицы системных вызовов sys_call_table из числа экспортируемых. Они сделали это из соображений безопасности … как ониеё понимают. Некоторые публикации вообще утверждают, что использовать в коде модуля ядра sys_call_table невозможно. Но мы можем воспользоваться для поиска адреса sys_call_table такими kernel API как kallsyms_on_each_symbol() или kallsyms_lookup_name() (эта новая функция появилась только в ядрах после 2.6.32). Во всех вариантах наших кодов для поиска адреса не экспортируемого имени ядра мы будем использовать собственную функцию:
Код: Выделить всё
static void* find_sym( const char *sym ) { // find address kernel symbol sym
static unsigned long faddr = 0; // static !!!
// ----------- nested functions are a GCC extension ---------
int symb_fn( void* data, const char* sym, struct module* mod, unsigned long addr ) {
if( 0 == strcmp( (char*)data, sym ) ) {
faddr = addr;
return 1;
}
else return 0;
};
// --------------------------------------------------------
kallsyms_on_each_symbol( symb_fn, (void*)sym );
return (void*)faddr;
}
Таким образом во всех кодах модулей ядра мы будем начинать с поиска адреса таблицы системных вызовов:
Код: Выделить всё
taddr = find_sym( "sys_call_table" ) ;