Маленькая проблемка с восстановлением памяти через memcpy

Тема в разделе "LANGS.C", создана пользователем featurelles, 7 янв 2010.

  1. featurelles

    featurelles New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    562
    Наверное у меня совсем плохо с СИ.
    вот вопрос.

    Есть структура

    #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-й байты перезаписались фиг знает чем.(и сигнатура функции выглядит совсем не так как показывает програмка )

    Соответственно, когда ядро пытается вызвать функцию, то выдаётся паника.

    Собственно вопрос. Что не так в коде?
     
  2. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    featurelles
    эммс, оформил бы код в соответсвующих тегах - читать было бы удобнее.
    далее..
    покажи объявление printk (это я к тому, что в строчке ниже лишнее приведение типов, хотя, это мелочи):
    Код (Text):
    1. hook_struct_ptr->address = printk; // сохраняем в структуре адрес printk
    2. memcpy( hook_struct_ptr->data, (unsigned char *)printk, SIZE ); // сохранили в массиве data пролог функции
    в 1-й строчке ты присвоил , без приведения типа, во 2-ой зачем-то кастишь.

    далее..

    Код (Text):
    1. memcpy(hook_struct_ptr->address, &hook_struct_ptr-->data, SIZE);
    зачем ты пытаешься передать указатель на указатель?
    прототив ф-ции:
    т.е. правильно будет
    Код (Text):
    1. memcpy(hook_struct_ptr->address, hook_struct_ptr-->data, SIZE);
    (почитай про массивы и указатели)

    далее не читал
     
  3. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    пардон, выше в моем ответе ошибка во второй части ответа. сорри. я лопухнулся
     
  4. featurelles

    featurelles New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    562
    Меня щас больше интересует синтаксис СИ.
    Тоесть нормально ли я написал сохранение и восстановление пролога функции.

    printk функция ядра linux аналогичная printf , её взял как простой пример.
    Весь код что написал в первом посте, это просто упрощенный вид кода в моей программе.
    В программе, сделаны две функции отвечающие за устновку и восстановление функции после перехвата.
    В первой функции, как аргумент передаётся адрес функции которую нужно перехватить.
    вот прототип функции
    hook_func( unsigned char *func, unsigned char *new_func);
    вызываю её так hook_func( printk, new_printk);
    передавая в качестве первого аргумента имя функции, означает передачу адреса по которому начинается перехватываемая функция.
    далее идёт этот код

    Код (Text):
    1. #define SIZE 5
    2.  
    3. struct hook_struct
    4. {
    5.   unsigned char *address; // адрес начала перехватываемой функции
    6.   unsigned char data[SIZE]; // тут сохраняем пролог перехвтываемой функции
    7. } hook_struct, *hook_struct_ptr;
    8.  
    9.  
    10. hook_struct_ptr = kmalloc(sizeof(struct hook_struct), GFP_ATOMIC); // выделяем память для структуры
    11. hook_struct_ptr->address = printk; // сохраняем в структуре адрес printk
    12. 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);


    Если с синтаксисом накладок нет, то буду искать ошибку в другом месте.
     
  5. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    featurelles
    да, IMHO, с точки зрения языка Си всё нормально.

    только (позволь придерусь) вот здесь:
    Код (Text):
    1. struct hook_struct
    2. {
    3.   unsigned char *address; // адрес начала перехватываемой функции
    4.   unsigned char data[SIZE]; // тут сохраняем пролог перехвтываемой функции
    5. } hook_struct, *hook_struct_ptr;
    ты объявляешь новый тип данных (структуру hook_struct) и тут же создаешь на стеке неюзаемый далее нигде объект hook_struct. указатель же, hook_struct_ptr, юзается -- потому, нужен.

    короче, можно написать так:
    Код (Text):
    1. struct hook_struct
    2. {
    3.   unsigned char *address;
    4.   unsigned char data[SIZE];
    5. } *hook_struct_ptr;
     
  6. featurelles

    featurelles New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    562
    varnie
    Спасибо.

    А насчёт этого есть какиенить идеи?
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Я тоже не понимаю почему &hook_struct_ptr-->data, а не hook_struct_ptr->data. Потом разве нужно не &printk? Хотя возможны разные варианты синтаксиса.
     
  8. featurelles

    featurelles New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    562
    Опечаточка вышла =)
    в коде записано hook_struct_ptr->data

    А насчёт &printk это аналогично printk ... адрес функции
     
  9. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Booster
    да, выходит, я изначально недаром заподозрил что-то неладное.
    вот, процитирую:
     
  10. featurelles

    featurelles New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    562
    Всем спасибо за помощь )..с проблемой почти разобрался)
    Ошибки в коде представленном выше, нету.