Добрый день! Поведайте мне пожалуйста про эти самые shared-секции: что это собственно такое и зачем они нужны, их описание в PE-файле (видимо от остальных секций она отличается полем IMAGE_SECTION_HEADER.Characteristics) и т.д. желательно уточнить, как эта штука программно-аппаратно реализуется. Ссылки на умные статьи и примерчик на асме приветствуются!
Граждане, ну окажите же посильную помощь. Тема вроде известная. Или гуру на Beginners не заглядывают???(((
Правильно ли я понял - если ДЛЛ уже мэппирована в один процесс, то при мэппировании в другой процесс ее shared-секция во второй процесс мэппироваться не будет??? Хотя в выдержке написано, что ВСЯ секция данных не мэппируется)?! Если это так, то тогда получается, что все остальные процессы юзают shared-секцию, мэппированную в процесс, первым загрузивший ДЛЛ?!А как они ее юзают, если аресное пространство каждого процесса защищено от таких посягательств??? И еще...Поясните пожалуйста вот это: Может все-таки "все процессы разделяют одну копию секции ДАННЫХ (и то если это shared-секция)"?! В общем больше вопросов, чем ответов.
Будет. Это опечатка/<неверный перевод>/<неверный оригинал>. Правильно так: "То есть, все пpоцессы pазделяют одну копию секции кода, но у них будет своя личная копия секции данных DLL!" Секция кода DLL совместно используется, всеми загрузившими её процессами. Т.е. физические страницы, на которых "лежит" код, не дублируются, а отображаются на виртуальные адреса в процессах. Это сделано по банальным соображениям экономии физ. памяти, ибо нет смысла дублировать то, что неизменно, а код, при нормальных условиях, неизменен. Если во всех процессах DLL загружена по одному и тому же виртуальному адресу, то эти виртуальные адреса будут совпадать. Если в каком-либо процессе DLL ребазирована, то секция кода отобразится на соответствующий виртуальный адрес, но физическая страни/ца/цы на кото/рой/рых лежит код всё равно как была, так и останется в единственном экземпляре. Если же какой-либо процесс пишет что-то в код DLL, например хучит функцию, то сработает механизм "copy on write" - физическая страница, в которую происходит запись, будет дублирована, в неё будет произведена запись (хук) и она будет отображена в процесс-писатель. Во всех других процессах ничего не изменится. С секцией данных DLL противоположная ситуация - она не может быть совместно использована, ибо секция данных фактически хранит состояние. Например, у нас есть переменная, в которую мы записываем время загрузки DLL. Естественно, что во всех процессах это значение будет отличаться и все другие переменные могут отличаться. Поэтому вся секция данных в каждом процессе своя, т.е. физические страницы разные. Из-за того, что секция данных DLL не может быть совместно использована и появилась необходимость в специальной разделяемой секции, которая отображается во все процессы и лежит на одной и той же физичес/кой/ких страни/це/цах, но механизм "copy on write" здесь не применяется. Именно поэтому, если один процесс что-то изменит в этой секции, эти изменения тут же увидят все другие процессы, в которые загружена эта DLL, ибо физически - это одна и та же страница.
Four-F А как же релоки ? Думается здесь также должен работать механизм copy-on-write, т.е. те страницы в которых лоадер изменил релоки должны быть продублированы в физ.памяти
Упс... Разумеется copy-on-write сработает и физ. страница будет дублирована и релоки будут пофиксены. Если дубаггер программную бряку будет ставить тоже copy-on-write. В общем случае всё, что требует изменения в страницах, на которых лежит код, требует copy-on-write, ибо эти страницы отображаются прямо из файла dll на диске. Если copy-on-write не сделать, то изменения сбросятся в саму dll.