Базовый адрес по умолчанию для .exe
, созданного в Visual Studio, - 0x00400000.
Базовый адрес по умолчанию для d3dx9_30.dll
и odbcint.dll
(которые находятся в %windir%\system32
) также 0x00400000. Таким образом, по умолчанию exe
s, которые ссылаются на любую из этих 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 резервирует эту память во время загрузки; мой отладочный фу недостаточно силен, чтобы определить, что, почему и когда именно.