Доступ к файлу proc//mem

119
03 сентября 2019, 02:00

При прохождении одного из онлайн тестов наткнулся на сложный вопрос. Вопрос формулируется примерно так:

Не удаётся прочитать файл /proc//mem даже из под рута из-за ошибки доступа (permission error). Как решить эту проблему? Код открывающий этот файл на чтение:

int mem_file = open("/proc/12345/mem", O_RDONLY);

Варианты ответов: 1. Использовать ptrace

ptrace(PTRACE_ATTACH, 12345, NULL, NULL);
waitpid(pid, NULL, 0);
int mem_file = open("/proc/12345/mem", O_RDONLY);
...
close(mem_file);
ptrace(PTRACE_DETACH);

2. Послать сигналы SIGSTOP/SIGCONT:

Kill(12345, SIGSTOP);
int mem_file = open("/proc/12345/mem", O_RDONLY);
...
close(mem_file);
kill(12345, SIGCONT);
  1. Проверить атрибуты исполняемого файла и удалить immutable profile.

  2. Это не работает из под рута. Нужно проверить пользовательский режим и задать разрешения.

Текст исходников приведён как есть, с сохранением опечаток в оригинале.

После чтения документации и компиляции и запуска кода, я обнаружил, что варианты 1 и 2 оба работают даже без рута. Но видимо какой-то один из них более правильный. Подскажите пожалуйста, какой из этих вариантов лучше подходит для доступа к памяти процесса?

Answer 1

Чтение первого байта /proc/pid/mem всегда приводит к ошибке ввода-вывода. Так задумано. В этом файле надо читать со смещением. Смещение совпадает с реальным смещением в запущенной программе.

Что-бы узнать о смещениях памяти используемых программой нужно читать /proc/pid/maps, там указанны используемые регионы памяти.

Важно:

  1. вы не сможете прочитать mem файл другого работающего процесса, получите ошибку Нет такого процесса.

  2. если все же есть необходимость читать mem файл другого процесса, то необходимо присоединиться к процессу, используя ptrace() вызов. Но все не так просто, и процесс надо останавливать на время чтения.

  3. процесс, выполняющийся от имени root, может читать память любого процесса без вызова ptrace, но наблюдаемый процесс должен быть остановлен, иначе все равно получите ошибку.

Есть ещё куча нюансов при работе с виртуальными файлами ядра, рекомендую знакомиться с исходными кодами кернеля если у вас возникают вопросы.

Вот примерный сценарий на C чтения mem файла по методу номер 2:

sprintf(fname, "/proc/%d/mem", pid);
fd = open(fname, O_RDONLY);
ptrace(PTRACE_ATTACH, pid, NULL, NULL);
waitpid(pid, NULL, 0);
lseek(fd, offset, SEEK_SET);
read(fd, buffer, _SC_PAGE_SIZE);
ptrace(PTRACE_DETACH, pid, NULL, NULL);

Посмотрите на mem_open и на check_mem_permission для понимания как там все устроено.

READ ALSO
Как спарсить строку?

Как спарсить строку?

Есть строка вида: "40 1234567 12"

139
Передать сигнал и слот QT как параметр

Передать сигнал и слот QT как параметр

Есть библиотека которая общается с устройством либо через usb, либо через ethernet, либо еще через что тоИ хотелось бы что бы передать в конструктор...

99
Задать время для перехода на следующий Activity

Задать время для перехода на следующий Activity

Подскажите, как задать время для перехода на следующий ActivityОбъясню для чего

110