Статьи Королевства Дельфи


Несколько слов о загрузке DLL




Здравствуйте, коллеги! Поводом для написания этой статьи стало прочтение статьи Криса Касперски .

Вкратце содержание статьи (дается в произвольном виде, со своими коментариями).

Все исполняемые модули (EXE и DLL) грузятся в память Windows(NT/2000/XP) следующим образом (я оставил только важные для нас пункты) Загрузка первой копии приложения:
  • Прочитать служебную информацию из файла.
  • Спроецировать в память все секции файла с защитой PAGE_EXECUTE_WRITECOPY(ну, кроме данных)
  • Некоторые дополнительные приготовления (о них речь и пойдет в статье)
  • Модуль готов.
Загрузка всех последующих копий приложения:
  • Прочитать служебную информацию из файла.
  • Спроецировать в память все секции файла с защитой PAGE_EXECUTE_WRITECOPY(ну кроме данных...), здесь система ведет себя несколько по-другому, нежели при первой загрузке, поэтому я выделил ее в другой блок, но это тонкости.
  • Некоторые дополнительные приготовления(о них речь и пойдет в статье)
  • Модуль готов.

Отличий, вроде бы, никаких? Но (!!!) пункт 2 говорит, что память выделяется всем копиям одна и та же(!!!). Таково свойство проецируемых файлов(см. Help. Topic: CreateFileMapping, OpenFileMapping, MapViewOfFile …).
"А как же данные каждого приложения, которые не зависимы от других приложений?"- спросите Вы. А для этого и стоит защита. Как только программа пытается писать что-то в память, система делает копию этой страницы, ставит ей соответствующую защиту, и далее это приложение работает со своей (измененной) страницей, а все остальные с общей. Зачем так сложно? Из экономии памяти и увеличения быстродействия, ведь когда идет SWAP памяти, не измененные страницы система просто удаляет (ведь они остались в исполняемом файле), а измененные скачиваются в SWAP-файл. Когда данные опять понадобятся, они читаются из разных мест (из исполняемого файла или из SWAP-файла).
В первом случае мы имеем огромный плюс:

  • Нет записи в SWAP-файл (а запись, между прочим, примерно в 3 раза медленнее, чем чтение),
  • Не расходуется виртуальная память.

Теперь про упаковку файла. После проецирования, прежде чем модуль будет готов, он распаковывается специальной подпрограммой. Т.е. сразу при загрузке модуль переписывает всю (!!!) свою память, что заставляет систему выделить ее (память) в отдельный блок. Т.е. ни о какой экономии речь уже не идет. Ладно, если Вы запустили упакованный таким образом NotePad, а если Word? Да еще и 3 раза?

А теперь, непосредственно по теме данной статьи.




Начало  Назад  Вперед