Исполняемые разделы, помеченные как "выполнить" И "прочитать"?

Я заметил (по крайней мере на Win32), что в исполняемых файлах разделы кода (.text) имеют установленный бит доступа "чтение", а также бит доступа "выполнение". Существуют ли какие-либо законные причины для того, чтобы код сам читал, а не выполнял себя? Я думал, что это было то, для чего были другие разделы (такие как.rdata).

(Конкретно я про IMAGE_SCN_MEM_READ.)

3 ответа

Решение

IMAGE_SCN_MEM_EXECUTE |IMAGE_SCN_MEM_READ отображаются в память как PAGE_EXECUTE_READ, что эквивалентно PAGE_EXECUTE_WRITECOPY. Это необходимо для обеспечения доступа при копировании при записи. Копирование при записи означает, что любые попытки изменить страницу приводят к созданию новой, приватной копии процесса создаваемой страницы.

Есть несколько разных причин необходимости записи-копирования:

  • Код, который должен быть перемещен загрузчиком, должен иметь этот набор, чтобы загрузчик мог делать исправления. Это очень распространено.
  • Разделы, которые содержат код и данные в одном разделе, также потребуются, чтобы можно было изменять глобальные переменные процесса. Код и данные в одном разделе могут сэкономить пространство и, возможно, улучшить локальность, имея код и глобальные переменные, которые использует код, на одной странице.
  • Код, который пытается изменить себя. Я считаю, что это довольно редко.

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

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

Также рассмотрим противоположную сторону. Какие преимущества дает запрет на чтение кода? Я немного боролся с этим, но не вижу никакой выгоды от этого.

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