Перебазирование - не удается заставить odbcint.dll загружаться на предпочитаемой базе

Базовый адрес по умолчанию для .exe, созданного в Visual Studio, - 0x00400000.

Базовый адрес по умолчанию для d3dx9_30.dll и odbcint.dll (которые находятся в %windir%\system32) также 0x00400000. Таким образом, по умолчанию exes, которые ссылаются на любую из этих dll, будут иметь конфликт адресов времени выполнения. ОС автоматически перемещает dll на другие базовые адреса и исправляет указатели по мере необходимости, и я могу видеть это, когда подключаю отладчик VS: перемещенный модуль получает наложение восклицательного значка.

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

Если я изменю свой клиентский EXE на другой базовый адрес, чтобы убрать его с пути d3dx9_30.dll, он будет работать нормально: без конфликтов адресов, без перемещения, без исправлений.

Но если я изменю свои серверные EXE-файлы на другой базовый адрес, чтобы убрать их с пути odbcint.dll, это не сработает.

odbcint.dll составляет 0x17000 байт в памяти и предпочитает базовый адрес 0x00400000. Я попытался установить свои EXE на 0x00420000, а затем на 0x00660000. Тем не менее odbcint.dll перемещается во время выполнения. Я провел профилирование с помощью depends.exe, который показал, что ни один другой модуль не пытается запросить этот адрес до загрузки odbcint.dll.

Есть ли у кого-нибудь теория, объясняющая, почему я не могу заставить odbcint.dll загрузиться по его предпочтительному адресу?

Update: vadump показывает, что к моменту, когда я вхожу в main (), память по адресу 0x00400000-0x00470000 запрашивается как UNKNOWN_MAPPED. Мне не удалось найти дополнительную информацию о том, что именно это означает. Я предполагаю, что некоторая системная dll резервирует эту память во время загрузки; мой отладочный фу недостаточно силен, чтобы определить, что, почему и когда именно.


person Tim Sparkles    schedule 17.04.2009    source источник


Ответы (1)


Если вы загружаете VADump (доступный в Windows Resource Kit:), вы можете точно увидеть, какой модуль попадает на эти страницы и заставляет его пропустить свой адрес. (Запустите vadump -op pid.)

Вы не сказали, над какой ОС вы работаете, но в Vista / 2K8 + вам также следует знать о ASLR.

person Bill Wert - MSFT    schedule 19.04.2009
comment
Тимбо, если тебе нравится ответ, выберите его как лучший ответ. - person Steve Rowe; 09.07.2009
comment
Это полезно и продвинуло меня дальше по пути к решению, но мой вопрос остается без ответа. Обратите внимание на обновление в исходном вопросе. - person Tim Sparkles; 30.09.2009