Защита памяти процессов в Linux

Тема в разделе "WASM.UNIX", создана пользователем _dima_, 18 ноя 2006.

  1. _dima_

    _dima_ New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2006
    Сообщения:
    9
    Нужно прехватить вызовы некоторых функций в Linux, с помощью подмены кода, но возникла проблема с изменением атрибутов виртуальной памяти процесса. В винде это делается с помощьюю VirtualProtect. Существует ли аналог подобной функции в Linux?
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    syscall #125 : mprotect
     
  3. _dima_

    _dima_ New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2006
    Сообщения:
    9
    Когда я указываю в параметрах mprotect адрес перехватываемой фунуции, она возвращает -1
    вот примерчик: mprotect((void*)fopen, cmd_sz, PROT_WRITE | PROT_EXEC);
     
  4. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Не адрес функции нужно указывать, а "page-aligned start address of memory region", т.е. стартовый адрес страницы. 2й параметр: "page-aligned bytes' size of memory region".
     
  5. _dima_

    _dima_ New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2006
    Сообщения:
    9
    как же тогда все-таки изменить атрибуты первых байтов функции, например open, используя mprotect, если вас не затруднит, не могли бы вы привести небольшой примерчик.
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    _dima_
    Посмотрите тогда описание VirtualProtect в msdn - принцип тотже. Атрибуты задаются постранично, а не побайтово. Нужно вычислить адрес начала страницы, где хранится код функции, которую нужно пропатчить. Если размер страницы - 4Кб, то вычислить адрес начала можно простым and addr,0FFFFF000h.
     
  7. _dima_

    _dima_ New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2006
    Сообщения:
    9
    Спасибо, mprotect заработала. Но к сожалению возникла новая проблемка: подмена первых байт функции fopen прошла удачно, на при попытке вызвать ее - segmentation fault, вот небольшой пример:
    #include<stdio.h>
    #include<string.h>
    #include<sys/mman.h>
    typedef unsigned char byte;
    int cmd_sz = 5;
    int addr_sz = 4;
    unsigned char JMP = 0xE9;

    int my(const char* fname, const char* mode){
    printf("your file ");
    printf(fname);
    printf(" could not de open in mode ");
    printf(mode);
    printf("\n");
    return 0;
    };

    int main(){
    unsigned char old_bytes[cmd_sz];
    unsigned char new_bytes[cmd_sz];
    new_bytes[0] = JMP;
    memmove(&new_bytes[1], (const void*)my, addr_sz);
    memmove(old_bytes, (const void*)fopen, cmd_sz);
    int addr = (int)(void*)fopen;
    printf("%d\n", addr);
    int page_addr = addr & 0x0FFFFF000;
    printf("%d\n", mprotect((void*)page_addr ,4096, PROT_READ | PROT_WRITE | PROT_EXEC)); //здесь ноль!
    memmove((void*)fopen, new_bytes , cmd_sz); //здесь тоже все ок!
    fopen("no.txt", "a+"); // здесь Segmentation fault
    return 0;
    }
     
  8. _dima_

    _dima_ New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2006
    Сообщения:
    9
    Блин, там ошибка с JMP. Если ее поправить все работает как надо. Спасибо большое за помощь!