Как CorFlags.exe / 32BIT + работа?
Я думаю, мой вопрос про CLR загрузчика. Я хочу понять механикуCorFlags.exe /32BIT+
функциональность.
мы знаем, что при запуске сборки, скомпилированной с помощью любой ЦП флаг установлен на 64-разрядной Windows, он начинается как 64-разрядный процесс. Если один CorFlags /32BIT+
в этой сборке он начнется как 32-разрядный процесс. Я думаю, что это интересная особенность.
у меня так много вопросов о это:
- как это реализовать?
- участвует ли загрузчик ОС?
- можно ли создать пользовательское приложение (я думаю, неуправляемое), которое загружает 32-битную или 64-битную CLR по желанию?
есть ли статья, книга, блог и т. д., которые объясняют внутреннюю работу этой функции?
2 ответов
Это не хорошо документировано в любом месте, о котором я знаю, я могу только указать вам на соответствующую статью MSDN. Да, ваше предположение верно, загрузчик в Windows XP и выше имеет осведомленность об управляемых исполняемых файлах. Он автоматически загружает оболочку загрузчика .NET (c:\windows\system32\mscoree - ... dll), соответствующей точкой входа является _CorValidateImage (). Раздел Примечания в связанной статье MSDN описывает механизм, который превращает 32-разрядный .exe-файл в 64-разрядный процесс:
в Windows XP и более поздних версиях загрузчик операционной системы проверяет наличие управляемых модулей, изучая бит каталога дескриптора COM в заголовке common object file format (COFF). Бит set указывает на управляемый модуль. Если загрузчик обнаруживает управляемый модуль, он загружает MsCorEE.dll и вызывает _CorValidateImage, который выполняет следующие действия:
- подтверждает, что образ является допустимым управляемым модулем.
- изменение точка входа в образ в точку входа в общеязыковой среде выполнения (CLR).
- для 64-разрядных версий Windows изменяет изображение, которое находится в памяти, преобразуя его из PE32 в формат PE32+.
- возвращается в загрузчик при загрузке образов управляемого модуля.
для исполняемых образов загрузчик операционной системы вызывает Функция _CorExeMain, независимо от точки входа, указанной в исполняемом файле. Для образов сборки DLL, загрузчик вызывает _CorDllMain функция.
_CorExeMain или _CorDllMain выполняет следующие действия:
- инициализирует CLR.
- находит управляемую точку входа из заголовка CLR сборки.
- начинает выполняться.
загрузчик вызывает функцию _CorImageUnloading при управляемом модуле изображения выгружаются. Однако, эта функция не выполняет действие; это просто возвращается.
чтобы добавить ответ Ханса, есть также код режима ядра Windows, который отвечает на этот флаг. Каждый загруженный исполняемый файл имеет структуру ядра, SECTION_IMAGE_INFORMATION
, связанные с ним. Вот его информация о символе:
0: kd> dt nt!_SECTION_IMAGE_INFORMATION
+0x000 TransferAddress : Ptr64 Void
+0x008 ZeroBits : Uint4B
+0x010 MaximumStackSize : Uint8B
+0x018 CommittedStackSize : Uint8B
+0x020 SubSystemType : Uint4B
+0x024 SubSystemMinorVersion : Uint2B
+0x026 SubSystemMajorVersion : Uint2B
+0x024 SubSystemVersion : Uint4B
+0x028 GpValue : Uint4B
+0x02c ImageCharacteristics : Uint2B
+0x02e DllCharacteristics : Uint2B
+0x030 Machine : Uint2B
+0x032 ImageContainsCode : UChar
+0x033 ImageFlags : UChar
+0x033 ComPlusNativeReady : Pos 0, 1 Bit
+0x033 ComPlusILOnly : Pos 1, 1 Bit
+0x033 ImageDynamicallyRelocated : Pos 2, 1 Bit
+0x033 ImageMappedFlat : Pos 3, 1 Bit
+0x033 BaseBelow4gb : Pos 4, 1 Bit
+0x033 Reserved : Pos 5, 3 Bits
флаги ComPlusILOnly
и ComPlusNativeReady
связаны с .NET,ComPlusILOnly
просто сообщает, Является ли сборка CIL только (не смешанный или родной - в этом случае сборка уже специфична для архитектуры) и ComPlusNativeReady
равно 1, только если /32BIT+ не установлен (32BITREQ или 32BITPREF в более новой версии CorFlags). Эти флаги проверяются во время nt!PspAllocateProcess
и на их основе a 32-bit
или процесс идет.
я писал об этом С некоторыми деталями.