Я пытаюсь вызвать функцию readdir по своему указателелю this_readdir который указывает на функцию readdir из структуры struct file_operations ядра. При попытке вызова, вылазит данная ошибка:
Пробовал использовать такой код, чтоб снять NX bit
/* снятие защиты */
int set_kernel_exec(unsigned long vaddr, int enable)
{
pte_t *pte;
unsigned int level = 0;
int ret = 1;
pte = lookup_address(vaddr, &level);
if (pte_val(*pte) & _PAGE_NX) ret = 0;
if (enable){ pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));}
else
{pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);}
__flush_tlb_all();
out:
return ret;
}
/* вызывал функцию так */
set_kernel_exec((unsigned long)this_readdir, 1);
После этого, при попытке вызова this_readdir система виснет.
Прошу помощи, т.к. сам уже опустил руки. Находил в сети https://github.com/cormander этот человек задавал точно такойже вопрос на англоязычном форуме, но несколько лет назад. Скачивал его исходники, искал код который может пригодится. Но нужного не нашёл. Очень рассчитываю на помощь.
Мне нужно заменить обработку одной функции ядра, другой (своей).
Тут замена функции ядра идёт, но полагаю замена syscall должна быть полностью аналогична.
Если у Вас есть какой-то код, который может мне помочь, то буду благодарен, очень.
По-моему, замена syscall это типовая задача, есть куча кода в инете.
Но у тебя может быть совсем другой случай.
Не уверен что тебе это поможет, но.. ты видел эти ссылки?
Оффтоп: а я ядре Linux есть хоть какая-то защита чтобы одна подсистема не нагадила по ошибке в другую подсистему? Хотя бы минимальная защита памяти есть? Подробнее... Ну если не полная изоляция процессов как в микроядре, но хоть что то...
«ты пытаешься прыгнуть на указатель по своему указателю вместо вызова функции?»
Я пробую сделать свой обрабочик функции readdir который в конце вызывает оригинальную функцию readdir ядра.
выглядит так
int (*this_readdir) (struct file *, void *, filldir_t); // оригинальная функция обрабочик
int my_readdir (struct file *, void *, filldir_t)
{
// моя функция обработчик, в неё попадаем без проблем
return this_readdir(struct file *, void *, filldir_t); // код который не удаётся выполнить
}
// в структуре struct file_operations ядра изменяю указатель readdir на my_readdir
// (далее код корректно заходит в функцию my_readdir
// но выдаёт ошибку при вызове оригинальной функции)
true_admin ссылки не видел, почитаю. спасибо. tailgunner Вы сказали что замена syscall не аналогична , замене функции обработчика самого ядра. Если не сложно объясните в чём различие.
Задача котороая передомной стоит изложена выше, если подскажите как её решить, буду благодарен. derlafff
Спасибо за ссылки! интересно почитать про http://habrahabr.ru/post/206778/
И ещё смотрел код kmod_hooking. Пока не разобрался, досконально как он работает, постараюсь сейчас понять принцип работы и попробую.
На всякий случай добавлю, заменить readdir на my_readdir я хочу просто заменой указателя на функцию обработчик, без использования сплайсинга.
а я ядре Linux есть хоть какая-то защита чтобы одна подсистема не нагадила по ошибке в другую подсистему?
Ну, с моей обывательской точки зрения, нет т.к. всё крутится в одном адресном пространстве. Но какая-то изоляция от сбоев есть. Начиная от макроса BUG_ON и заканчивая некоторыми специфичными обработчиками исключений и вещами типа nmi_watchdog итп. Т.е. разыменовывание нулевого указателя в обычном модуле ядра вряд ли подвесит систему.
Не вчитывался — не знаю. Вообще-то NX выключается/выключался в BIOS'е. Но это абсолютно неправильное решение. Ищи проблемы в своём коде, а не пытайся их решить через заднепроходнее отверстие. На то NX и создавался, что бы исключить подобные грязные хаки, ломающие всё и вся.
Всё таки, показал бы ты лучше код. А так гадание на кофейной гуще выходит. Может у тебя там большие локальные структуры, а стек IIRC в кернеле ограничен — часто имеет смысл (? но тут я не эксперт) их определить глобально.
Тут дело не в стеке, нет больших структур (кстати как помню, в стеке может быть 1024 байта, для одной функции) . Тут ошибка именно с защитой памяти от выполнения. Надо блокировку снять и должно заработать, а как это сделать ума не приложу.
Толькочто подумал, можно попробовать снять блокировку на выполнение кода в ядре, через команду системе (с прикладного уровня) а дальше уже грузить модуль для теста, посмотреть что будет. Кто знает? как сделать?