Решил как то по шаманить над одним примером который нашёл в интернете При запуске там открывается модальное диалоговое окно из шаблона ресурса Код (ASM): invoke DialogBoxParam,hInstance,addr szDialogName,0,addr SetupDialog,0 Сам исполняемый файл примера работал как и положено Но когда я подставил код примера под свою компиляцию то обнаружил что при удачной компиляции исполняемый файл при запуске не открыл модальное окно Когда я стал разбиратся в чём дело то обнаружил что автор исходника значение дескриптора модуля - hInstance просто прописал в сегменте данных Код (ASM): .data hInstance dd 400000h .code Я вспомнил что в некоторых старых публикациях иногда предлагали это значение так как оно всегда одно и тоже смело ставить под - 400000h Как я потом понял автор исходника использовал линковщик - Link.exe не выше девятой версии - Microsoft Visual Studio 9.0 а может быть и ещё старее Линковщики этих версий всегда ставят дескриптор модуля под одно и тоже значение - 400000h Наверное автор исходника и творил в это незабвенное время Я пользуюсь пакетом сборки 14 версии - Microsoft Visual Studio 14.0 Смысл в том что линковщики начиная с десятой версии значение дескриптора модуля при каждой сборке ставят разное Интересно что для обычных окон это значение вроде бы не так важно а вот для мадального окна оно оказалось очень важным наверное потому что для использования шаблона из файла ресурсов нужно правильное значение дескриптора модуля по этому лучше всего это значение всегда инициализировать при помощи Код (ASM): invoke GetModuleHandle,0 mov hInstance,eax Я понимаю что в подобную ситуацию можно попасть крайне редко я также понимаю что многие об этом прекрасно знают но всё же просто решил расказать об особенностях версий линковщиков
Вообще-то в линкере есть ключ /BASE:{address|@filename,key}, который может быть использован при линковке для установления необходимого ImageBase программы (значение должно быть кратно 64k hex).
assch, есть такой волшебный ключик /BASE, добавь в bat-файл для сборки ЕХЕ "/BASE:0x400000" и будет тебе щастья даже с link.exe версии выше десятой, блин, пока набирал, уже подбросили совет
Решил попробывать добавить ключ - BASE:0x400000 Код (ASM): \masm32\bin\Link.exe /BASE:0x400000 /SUBSYSTEM:WINDOWS asm.obj rc.obj но при проверке Код (ASM): invoke GetModuleHandle,0 mov hInstance,eax hInstance - всё равно значение не получается (400000h) а получается разным Может я не правильно прописал этот ключ
assch, У вас походу говно в голове, не иначе. Дескриптор это аппаратный обьект. Например дескриптор прерывания - запись в дескрипторной таблице. Описатель или handle, это локальное в процессе значение, через которое адресуются обьекты. Какой либо адрес не является описателем, это просто значение. Учите матчасть, прежде чем что то кодить.
Протестировал линкеры (Link.exe) версий - 5,7,8,9,10,11,12,14 Оказалось линкеры девятой серии и ниже как и советовали прекрасно понимают ключ - /BASE:{ } ради интереса адрес базы прописал - 800000h Код (ASM): \masm32\bin\Link.exe /BASE:0x800000 /SUBSYSTEM:WINDOWS asm.obj rc.obj в итоге при проверке Код (ASM): invoke GetModuleHandle,0 mov hInstance,eax значение адреса базы (hInstance) получается так как и прописано было в ключе - 800000h Но линкеры выше девятой серии запись этого ключа записанного этим способом игнорируют то есть значение адреса базы (hInstance) получается всегда разное Или ключ в этих версиях нужно прописывать синтаксически как то по другому или в этих версиях этот ключ попросту игнорируется
В архивном файле два экзешника первый сделан старым линкером второй новым каждый показывает адрес базы только первый открывает окно а второй нет Честно говоря вроде бы понял что - ASLR по умолчанию включен тогда как его отключить или я что то напутал Прошу прощения за непонятки По ошибке привязал два одинаковых файла
Немного прочитал про - ASLR ASLR (англ. address space layout randomization — «рандомизация размещения адресного пространства») Как я понимаю это технология для некоторой защиты от взлома видимо по этому новые линкеры игнорируют этот ключ
assch, да, в образе установлены флаги IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE и IMAGE_DLLCHARACTERISTICS_NX_COMPAT. Первый флаг как раз и отвечает за ASLR. Чтобы оключить ASLR используй ключ /DYNAMICBASE:NO
Большое спасибо Thetrik за объяснения Эту запись нужно прописать если при линковке надо просто отключить - ASLR Код (ASM): \masm32\bin\Link.exe /DYNAMICBASE:NO /SUBSYSTEM:WINDOWS asm.obj rc.obj по умолчанию базовый адрес будет - 400000h а если нужен другой адрес (кратный 64 кб) например - 800000h то Код (ASM): \masm32\bin\Link.exe /BASE:0x800000 /DYNAMICBASE:NO /SUBSYSTEM:WINDOWS asm.obj rc.obj Ещё раз спасибо Век живи век учись