Вот код, трассирую в отладчике: Код (Text): PUSH 4020B0 //Это указатель на старые атрибуты PUSH 4 //Это новые атрибуты PAGE_READWRITE PUSH 10 PUSH 408010 CALL kernel32.VirtualProtect Тут ставлю бряк и смотрю в EAX, EAX==1, по адресу 4020B0 значение 8 Пока всё нормально. Теперь дальше у меня следует такой же код, но с другими данными: (продролжаю трассировать) Код (Text): PUSH 4020B4 //Это указатель на старые атрибуты PUSH 8 //Это новые атрибуты PAGE_WRITECOPY PUSH 10 PUSH 408010 CALL kernel32.VirtualProtect Так, смотрю,на EAX==1, но по адресу 4020B4 значение 8! А я ожилдал там увидеть 4, т. к. перед этим успешно присвоил этому региону атрибут PAGE_READWRITE В чём дело, друзья?
Зачем мне эти ссылки? Чтобы они у меня были? Так они у меня есть. Странице присвоен атрибут PAGE_READWRITE? ПРисвоен. Теперь присваиваем новый атрибут. PAGE_READWRITE должен переписаться в указанный адрес. Не переписывается. НЕужели чисто и честно на пальцах нельзя объяснить, почему?
НЕт, не объясняет. Вот его перевод: PAGE_READWRITE разрешает чтение и запись в указанный регион. Если в основную секцию позволено запиывать, то позволено и копирование совместно разделяемых страниц. Иначе страницы есть совместо разделяемые для чтения или только копирования или записи. Ну и чё? Вопрос как был, так и остался нерешённым.
Я не использую CreateFileMapping, в том-то и дело. ПРоцесс работает с собственной проекцией и никакие другие файлы с помощью CreateFileMapping не подгружает.
нет, в данном случае вирт странице будут выставлены права доступа PAGE_WRITECOPY, т к она относится к проекции модуля (разделяемой памяти), а не к приватной памяти в посте #4 уже была ссылка на статью в msdn описывающую механизм copy-on-write
Ну вот видите как всё непонятно Во-первых, с какой стати? Обыкновенный экзешник спроецирован в память. Откуда предположение, что он будет использоваться другими экзешниками? Что в его секции какой-то другой процесс будет смотреть, что-то писать? Неразумно. Но это на совести винды. опять плохо. В этом случае VirtualProtect могла бы как-то сигнализировать возвращаемым значением. Короче, всё плохо. Если бы не вы, друзья, я бы не разобрался.
amvoz Другие процессы тут ни причем. Экзешник не загружается в память целиком, а именно проецируется для обеспечения подкачки страниц (загрузки их с диска по мере обращения + сброса при нехватке памяти). Но если страница спроецирована с атрибутом PAGE_READWRITE, то при записи в нее эти изменения должны быть записаны на диск, что для экзешников ес-но недопустимо. Поэтому для проекций исполнямых модулей вместо атрибута READWRITE устанавливается WRITECOPY, который по сути означает то же самое (поэтому твой первый вызов VirtualProtect и не выдает ошибки) , но с той разницей, что при попытке записи создается приватная копия страницы с атрибутом READWRITE и ее изменения не отражаются на экзе-файле