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

StackOverflow https://stackoverflow.com/questions/269314

Вопрос

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

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

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

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

Обновить:

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

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

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

Это было полезно?

Решение

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

  • вы настраиваете обработчик сигналов, перехватывающий 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 Так что это не совсем безобидно...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top