Книга: Программирование для Linux. Профессиональный подход

Листинг 8.7. (mprotect.c) Обнаружение попыток доступа к памяти благодаря функции mprotect()

закрыть рекламу

Листинг 8.7. (mprotect.c) Обнаружение попыток доступа к памяти благодаря функции mprotect()

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
static int alloc_size;
static char* memory;
void segv_handler(int signal_number) {
 printf("memory accessed!n");
 mprotect(memory, alloc_size, PROT_READ | PROT_WRITE);
}
int main() {
 int fd;
 struct sigaction sa;
 /* Назначение функции segv_handler() обработчиком сигнала
    SIGSEGV. */
 memset(&sa, 0, sizeof(sa));
 sa.sa_handler = &segv_handler;
 sigaction(SIGSEGV, &sa, NULL);
 /* Выделение одной страницы путем отображения в памяти файла
    /dev/zero. Сначала память доступна только для записи. */
 alloc_size = getpagesize();
 fd = open("/dev/zero", O_RDONLY);
 memory =
  mmap(NULL, alloc_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
 close(fd);
 /* Запись на страницу для получения ее копии в частное
    использование. */
 memory[0] = 0;
 /* Запрет на запись в память. */
 mprotect(memory, alloc_size, PROT_NONE);
 /* Попытка записи в память. */
 memory[0] = 1;
 /* Удаление памяти. */
 printf("all donen");
 munmap(memory, alloc_size);
 return 0;
}

Программа работает по следующей схеме.

1. Задается обработчик сигнала SIGSEGV.

2. Файл /dev/zero отображается в памяти, из которой выделяется одна страница. В эту страницу записывается инициализирующее значение, благодаря чему программе предоставляется частная копия страницы.

3. Программа защищает память, вызывая функцию mprotect() с флагом PROT_NONE.

4. Когда программа впоследствии обращается к памяти, Linux посылает ей сигнал SIGSEGV, который обрабатывается в функции segv_handler(). Обработчик сигнала отменяет защиту памяти, разрешая выполнить операцию записи.

5. Программа удаляет область память с помощью функции munmap().

Оглавление книги


Генерация: 1.031. Запросов К БД/Cache: 4 / 1
поделиться
Вверх Вниз