2012-04-30 38 views
10

我想我的問題是關於CLR加載程序。我想了解CorFlags.exe/32BIT+功能背後的機制。CorFlags.exe/32BIT +如何工作?

我們知道,當啓動一個使用編譯的程序集時,它將在64位Windows上設置任何CPU標誌,它將作爲64位進程啓動。如果在該程序集上運行CorFlags /32BIT+,則它將以32位進程啓動。我認爲這是一個有趣的功能。

我有這麼多的問題:

  1. 它是如何實現的?
  2. OS Loader是否涉及?
  3. 是否有可能建立一個自定義的應用程序(我猜是一個非託管的應用程序),希望加載32位或64位CLR?

是否有文章,書籍,博客等解釋此功能的內部運作?

回答

5

這在我所知的任何地方都沒有很好的記錄,我只能指出你的相關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函數。但是,此功能不執行任何 操作;它只是返回。

+0

感謝您的快速回答。這是一個很好的起點。我想知道clr如何處理.reloc部分。我在sscli中挖掘,主要是在pedecoder.h/pewriter.cpp中找到我的答案。仍然有很多問題(例如Windows 2000 x64),但我想我會在sscli中找到答案。 –

+0

這是一個簡單的,Windows 2000 x64最後被看到由偉大的白色雪人使用。 –

+1

哇。我想知道是否有任何方法可以利用這種「特殊意識」爲Windows創建適當的fat(本地代碼)二進制文件。 – Fowl

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 +時才爲1(32BITREQ or 32BITPREF in newer CorFlags version)。在nt!PspAllocateProcess期間檢查這些標誌,並基於它們創建32-bit64-bit進程。

I wrote about it有一些細節。

+0

非常感謝!我在使用Windows NT/2000 Native API Reference中的過時信息計算字段結構的某些偏移時感到困惑。 –