CorFlags.exe / 32BIT +如何工作?

时间:2012-04-30 19:55:01

标签: clr loader corflags

我想我的问题是关于CLR Loader。我想了解CorFlags.exe /32BIT+功能背后的机制。

我们知道当一个人启动使用64位Windows上设置的 Any CPU 标志编译的程序集时,它将以64位进程启动。如果在该程序集上运行CorFlags /32BIT+,它将以32位进程启动。我认为这是一个引人入胜的特征。

我有很多问题:

  1. 如何实施?
  2. 操作系统加载程序是否涉及?
  3. 是否可以构建一个自定义应用程序(我想是一个非托管应用程序),可以根据需要加载32位或64位CLR?
  4. 是否有文章,书籍,博客等解释了此功能的内部工作原理?

2 个答案:

答案 0 :(得分:6)

在我所知的任何地方都没有详细记录,我只能向您指出相关的MSDN文章。是的,您的假设是正确的,Windows XP及更高版本中的加载程序具有托管可执行文件的意识。它自动加载.NET加载程序填充程序(c:\ windows \ system32 \ mscoree.dll),相关入口点为_CorValidateImage()。链接的MSDN文章中的“备注”部分描述了将32位.exe文件转换为64位进程的机制:

  

在Windows XP及更高版本中,操作系统加载程序通过检查公共对象文件格式(COFF)标头中的COM描述符目录位来检查托管模块。设置位表示受管模块。如果加载程序检测到托管模块,它会加载MsCorEE.dll并调用_CorValidateImage,它会执行以下操作:

     
      
  • 确认该图像是有效的托管模块。
  •   
  • 将图像中的入口点更改为公共语言运行库(CLR)中的入口点。
  •   
  • 对于64位版本的Windows,通过将其从PE32转换为PE32 +格式来修改内存中的映像。
  •   
  • 加载托管模块映像时返回加载程序。
  •   
     

对于可执行映像,操作系统加载程序然后调用   _CorExeMain函数,与可执行文件中指定的入口点无关。对于DLL程序集图像,加载程序调用_CorDllMain   功能

     

_CorExeMain或_CorDllMain执行以下操作:

     
      
  • 初始化CLR。
  •   
  • 从程序集的CLR标题中找到托管入口点。
  •   
  • 开始执行。
  •   
     

加载程序在托管模块时调用_CorImageUnloading函数   图像被卸载。但是,此功能不执行任何操作   行动;它只是回归。

答案 1 :(得分:2)

为了补充Hans的答案,还有一些响应该标志的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

标志ComPlusILOnlyComPlusNativeReady与.NET相关,ComPlusILOnly只是告诉程序集是否仅CIL(不是混合或本机 - 在这种情况下是程序集已经是特定于体系结构的),并且ComPlusNativeReady仅在未设置/ 32BIT +(32BITREQ or 32BITPREF in newer CorFlags version)时为1。这些标记会在nt!PspAllocateProcess期间进行检查,并根据这些标记创建32-bit64-bit进程。

I wrote about it有一些细节。