Вопросы относительно загрузки DLL в адресное пространство процесса - PullRequest
3 голосов
/ 16 декабря 2010

Что ж, я прочитал несколько статей Мэтта Пьетрека о файлах Portable Executable (PE), таких как:

Кроме того, я прочитал несколько других источников на эту тему.Это либо я пропускаю некоторые части, либо вопросы там не отвечают.

Итак, вот вопросы:

Известно, что при загрузке EXE загрузчик Windows читаетсписок импортированных DLL-файлов из таблицы адресов Importta (IAT) и загружает их в адресное пространство процесса.

  1. адресное пространство процесса является виртуальным пространством.Возможно, DLL уже загружена в какое-то физическое пространство.Это происходит для DLL, таких как KERNEL32.dll или USER32.dll.Какова связь между физическим и виртуальным адресом?Разве загрузчик просто распределяет страницы и копирует DLL или делает ссылки?

  2. Если DLL не загружена, загрузчик загружает всю DLL или только необходимые функции?Например, если вы использовали функцию foo() из bar.dll, загружает ли загрузчик целое bar.dll в адресное пространство процесса?Или он просто загружает код foo в адресное пространство процесса?

  3. Предположим, что ваш EXE-файл использует функцию MessageBox() из USER32.DLL, которая находится в %WINDIR%\system32\user32.dll.Можете ли вы разработать настроенный USER32.DLL, поместить его в тот же каталог, в котором находится ваш EXE-файл, и ожидать, что ваше настроенное MessageBox вызывается вашим приложением, а не системное значение по умолчанию MessageBox?

Ответы [ 2 ]

6 голосов
/ 16 декабря 2010

Re 1: физические адреса не играют никакой роли, здесь задействовано только виртуальная память. Физический адрес устанавливается только тогда, когда страница виртуальной памяти отображается в ОЗУ, вызванную ошибкой страницы. Многие базовые библиотеки DLL появляются по одному и тому же адресу виртуальной памяти в нескольких процессах, например kernel32.dll. Процессы просто используют одни и те же страницы кода (не данные).

Re 2: фактической «загрузки» не происходит, используется та же функция, которая поддерживает файлы, отображаемые в память. Основой этих страниц является сам файл DLL, а не файл подкачки. Ничего не загружается, пока сбой страницы не заставит Windows прочитать страницу из файла в ОЗУ. Но да, весь раздел кода DLL отображается.

Re 3: да, это сработало бы. Но практически невозможно заставить его работать на практике, так как вам придется написать функции замены для all , которые user32 экспортирует в вашу программу. В том числе те, которые используют другие функции Win32, вы не можете знать. Перехват API - это типичная используемая методика, Detours от Microsoft Labs хорош.

Windows Internals edition 5 - отличная книга, чтобы узнать больше о сантехнике.

2 голосов
/ 16 декабря 2010

1) При создании нового процесса загрузчик ядра NT выделяет пространство для процесса и сопоставляет все разделы PE в указанном месте.Затем загрузчик NT просматривает таблицу импорта, загружает библиотеки DLL в память процесса и, при необходимости, корректирует указатели (это называется перемещением).

2) Загрузчик загружает всю библиотеку DLL в адресное пространство процесса.

3)Да, он будет использовать user32.dll из той же директории, где находится EXE.Смотрите эту ссылку .Но поскольку большинство функций WinAPI расположены в user32.dll, ваша пользовательская библиотека DLL должна экспортировать многие из них.

...