Загрузчик указывает, а берет из EXE, а в EXE это указывает компоновщик(linker) и адрес этот в нем можно менять.
Для программиста, разрабатывающего софт на высокоуровневых языках, хороший ответ, больше вопросов не имею) Это значение - ImageBase в IMAGE_NT_HEADERS, правда, он изменяться может, если файл имеет таблицу перемещаемых элементов. В этом случае загрузчик может разместить файл по любому доступному адресу и скорректировать некоторые значения в памяти, руководствуясь этой таблицей, если этот адрес не равен ImageBase. Такое практически всегда происходит с dll-файлами.
А как это противоречит моисм словам? Оно берется из ImageBase и почти всегда с ним совпадает. НО в редких случаях загрузчик может переместить модуль в памяти (поэтому он и называется Portable Executable) с использованием Relocation Table. P.S. Я не гуглю)
Ну, вы сказали, что нет вообще никакой структуры там, и в то же время там проекция PE. Противоречие есть) В предыдущем посте дописал, когда.
Я искал в вашем вопросе подъ***у, поэтому в первую очередь подумал о рантаймовых структурах. А так конечно вы правы. Про DLL справедливо не всегда. Некоторые системные библиотеки грузятся всегда по одному адресу. К тому же (тут я могу ошибаться), существует способ явно указать загрузчику куда грузить модуль
Чаще всего происходит перемещение dll, потому что первым грузится сам exe файл, а после него dll'ки, из которых он импортирует функции, и адрес 0x400000, который так все любят ставить как ImageBase, может быть уже занят. Ну или одна дллка загрузилась по некоторому адресу, а следующая за ней уже не может быть загружена по нему же. DLL всегда должны иметь таблицу перемещаемых элементов, чтобы 100% успешно загрузиться. Существует - просто записать в IMAGE_NT_HEADERS, что файл не имеет перемещаемых элементов, тогда загрузчик будет вынужден грузить файл по ImageBase)
К моменту загрузки EXE в памяти уже присутствуют как минимум ntdll.dll и Kernel32.dll, из последней кстати и вызывается EntryPoint. Не, я где-то слышал именно про программный способ. Хотя, повторюсь, возможно я и ошибаюсь.
Загрузчик вызывает для вашей программы LoadLibrary для всех импортируемых библиотек. Но для Kernel32.dll LoadLibrary возвратит адрес практически мгновенно, так как она уже загружена. Пруф UPD. По материалам этой статьи можно написать EXE у которого вообще не будет таблицы импорта.
Хех, скриншот выше как раз сделал с MessageBox'а, выводимого программой без импорта) А список загруженных модулей по порядку загрузки взят из Process Environment Block. Ну так сначала же надо сам exe загрузить, вдруг там вообще структуры имеют недопустимые значения в полях, LoadLibrary заранее-то зачем делать)
Значит не будете отрицать что кернел уже присутствует в памяти к моменту старта программы? Сначала загружается EXE, потом загрузчик проходит по таблице импорта, здесь все верно. Но сам загрузчик уже находится в памяти
kernel32.dll проецируется в адресное пространство всех процессов в системе, поэтому она там будет еще до загрузки. Мы уже ушли в глубокий оффтоп, давайте завязывать
Отпишу последнее слово) На васме том же вот здесь http://www.wasm.ru/forum/viewtopic.php?pid=375916 приведен кусочек кода: Code: NTSTATUS LdrpInitializeProcess(CONTEXT* Context, HMODULE SystemDllBase) { ... IMAGE_NT_HEADERS* NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress); ... if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI || NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) { status = LdrLoadDll(Kernel32DllName, &KernelHandle); if (SUCCEEDED(status)) { LdrGetProcedureAddress(Kernel32Handle, Kernel32ThreadInitThunkName, &Kernel32ThreadInitThunk); // "BaseThreadInitThunk" LdrGetProcedureAddress(Kernel32Handle, Kernel32BaseQueryModuleDataName, &Kernel32BaseQueryModuleData); // "BaseQueryModuleData" } #if NTDDI >= NTDDI_WIN7 if (status == STATUS_DLL_NOT_FOUND) status = LdrLoadDll(KernelBaseDllName, &KernelHandle); #endif if (FAILED(status)) ... } ... из которого видно, что kernel32 (или kernelbase) грузится только после проверки подсистемы нашего exe, который, соответственно, к этому моменту должен быть в памяти уже (RtlImageNtHeader как раз принимает значение HINSTANSE (HMODULE) нашего exe). И не всех процессов, а только с подсистемой IMAGE_SUBSYSTEM_WINDOWS_GUI или IMAGE_SUBSYSTEM_WINDOWS_CUI, как опять-таки видно из кода.
Пля, народ ну вы даете. Начали за здравие закончили за упокой. 2 GRRRL Power нах ты так дале полез? МОжет давай вообще полезим в Shadow SDT чтобы поглядеться что там делает CreateWindows? И подкрепим всё исходниками из WRK. А нехера, вы ошиблись. в w7 вместо kernel32 там торчит kernelbase. Заугукали флудить. Тему закрываю. Следующий раз по сношу все сообщения. Хочется пообсуждать идите в чат