Как работает GetModuleHandle ()? - PullRequest
7 голосов
/ 12 ноября 2010

Я читаю , он описывает API GetModuleHandle () следующим образом:

Когда вы вызываете эту функцию, вы передаете строку с нулевым символом в конце, которая задает имя исполняемого файла или файла DLL, загруженного в адресное пространство вызывающего процесса. Если система находит указанный исполняемый файл или имя DLL , GetModuleHandle возвращает базовый адрес, по которому загружается этот исполняемый файл или DLL; образ файла файла.

Мне интересно где система ищет имя файла ? Когда я загружал какой-то файл в мое адресное пространство процесса, существует ли какая-то централизованная таблица для хранения сопоставления имен всех загруженных файлов и их загрузочных адресов? Если мы ищем на основе совпадения строк, это будет что-то вроде низкой эффективности?

Большое спасибо за ваши insigts.

Ответы [ 3 ]

10 голосов
/ 12 ноября 2010

Информация о загруженном модуле сохраняется как связанный список в PEB процесса в структуре с именем PEB_LDR_DATA. Если вы получили указатель PEB, вы можете просмотреть этот список и получить такую ​​информацию, как имя DLL, базовый адрес, точка входа, размер и т. Д. Проверьте эти страницы:
http://msdn.microsoft.com/en-us/library/aa813708.aspx
http://www.codeproject.com/KB/threads/CmdLine.aspx

4 голосов
/ 12 ноября 2010

Я хотел подтвердить (см. Ответ swatkat ), что по моим сведениям реализация GetModuleHandle() действительно заглядывает внутрь Wine и ReactOS это ).Вы увидите реализацию GetModuleHandle().Разработчики Wine и ReactOS разбирают код Windows и внедряют собственный код на основе результатов дизассемблирования.Поэтому в большинстве случаев код работает так же, как и код Windows.

Если вы хотите, вы можете реализовать собственную реализацию GetModuleHandle() base только VirtualAllocEx().Смотрите мой старый ответ для деталей.(Если вы еще не знаете, дескриптор, возвращаемый функцией GetModuleHandle(), является адресом соответствующего модуля в памяти, поэтому нужно просто каким-либо образом найти dll в памяти текущего процесса).

4 голосов
/ 12 ноября 2010

Он просматривает внутреннюю структуру данных загрузчика (имя Windows для динамического компоновщика).

GetModuleHandle работает только для DLL, которые вы загрузили в текущем процессе.Всякий раз, когда загрузчик загружает DLL в процесс, он, конечно, поддерживает структуру данных, которая включает имя модуля.Нет необходимости посещать файловую систему.

LdrInitializeThunk запускается в пространстве пользователя, чтобы начать процесс извлечения DLL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...