![]() |
|
![]() ![]() ![]() |
|
Абабо |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 14.1.2005 Репутация: нет Всего: 1 |
Не могли бы вы мне подсказать, как работают инструкции call, длинные jmp и им подобные внутри модуля DLL, спроецированного на адресное пространство процесса? Поскольку в процессе компоновки (создания) DLL известны только относительные адреса (относительно начала DLL-модуля), то при выполнении они должны инкрементироваться некоторым базовым адресом DLL. Мой вопрос в том, где он находится и как, говоря языком ассемблера, происходят подобные вызовы? (т.е. хранится ли базовый адрес постоянно в одном из регистров, либо он перед каждым вызовом считывается из некоторого адреса). Касательно экспортируемых функций вопросов не возникает, поскольку при загрузке DLL их адреса располагаются в собственном (принадлежащем только данному процессу) блоке IAT (Import Address Table) и инкрементируются базовым адресом сразу после проецирования. Но вот как работают вызова локальных (не экспортируемых) функций и переходов (jmp > 128 байт) внутри DLL? Спасибо.
--------------------
С уважением, Абабо. |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 1 Всего: 121 |
При загрузке PE образа по адресу отличному от ImageBase лоадер использует базовые поправки. В PE предусмотрена таблица под название Relocation Table, в ней эти поправки хранятся. Каждая поправка привязана к определённому RVA в exe.
Релоки -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
Абабо |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 14.1.2005 Репутация: нет Всего: 1 |
Спасибо... сейчас буду разбираться...
--------------------
С уважением, Абабо. |
|||
|
||||
Абабо |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 14.1.2005 Репутация: нет Всего: 1 |
Таким образом, для каждого перехода происходит обращение на соответствующую поправку, которая дает реальный VA... Наверно, при таком подходе имееют место ощутимые потери производительности...
Это сообщение отредактировал(а) Абабо - 5.8.2008, 15:00 --------------------
С уважением, Абабо. |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 1 Всего: 121 |
Ну эти поправки применяются только при загрузке при проецировании образа в памяти, поэтому они слишком малы даже для больших файлов, чтобы их можно было заметить.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
Абабо |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 14.1.2005 Репутация: нет Всего: 1 |
Места они занимают немного (особенно, если учесть, что в коде большинство переходов условные, т.е. относительные), но любые абсолютные переходы (call, jmp) происходят через поправки, потому при каждом таком переходе происходит дополнительное обращение к соотв. поправке. Или я чего-то не понимаю?
--------------------
С уважением, Абабо. |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 1 Всего: 121 |
Нет, все абсолютные переходы после применения поправок уже верные. Поправки применяются один раз на стадии загрузки PE и всё, дальше уже все переходы выполняются как если бы мы грузили образ по ImageBase.
Это сообщение отредактировал(а) W4FhLF - 5.8.2008, 15:53 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
Абабо |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 14.1.2005 Репутация: нет Всего: 1 |
Как такое возможно? Ведь DLL разделяется многими процессами, располагаясь в общем случае по разным адресам их вирт. пространств? Проецируются же страницы одной и той же копии... (ведь иначе нивелируется весь смысл DLL). Или, может, при загрузке DLL одним процессом для неё резервируется область виртуальной памяти у всех процессов, вне зависимости от того, проецируется она на пространство того или иного процесса?
Это сообщение отредактировал(а) Абабо - 5.8.2008, 16:30 --------------------
С уважением, Абабо. |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 1 Всего: 121 |
Основные системные DLL грузятся всегда по одним адресам: kernel32.dll и ntdll.dll. Остальные базовые библиотеки(gdi32, user32, advapi32...) система старается загрузить тоже по одному адресу, но если этот адрес уже занят - будет выделена вирт. память по другому адресу. Для тех страниц, в которых надо применить базовые поправки система выделит отдельную физическую память.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
Абабо |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 14.1.2005 Репутация: нет Всего: 1 |
Т.е., поскольку в общем случае нельзя предугадать, какой интервал адресов будет занят, а какой нет, то много шансов, что собственная DLL в процессах с различным DLL-импортом вероятно будет дублирована в памяти, что не есть хорошо... Ясно, большое спасибо.
--------------------
С уважением, Абабо. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Asm для Windows/DOS" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Asm для Windows/Dos | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |