Подтвердить что ты не робот

Неужели перезагрузка DLL (или предоставление соответствующего загрузочного адреса по умолчанию) стоит того?

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

Это может быть достигнуто с помощью инструмента, такого как Rebase.exe, или путем указания адресов загрузки по умолчанию для всех ваших (собственных) DLL, чтобы они "соответствовали" вашему исполняемому процессу.

Весь смысл управления базовыми адресами DLL таким образом - ускорить загрузку приложений. (Или так я понимаю.)

вопрос: стоит ли беспокоиться?

У меня есть книга Windows через C/С++ от Richter/Nazarre, и они настоятельно рекомендуют [a] убедиться, что адреса загрузки все совпадают, так что загрузчику не нужно перегружать загруженные библиотеки DLL.

Однако они не могут утверждать, что это ускоряет время загрузки приложения до любого значительного количества.

Кроме того, с ASLR кажется сомнительным, что это имеет какое-либо значение вообще, так как адреса загрузки будут рандомизированы в любом случае.

Есть ли какие-либо жесткие факты о про/минусах этого?

[a]: В моем WvС++/5th ed он находится в разделах под названием Rebasing Modules и Binding Modules на стр. 568ff. в главе 20 "Расширенные методы DLL".

4b9b3361

Ответ 1

Я хотел бы дать один ответ сам, хотя ответы Hans Passant и другие описывают компромиссы уже довольно хорошо.

После того, как мы в последнее время возились с базовыми адресами DLL в нашем приложении, я приведу свой вывод:

Я думаю, что если вы не можете доказать обратное, предоставление DLL с базовым адресом, отличным от Default, является бесполезным упражнением. Это включает в себя перезагрузку моих DLL.

  • Для DLL, которые я контролирую, учитывая среднее приложение, каждая DLL будет загружаться в память только один раз, так что загрузка файла подкачки должна быть минимальной. (Но см. Комментарий Michal Burr в другом ответе о среде сервера терминалов.)

  • Если библиотеки DLL снабжены фиксированным базовым адресом (без перезагрузки), это фактически увеличит фрагментацию адресного пространства, так как рано или поздно эти адреса больше не будут соответствовать. В нашем приложении мы предоставили всем DLL фиксированный базовый адрес (по другим причинам, а не из-за фрагментации адресного пространства) без использования файла rebase.exe, и это значительно увеличило фрагментацию адресного пространства для нас, потому что вы действительно не можете это сделать вручную.

  • Rebasing (через rebase.exe) не дешево. Это еще один шаг в процессе сборки, который необходимо поддерживать и проверять, поэтому он должен иметь некоторую выгоду.

  • В большом приложении всегда будут загружены некоторые DLL файлы, где базовый адрес не совпадает, из-за некоторых DLL файлов с крючками (AV) и потому, что вы не перегружаете сторонние DLL файлы (или, по крайней мере, я бы этого не сделал).

  • Если вы используя RAM-диск для файла подкачки, вам может быть лучше, если загружаемые DLL файлы будут выгружены out: -)

Итак, чтобы подвести итог, я думаю, что rebasing не стоит проблем, кроме особых случаев, таких как системные DLL.


Я бы хотел добавить исторический фрагмент, который я нашел в Old New Thing: Как перезагрузили DLL файлы Windows 95? -

Когда нужно было переустановить DLL, Windows 95 просто сделала бы заметку нового базового адреса DLL, но не сделал бы ничего другого. Реальность работа произошла, когда страницы DLL в конечном итоге были заменены. сырая страница была снесена с диска, затем исправления были применены к летать на необработанную страницу, тем самым перемещая ее. Фиксированная страница была затем отображается в адресное пространство процесса, и программа была разрешено продолжить.

Глядя на то, как этот процесс выполняется (читает все это), я лично подозреваю, что часть "перерегулирования зла" восходит к старым дням Win9x и условиям низкой памяти.


Посмотрите, теперь есть неисторическая часть в Old New Thing:

Насколько важно в настоящее время гарантировать, что все мои DLL файлы имеют неконфликтные базовые адреса?

В тот же день, одна из вещей, которую вы были призваны сделать, это перебазировать ваши библиотеки DLL, чтобы все они имели неперекрывающиеся диапазоны адресов, тем самым избегая затрат времени на перемещение. Это все еще важно в настоящее время?

...

При наличии ASLR перезагрузка ваших DLL не влияет, поскольку ASLR все равно будет игнорировать ваш базовый адрес и переместить DLL в местоположение своего псевдослучайного выбора.

...

Заключение: на всякий случай не повредить, но понять что выигрыш будет крайне редким. Создайте свою DLL с помощью /DYNAMICBASE включен (и с /HIGHENTROPYVA для хорошей меры) и пусть ASLR выполняет работу по обеспечению того, чтобы столкновение без базового адреса имеет место. Это будет охватывать практически все реальные сценарии. Если вы попали в один из очень редких случаев, когда ASLR недоступно, тогда ваша программа по-прежнему будет работать. Это может привести к немного медленнее из-за штрафа за перемещение.

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

Ответ 2

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

Стоимость этого не так проста в измерении, особенно на современных машинах с большим количеством ОЗУ. Он учитывается только тогда, когда машина начинает загружаться с большим количеством процессов, конкурирующих за память. И фрагментация файла подкачки.

Но, очевидно, перебазирование - очень дешевая оптимизация. И это очень легко увидеть в окне Debug + Windows + Modules, там есть яркая иконка на перезагруженных DLL. В столбце Address вы найдете хороший намек на то, какой базовый адрес будет хорошим выбором. Оставьте много места между ними, чтобы вам не приходилось постоянно настраивать его по мере роста вашей программы.

Ответ 3

Однако они не могут утверждать, что это ускоряет время загрузки приложения до какой-либо значительной суммы.

Изменение времени загрузки минимально, поскольку v-таблица обновляется с новыми адресами. Однако, если у вас низкая память - достаточно, чтобы материал загружался в/из файла страницы, система должна поддерживать DLL в файле страницы (поскольку эти адреса изменены). Если dlls были переустановлены - и переустановленные DLL не сталкивались с какой-либо другой dll - тогда вместо того, чтобы переставлять их в файл страницы (и обратно), система просто перезаписывает память и перезагружает dll из оригинала на жестком диске водить машину.

Преимущество имеет значение только в том случае, если системы представляют собой элементы подкачки в и из основной памяти. В последний раз, когда я делал попытки сохранить базы данных приложений и их базовые адреса, я вернулся в VB6 дней, когда компьютерам в наших офисах и центрах обработки данных повезло иметь даже 256 МБ ОЗУ.

Кроме того, с ASLR кажется сомнительным, что это имеет какое-либо значение вообще, поскольку в любом случае адреса загрузки будут рандомизированы.

В настоящий момент ASLR влияет только на DLL и исполняемые файлы с установленным флагом динамического переноса. Это включает в себя системные DLL Vista/Win7 и исполняемые файлы, а также любые разработчики, которые разработчик намеренно установил этот флаг во время сборки.

Если вы собираетесь установить флаг динамического перемещения, то не беспокойтесь о перезагрузке DLL. Если все ваши клиенты имеют 4 ГБ ОЗУ, то не беспокойтесь. Если ваш босс - дешевый, тогда, может быть.

Ответ 4

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

Для тех, кто загружен другими процессами, используется механизм копирования-записи. Таким образом, повторное перемещение будет означать дополнительные операции.

Что касается ASLR, он предназначен для целей безопасности, а не для производительности.

Ответ 5

Да, вы должны это сделать. ASLR влияет только на "системные" DLL, и поэтому те, которые вы пишете, не должны подвергаться воздействию ASLR. Кроме того, ASLR не полностью "рандомизирует" местоположение этих системных двоичных файлов, он просто перемещает их в основном месте на карте vm.