Наверное у меня совсем плохо с СИ. вот вопрос. Есть структура #define SIZE 5 struct hook_struct { unsigned char *address; // адрес начала перехватываемой функции unsigned char data[SIZE]; // тут сохраняем пролог перехвтываемой функции } hook_struct, *hook_struct_ptr; hook_struct_ptr = kmalloc(sizeof(struct hook_struct), GFP_ATOMIC); // выделяем память для структуры hook_struct_ptr->address = printk; // сохраняем в структуре адрес printk memcpy( hook_struct_ptr->data, (unsigned char *)printk, SIZE ); // сохранили в массиве data пролог функции ...ставлю хук. Затем в /dev/mem смотрю как пропатчилась функция (первые 5 байт заменены jmp и адрес) И перехват функции работает на отлично. Однако, когда делаю следующее memcpy(hook_struct_ptr->address, &hook_struct_ptr-->data, SIZE); Чтоб восстановить прежние пять байт, то происходит следующее. Посмотрев /dev/mem вижу что восстановились только первые 4 байта. 5-й 6-й 7-й 8-й байты перезаписались фиг знает чем. До модификации функции делаю вывод байтов printk unsigned char *test1=printk; int i=0; for(i=0; i<SIZE*n; i++) { printk("%x ", test1); } Выводит 55 89 e5 83 ec 8 89 1c 24 89 74 24 4 f 1f 44 После модификации имеем e9 4b 9d b0 37 8 89 1c 24 89 74 24 4 f 1f 44 После попытки восстановления первоначальных 5 байт через этот код memcpy(hook_struct_ptr->address, &hook_struct_ptr->data, SIZE); Снова вывожу байты функции и вижу следующее. 55 89 e5 83 ec 8 89 1c 24 89 74 24 4 f 1f 44 То что всё восстановилось. Но посмотрев /dev/mem/ вижу что восстановились только первые 4 байта. 5-й 6-й 7-й 8-й байты перезаписались фиг знает чем.(и сигнатура функции выглядит совсем не так как показывает програмка ) Соответственно, когда ядро пытается вызвать функцию, то выдаётся паника. Собственно вопрос. Что не так в коде?
featurelles эммс, оформил бы код в соответсвующих тегах - читать было бы удобнее. далее.. покажи объявление printk (это я к тому, что в строчке ниже лишнее приведение типов, хотя, это мелочи): Код (Text): hook_struct_ptr->address = printk; // сохраняем в структуре адрес printk memcpy( hook_struct_ptr->data, (unsigned char *)printk, SIZE ); // сохранили в массиве data пролог функции в 1-й строчке ты присвоил , без приведения типа, во 2-ой зачем-то кастишь. далее.. Код (Text): memcpy(hook_struct_ptr->address, &hook_struct_ptr-->data, SIZE); зачем ты пытаешься передать указатель на указатель? прототив ф-ции: т.е. правильно будет Код (Text): memcpy(hook_struct_ptr->address, hook_struct_ptr-->data, SIZE); (почитай про массивы и указатели) далее не читал
Меня щас больше интересует синтаксис СИ. Тоесть нормально ли я написал сохранение и восстановление пролога функции. printk функция ядра linux аналогичная printf , её взял как простой пример. Весь код что написал в первом посте, это просто упрощенный вид кода в моей программе. В программе, сделаны две функции отвечающие за устновку и восстановление функции после перехвата. В первой функции, как аргумент передаётся адрес функции которую нужно перехватить. вот прототип функции hook_func( unsigned char *func, unsigned char *new_func); вызываю её так hook_func( printk, new_printk); передавая в качестве первого аргумента имя функции, означает передачу адреса по которому начинается перехватываемая функция. далее идёт этот код Код (Text): #define SIZE 5 struct hook_struct { unsigned char *address; // адрес начала перехватываемой функции unsigned char data[SIZE]; // тут сохраняем пролог перехвтываемой функции } hook_struct, *hook_struct_ptr; hook_struct_ptr = kmalloc(sizeof(struct hook_struct), GFP_ATOMIC); // выделяем память для структуры hook_struct_ptr->address = printk; // сохраняем в структуре адрес printk memcpy( hook_struct_ptr->data, (unsigned char *)printk, SIZE ); // сохранили в массиве data пролог функции Меня смущает только синтаксис СИ.. правильно ли я сохранил вот тут memcpy( hook_struct_ptr->data, (unsigned char *)printk, SIZE ); Пролог функции (вроде верно) И правильно ли я его записал обратно по адресу по которому расположен этот самый printk memcpy(hook_struct_ptr->address, &hook_struct_ptr->data, SIZE); Если с синтаксисом накладок нет, то буду искать ошибку в другом месте.
featurelles да, IMHO, с точки зрения языка Си всё нормально. только (позволь придерусь) вот здесь: Код (Text): struct hook_struct { unsigned char *address; // адрес начала перехватываемой функции unsigned char data[SIZE]; // тут сохраняем пролог перехвтываемой функции } hook_struct, *hook_struct_ptr; ты объявляешь новый тип данных (структуру hook_struct) и тут же создаешь на стеке неюзаемый далее нигде объект hook_struct. указатель же, hook_struct_ptr, юзается -- потому, нужен. короче, можно написать так: Код (Text): struct hook_struct { unsigned char *address; unsigned char data[SIZE]; } *hook_struct_ptr;
Я тоже не понимаю почему &hook_struct_ptr-->data, а не hook_struct_ptr->data. Потом разве нужно не &printk? Хотя возможны разные варианты синтаксиса.
Опечаточка вышла =) в коде записано hook_struct_ptr->data А насчёт &printk это аналогично printk ... адрес функции