Подтвердить что ты не робот

Есть ли лучший способ, чем синтаксический анализ /proc/self/maps для определения защиты памяти?

В Linux (или Solaris) есть лучший способ, чем ручной разбор /proc/self/maps, чтобы выяснить, можете ли вы читать, записывать или выполнять все, что хранится по одному или нескольким адресам в памяти?

Например, в Windows у вас есть VirtualQuery.

В Linux я могу mprotect изменить эти значения, но я не могу их прочитать.

Кроме того, есть ли способ узнать, когда эти разрешения изменяются (например, когда кто-то использует mmap в файле за моей спиной), кроме как что-то ужасно инвазивное и используя ptrace для всех потоков в процессе и перехватывая любые попытаться сделать syscall, который может повлиять на карту памяти?

Update:

К сожалению, я использую это внутри JIT, у которого очень мало информации о коде, который он выполняет, чтобы получить приближение к тому, что является постоянным. Да, я понимаю, что могу иметь постоянную карту изменчивых данных, например, страницу vsyscall, используемую Linux. Я могу смело откинуться на предположение, что все, что не включено в начальный синтаксический анализ, изменчиво и опасно, но я не совсем доволен этой возможностью.

Прямо сейчас, что я делаю, я читаю /proc/self/maps и строю структуру, через которую я могу выполнить двоичный поиск для определенной защиты адреса. Каждый раз, когда мне нужно что-то знать о странице, которая не входит в мою структуру, я перечитываю /proc/self/maps, предполагая, что она была добавлена ​​тем временем, или я собираюсь все равно segfault.

Кажется, что разбор текста, чтобы получить эту информацию и не зная, когда он изменится, ужасно крут. (/dev/inotify не работает почти ничего в /proc)

4b9b3361

Ответ 1

Я не знаю эквивалента VirtualQuery для Linux. Но некоторые другие способы сделать это могут или не могут работать:

  • вы настраиваете обработчик сигналов, захватывая SIGBUS/SIGSEGV и продолжайте чтение или запись. Если память защищена, вызывается код захвата сигнала. Если ваш код захвата сигнала не вызывается. В любом случае вы выигрываете.

  • вы можете отслеживать каждый раз, когда вы вызываете mprotect, и создавать соответствующую структуру данных, которая поможет вам узнать, защищена ли область или защищена ли она. Это хорошо, если у вас есть доступ ко всему коду, который использует mprotect.

  • вы можете отслеживать все вызовы mprotect в вашем процессе, связывая свой код с библиотекой, переопределяя функцию mprotect. Затем вы можете создать необходимую структуру данных для того, чтобы узнать, защищена ли область или защищена ли она, а затем вызовите систему mprotect, чтобы действительно установить защиту.

  • вы можете попробовать использовать /dev/inotify и отслеживать файл /proc/self/maps для любых изменений. Я думаю, что это не работает, но стоит попробовать.

Ответ 2

Там sorta is/was/proc/[pid | self]/pagemap, документация в ядре, оговорки здесь: https://lkml.org/lkml/2015/7/14/477 Так что это не совсем безопасно...