Как CorFlags.exe / 32BIT + работа?

Я думаю, мой вопрос про CLR загрузчика. Я хочу понять механикуCorFlags.exe /32BIT+ функциональность.

мы знаем, что при запуске сборки, скомпилированной с помощью любой ЦП флаг установлен на 64-разрядной Windows, он начинается как 64-разрядный процесс. Если один CorFlags /32BIT+ в этой сборке он начнется как 32-разрядный процесс. Я думаю, что это интересная особенность.

у меня так много вопросов о это:

  1. как это реализовать?
  2. участвует ли загрузчик ОС?
  3. можно ли создать пользовательское приложение (я думаю, неуправляемое), которое загружает 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 или процесс идет.

я писал об этом С некоторыми деталями.