我想我的问题是关于CLR装载机。我想了解CorFlags.exe /32BIT+功能背后的机制。
我们知道,当启动使用64位Windows上设置的任意CPU标志编译的程序集时,它从64位进程开始。如果在该程序集上运行CorFlags /32BIT+,它将作为32位进程启动。我觉得这是个迷人的特征。
我对此有很多疑问:
是否有一篇文章、书籍、博客等解释了这一特性的内在运作?
发布于 2012-05-01 01:09:24
这在我所知道的任何地方都没有很好的记录,我只能向您指出一篇相关的MSDN文章。是的,您的假设是正确的,Windows和up中的加载程序知道托管可执行文件。它自动加载.NET加载器shim (c:\windows\system32\mscoree.dll),相关的切入点是CorValidateImage()。链接的MSDN文章中的备注部分描述了将32位.exe文件转换为64位进程的机制:
在Windows XP和更高版本中,操作系统加载程序通过检查公共对象文件格式(COFF)头中的COM描述符目录位来检查托管模块。集合位指示托管模块。如果加载程序检测到托管模块,它将加载MsCorEE.dll并调用_CorValidateImage,后者执行以下操作:
对于可执行映像,操作系统加载程序然后调用_CorExeMain函数,而不考虑可执行文件中指定的入口点。对于DLL程序集映像,加载程序调用_CorDllMain函数。
_CorExeMain或_CorDllMain执行以下操作:
卸载托管模块映像时,加载程序调用_CorImageUnloading函数。但是,此函数不执行任何操作;它只是返回。
发布于 2015-04-18 19:10:23
要添加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标志ComPlusILOnly和ComPlusNativeReady与.NET相关,ComPlusILOnly只告诉程序集是否仅为CIL (不是混合的还是本机的--在这种情况下,程序集已经是特定于体系结构的),而ComPlusNativeReady只有在没有设置/32BIT+ (更新的CorFlags版本中的32 32BITREQ或32 32BITPREF)的情况下才是1。在nt!PspAllocateProcess期间检查这些标志,并根据这些标志创建32-bit或64-bit进程。
我写的提供了一些细节。
https://stackoverflow.com/questions/10389756
复制相似问题