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

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

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

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

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

Обновить:

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

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

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

2 ответа

Решение

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

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

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

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

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

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

Другие вопросы по тегам