Есть ли лучший способ, чем парсинг /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 Так что это не совсем безопасно.,