Базовый адрес по умолчанию для .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 резервирует эту память во время загрузки; мой отладочный фу недостаточно силен, чтобы определить, что, почему и когда именно.