Делаю так ошибка появляется: "Память не может быть read" Код (Text): VirtualProtect(@ForCopy, 1, PAGE_NOACCESS, Old); try ForCopy; except end; Делаю так, прога вылетает... Код (Text): try VirtualProtect(@ForCopy, 1, PAGE_NOACCESS, Old); try ForCopy; except end; except end; Странно это...
Ничего странного, если твоя ForCopy расположена в той же 4K странице, что и вызов VirtualProtect (думаю ты понимаешь, что доступ устанавливается не для одного байта, а для всей страницы, в которой лежит этот байт). В этом случае ошибка возникает уже при возврате из VirtualProtect до вызова ForCopy. В первом варианте try\except на возврат не установлен и исключение передается в финальный дефолтный обработчик приложения, который расположен в другой 4K странице. Во втором варианте локальный обработчик try\except установлен, но лежит поблизости в той же заблокированной странице. Повторное исключение при вызове обработчика это уже слишком и ось просто прибивает твою прогу (имхо).
IceStudent При обращении к PAGE_NOACCESS возникает #GP, т.е. Access Violation. Откуда у SnugForce берется "Память не может быть read" - нужно у него спросить
Хм... понял. Хотя у меня выскакивает: "Инструкция по адресу ... обратилась к памяти по адресу ... . Память не может быть read"
leo Не, спорить не буду, просто по идее он же обращается на читая, а пытаясь вернуться в код, на который выставлено PAGE_NOACCESS..
SnugForce Ну дык посмотри в отладчике, на какой инструкции происходит ошибка. Может тут еще какие собаки зарыты или просто сообщение выводится неточное.
Смоделировал ситуацию и тоже получаю сообщение типа Read of address ..., хотя это адрес команды xor eax,eax (стандартное начало try\except в дельфях) и естественно его никто не read, а лишь execute. Так что это имхо не более чем общая фраза. Кстати в пошаговом режиме Оля возвращается из ret VirtualProtect на xor, но при попытке исполнить этот xor кричит об access violation
IceStudent > А разве исключение будет не "cannot be to execute"? А ты когда-будь встречал такие сообщения ? Насколько я понимаю такое возможно только при наличии аппаратной поддержки DEP (предотвращение исполнения данных). Без такой поддержки процессор распознает только два варианта доступа к странице read-only или read-write. Запретить read и execution процессору явно нельзя, можно только сделать страницу недоступной вообще - сбросить флаг present или установить резервные флаги, что видимо ось и делает при установке атрибута PAGE_NOACCESS. При обращении к инвалидной странице проц выдает исключение #PF (page fault) и в error-коде указывает тип доступа, при котором произошла ошибка - read или write (никакого execute не предусмотрено). Поэтому имхо и вываливаются два стандартных варианта сообщения "Память не может быть read (или write)". Ну а поскольку при исполнении ошибка происходит при попытке чтения кода в кэш, то ес-но это read Во втором варианте кода, когда VirtualProtect заключена в try\except, происходит двойной fault и программу приходится прибивать. В XP, кстати при этом срабатывает программный DEP - прежде чем передать управление SEH-обработчику ось проверяет валидность его адреса. Поэтому при включенном DEP прога умирает не по тихому, а после серии виндовых предупреждений, разъяснений и предложений )
> "никакого execute не предусмотрено" А вот в AMD64 предусмотрено - в PF error-коде есть доп. флажок I/D (instruction/data), который установлен если ошибка произошла при фетче инструкций. Все течет, все изменяется, однако