Как «использовать системный вызов write () для чтения со страницы (запись в дескриптор фиктивного pipe ())» в C / C ++?

0

Мне нужно проверить, читается ли адрес памяти, поэтому я искал и нашел этот вопрос: как проверить, читается ли адрес в приложении для Linux-приложения. Как пользователь @caf заявил:

Канонический способ - использовать системный вызов write() для чтения со страницы (запись в дескриптор файла dummy pipe()).

К сожалению, он не представил какой-либо пример кода, и я не могу комментировать (низкая репутация) и не отправлять ему сообщение (по крайней мере, я не знаю, как).

РЕДАКТИРОВАТЬ

Не могу ли я просто пропустить создание трубы, сделав что-то подобное?

int result = write(0, addr, 1);

@Mats Petersson: Я пытаюсь проанализировать и изменить функцию после загрузки ее в память с помощью указателя функции (я увеличиваю указатель и копирую его байт по байтам), поэтому, чтобы определить, нужна ли мне эта функция для знайте, может ли память записываться и читаться (это немного глупо, я знаю). Во всяком случае, я бы не хотел изменять свои права на чтение и запись в памяти программ, поэтому то, что вы сказали, может быть проблемой.

EDIT 2 @Damon: так есть ли другой верный способ сделать это?

  • 0
    Обратите внимание, что этот метод страдает от обычной проблемы «toctou» (время проверки на время использования) - вы проверяете, что адрес X действителен, он действителен, ОС решает вернуть эту часть памяти в результате какой-либо операции [ такие как закрытие канала, но существуют сотни других возможных сценариев, особенно в многоядерной / многопоточной системе], и память больше не действительна. Может быть, если вы опишите проблему, которую вы НАСТОЯЩЕМУ пытаетесь решить (например, «почему вы считаете, что вам нужно знать, правильна ли память»), и мы сможем найти лучшее решение?
  • 0
    Также обратите внимание, что это может вызвать сбой страницы (предполагается, что адрес является допустимой страницей), который не только медленный, но и, возможно, удаляет другую страницу из вашего рабочего набора.
Показать ещё 1 комментарий
Теги:
pointers
memory

2 ответа

5
Лучший ответ

Сначала создайте пару труб, чтобы записать данные:

 int fd[2];
 pipe(fd);

Затем попробуйте записать некоторые данные с вашего адреса на сторону записи в трубе:

 int result = write(fd[1], addr, 1);

Если result равен 1, запись была выполнена, поэтому адрес был доступен для чтения. Если он равен нулю и errno == EFAULT, адрес не читается. Если errno - это что-то другое, что-то другое пошло не так.

Конечно, закройте трубы, как только вы закончите, конечно:

 close(fd[0]);
 close(fd[1]);
2

Я никогда не использовал этот метод себя, но я думаю, что года должны создать трубу ( с помощью pipe системного вызова), когда write в эту трубу, обеспечивая адрес, который вы хотите проверить, в качестве буфера.

Итак, скажем, вы хотите проверить адрес 0x1000000, тогда вы делаете

int res = write(dummypipe[1], 0x1000000, 1);

Если res - -1 то вы проверяете, является ли errno == EFAULT что указывает, что адрес недействителен.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню