文章目錄
如何知道使用的 dll 是否需以 32 位元模式執行
最近因為年度計畫預計做些 Windows server OS 的升級作業,將大部份 OS 升級為 Windows Server 2016,也順便整理 server 上的 application,發現仍有不少 application 執行在 32 位模式下,過去主要的原因是 Oracle.DataAccess.dll
,原以為只要搞定 Oracle.DataAccess.dll
就可以,想不到後續又遇到其他參考的 dll 需要執行在 32 bit 模式下,所以找了幾個方式來試著不需要反覆部署至 IIS 上進行測試即可得知特定的 dll 是否需要執行在 32 bit 的相容執行環境
網路上分享的方法有很多種,今天會以本次遇到問題的 dll 中的 Oracle.DataAccess.dll
與 System.Data.dll
當做範例來進行測試,立馬來看看哪個方式比較方便吧
使用 dumpbin:無法識別是否需要 32 位元模式
曾經在之前筆記 如何看程式是 32 bit 還是 64 bit 紀錄到,詳細的使用方式可以參考原文 如何看程式是 32 bit 還是 64 bit
使用方式
dumpbin.exe /headers {檔案}
實際使用
System.Data.dll
需要 32 位元模式
$ "G:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\dumpbin.exe" /headers D:\Test\System.Data.dll Microsoft (R) COFF/PE Dumper Version 12.00.40629.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file D:\Test\System.Data.dll PE signature found File Type: DLL FILE HEADER VALUES 14C machine (x86) 5 number of sections 471EBF27 time date stamp Wed Oct 24 11:42:31 2007 0 file pointer to symbol table 0 number of symbols E0 size of optional header 2102 characteristics Executable 32 bit word machine DLL OPTIONAL HEADER VALUES 10B magic # (PE32) 8.00 linker version 2A4800 size of code 40800 size of initialized data 0 size of uninitialized data 2A4630 entry point (65114630) 1000 base of code 2A6000 base of data 64E70000 image base (64E70000 to 6515BFFF) 1000 section alignment 200 file alignment 5.00 operating system version 8.00 image version 4.10 subsystem version 0 Win32 version 2EC000 size of image 400 size of headers 2EDF46 checksum 3 subsystem (Windows CUI) 0 DLL characteristics 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit 0 loader flags 10 number of directories 2A5580 [ 1A2] RVA [size] of Export Directory 2A478C [ B4] RVA [size] of Import Directory 2AE000 [ 35F40] RVA [size] of Resource Directory 0 [ 0] RVA [size] of Exception Directory 0 [ 0] RVA [size] of Certificates Directory 2E4000 [ 4BCC] RVA [size] of Base Relocation Directory 1330 [ 1C] RVA [size] of Debug Directory 0 [ 0] RVA [size] of Architecture Directory 0 [ 0] RVA [size] of Global Pointer Directory 0 [ 0] RVA [size] of Thread Storage Directory 116D0 [ 40] RVA [size] of Load Configuration Directory 0 [ 0] RVA [size] of Bound Import Directory 1000 [ 2D8] RVA [size] of Import Address Table Directory 0 [ 0] RVA [size] of Delay Import Directory 110C4 [ 48] RVA [size] of COM Descriptor Directory 0 [ 0] RVA [size] of Reserved Directory
不需 32 位元模式
Dump of file D:\Test\System.Data_ok.dll PE signature found File Type: DLL FILE HEADER VALUES 14C machine (x86) 3 number of sections 4BA1E072 time date stamp Thu Mar 18 16:12:34 2010 0 file pointer to symbol table 0 number of symbols E0 size of optional header 2022 characteristics Executable Application can handle large (>2GB) addresses DLL OPTIONAL HEADER VALUES 10B magic # (PE32) 10.00 linker version 142600 size of code 800 size of initialized data 0 size of uninitialized data 142A7A entry point (615B2A7A) 2000 base of code 146000 base of data 61470000 image base (61470000 to 615B9FFF) 2000 section alignment 200 file alignment 4.00 operating system version 0.00 image version 4.00 subsystem version 0 Win32 version 14A000 size of image 200 size of headers 14ED98 checksum 3 subsystem (Windows CUI) 140 DLL characteristics Dynamic base NX compatible 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit 0 loader flags 10 number of directories 0 [ 0] RVA [size] of Export Directory 142A28 [ 4F] RVA [size] of Import Directory 146000 [ 434] RVA [size] of Resource Directory 0 [ 0] RVA [size] of Exception Directory 143000 [ 1758] RVA [size] of Certificates Directory 148000 [ C] RVA [size] of Base Relocation Directory 0 [ 0] RVA [size] of Debug Directory 0 [ 0] RVA [size] of Architecture Directory 0 [ 0] RVA [size] of Global Pointer Directory 0 [ 0] RVA [size] of Thread Storage Directory 0 [ 0] RVA [size] of Load Configuration Directory 0 [ 0] RVA [size] of Bound Import Directory 2000 [ 8] RVA [size] of Import Address Table Directory 0 [ 0] RVA [size] of Delay Import Directory 2008 [ 48] RVA [size] of COM Descriptor Directory 0 [ 0] RVA [size] of Reserved Directory
Oracle.DataAccess.dll
需要 32 位元
$ "G:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\dumpbin.exe" /headers D:\Test\Oracle.DataAccess.dll Microsoft (R) COFF/PE Dumper Version 12.00.40629.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file D:\Test\Oracle.DataAccess.dll PE signature found File Type: DLL FILE HEADER VALUES 14C machine (x86) 3 number of sections 48B315B4 time date stamp Tue Aug 26 04:27:32 2008 0 file pointer to symbol table 0 number of symbols E0 size of optional header 210E characteristics Executable Line numbers stripped Symbols stripped 32 bit word machine DLL OPTIONAL HEADER VALUES 10B magic # (PE32) 8.00 linker version DE000 size of code 2000 size of initialized data 0 size of uninitialized data DFD1E entry point (110DFD1E) 2000 base of code E0000 base of data 11000000 image base (11000000 to 110E3FFF) 2000 section alignment 1000 file alignment 4.00 operating system version 0.00 image version 4.00 subsystem version 0 Win32 version E4000 size of image 1000 size of headers E5C54 checksum 3 subsystem (Windows CUI) 540 DLL characteristics Dynamic base NX compatible No structured exception handler 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit 0 loader flags 10 number of directories 0 [ 0] RVA [size] of Export Directory DFCC4 [ 57] RVA [size] of Import Directory E0000 [ 460] RVA [size] of Resource Directory 0 [ 0] RVA [size] of Exception Directory 0 [ 0] RVA [size] of Certificates Directory E2000 [ C] RVA [size] of Base Relocation Directory 0 [ 0] RVA [size] of Debug Directory 0 [ 0] RVA [size] of Architecture Directory 0 [ 0] RVA [size] of Global Pointer Directory 0 [ 0] RVA [size] of Thread Storage Directory 0 [ 0] RVA [size] of Load Configuration Directory 0 [ 0] RVA [size] of Bound Import Directory 2000 [ 8] RVA [size] of Import Address Table Directory 0 [ 0] RVA [size] of Delay Import Directory 2008 [ 48] RVA [size] of COM Descriptor Directory 0 [ 0] RVA [size] of Reserved Directory
不需要 32 位元
$ "G:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\dumpbin.exe" /headers D:\Test\Oracle.DataAccess_ok.dll Microsoft (R) COFF/PE Dumper Version 12.00.40629.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file D:\Test\Oracle.DataAccess_ok.dll PE signature found File Type: DLL FILE HEADER VALUES 8664 machine (x64) 2 number of sections 4B9A20B6 time date stamp Fri Mar 12 19:08:38 2010 0 file pointer to symbol table 0 number of symbols F0 size of optional header 212E characteristics Executable Line numbers stripped Symbols stripped Application can handle large (>2GB) addresses 32 bit word machine DLL OPTIONAL HEADER VALUES 20B magic # (PE32+) 8.00 linker version F6000 size of code 1000 size of initialized data 0 size of uninitialized data 0 entry point 2000 base of code 11000000 image base (0000000011000000 to 00000000110F9FFF) 2000 section alignment 1000 file alignment 4.00 operating system version 0.00 image version 4.00 subsystem version 0 Win32 version FA000 size of image 1000 size of headers 1036BB checksum 3 subsystem (Windows CUI) 540 DLL characteristics Dynamic base NX compatible No structured exception handler 400000 size of stack reserve 4000 size of stack commit 100000 size of heap reserve 2000 size of heap commit 0 loader flags 10 number of directories 0 [ 0] RVA [size] of Export Directory 0 [ 0] RVA [size] of Import Directory F8000 [ 460] RVA [size] of Resource Directory 0 [ 0] RVA [size] of Exception Directory 0 [ 0] RVA [size] of Certificates Directory 0 [ 0] RVA [size] of Base Relocation Directory 0 [ 0] RVA [size] of Debug Directory 0 [ 0] RVA [size] of Architecture Directory 0 [ 0] RVA [size] of Global Pointer Directory 0 [ 0] RVA [size] of Thread Storage Directory 0 [ 0] RVA [size] of Load Configuration Directory 0 [ 0] RVA [size] of Bound Import Directory 0 [ 0] RVA [size] of Import Address Table Directory 0 [ 0] RVA [size] of Delay Import Directory 2000 [ 48] RVA [size] of COM Descriptor Directory 0 [ 0] RVA [size] of Reserved Directory
使用 CorFlags:個人測試下不一定可以識別是否需要 32 位元模式
CorFlags.exe
是 .net framework 的內建工具
判斷基準
platform PE 32BITREQ Any CPU PE32 0 x86 PE32 1 x64 PE32+ 0 實際使用
System.Data.dll
需要 32 位元模式
$ "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools\CorFlags.exe" d:\TEST\System.Data.dll Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.7.2558.0 Copyright (c) Microsoft Corporation. All rights reserved. Version : v2.0.50727 CLR Header: 2.5 PE : PE32 CorFlags : 0x18 ILONLY : 0 32BITREQ : 0 32BITPREF : 0 Signed : 1
不需要 32 位元模式
$ "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools\CorFlags.exe" d:\TEST\System.Data_ok.dll Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.7.2558.0 Copyright (c) Microsoft Corporation. All rights reserved. Version : v4.0.30319 CLR Header: 2.5 PE : PE32 CorFlags : 0x9 ILONLY : 1 32BITREQ : 0 32BITPREF : 0 Signed : 1
Oracle.DataAccess.dll
需要 32 位元模式
$ "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools\CorFlags.exe" d:\TEST\Oracle.DataAccess.dll Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.7.2558.0 Copyright (c) Microsoft Corporation. All rights reserved. Version : v2.0.50727 CLR Header: 2.5 PE : PE32 CorFlags : 0xb ILONLY : 1 32BITREQ : 1 32BITPREF : 0 Signed : 1
不需要 32 位元模式
$ "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools\CorFlags.exe" d:\TEST\Oracle.DataAccess_ok.dll Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.7.2558.0 Copyright (c) Microsoft Corporation. All rights reserved. Version : v2.0.50727 CLR Header: 2.5 PE : PE32+ CorFlags : 0x9 ILONLY : 1 32BITREQ : 0 32BITPREF : 0 Signed : 1
使用 powershell:勉強可識別是否需要 32 位元模式
ProcessorArchitecture
ProcessorArchitecture 說明 Amd64 僅 64-bit AMD 處理器適用 Arm ARM 處理器適用 IA64 僅 64-bit Intel 處理器適用. MSIL 不限處理器 None 無法辨識處理器 X86 32-bit Intel 處理器, 或是 64-bit 平台上 Windows on Windows 環境(WOW64). 實際使用
System.Data.dll
需要 32 位元模式
PS C:\Users\yowko.tsai> $dllpath="d:\TEST\System.Data.dll" [reflection.assemblyname]::GetAssemblyName($dllpath) | fl Name : System.Data Version : 2.0.0.0 CultureInfo : CultureName : CodeBase : file:///d:/TEST/System.Data.dll EscapedCodeBase : file:///d:/TEST/System.Data.dll ProcessorArchitecture : X86 ContentType : Default Flags : PublicKey HashAlgorithm : SHA1 VersionCompatibility : SameMachine KeyPair : FullName : System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
不需要 32 位元模式
PS C:\Users\yowko.tsai> $dllpath="d:\TEST\System.Data_ok.dll" [reflection.assemblyname]::GetAssemblyName($dllpath) | fl Name : System.Data Version : 4.0.0.0 CultureInfo : CultureName : CodeBase : file:///d:/TEST/System.Data_ok.dll EscapedCodeBase : file:///d:/TEST/System.Data_ok.dll ProcessorArchitecture : None ContentType : Default Flags : PublicKey HashAlgorithm : SHA1 VersionCompatibility : SameMachine KeyPair : FullName : System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Oracle.DataAccess.dll
需要 32 位元模式
PS C:\Users\yowko.tsai> $dllpath="d:\TEST\Oracle.DataAccess.dll" [reflection.assemblyname]::GetAssemblyName($dllpath) | fl Name : Oracle.DataAccess Version : 2.111.7.0 CultureInfo : CultureName : CodeBase : file:///d:/TEST/Oracle.DataAccess.dll EscapedCodeBase : file:///d:/TEST/Oracle.DataAccess.dll ProcessorArchitecture : X86 ContentType : Default Flags : PublicKey HashAlgorithm : SHA1 VersionCompatibility : SameMachine KeyPair : FullName : Oracle.DataAccess, Version=2.111.7.0, Culture=neutral, PublicKeyToken=89b483f429c47342
不需要 32 位元模式
PS C:\Users\yowko.tsai> $dllpath="d:\TEST\Oracle.DataAccess_ok.dll" [reflection.assemblyname]::GetAssemblyName($dllpath) | fl Name : Oracle.DataAccess Version : 2.112.1.0 CultureInfo : CultureName : CodeBase : file:///d:/TEST/Oracle.DataAccess_ok.dll EscapedCodeBase : file:///d:/TEST/Oracle.DataAccess_ok.dll ProcessorArchitecture : Amd64 ContentType : Default Flags : PublicKey HashAlgorithm : SHA1 VersionCompatibility : SameMachine KeyPair : FullName : Oracle.DataAccess, Version=2.112.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342
使用 c#:可識別是否需要 32 位元模式
實際使用
System.Data.dll
需要 32 位元模式
string dllpath = @"D:\Test\System.Data.dll"; Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllpath); assembly.ManifestModule.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine); peKind.Dump();
不需要 32 位元模式
string dllpath = @"D:\Test\System.Data_ok.dll"; Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllpath); assembly.ManifestModule.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine); peKind.Dump();
Oracle.DataAccess.dll
需要 32 位元模式
string dllpath = @"D:\Test\Oracle.DataAccess.dll"; Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllpath); assembly.ManifestModule.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine); peKind.Dump();
不需要 32 位元模式
string dllpath = @"D:\Test\Oracle.DataAccess_ok.dll"; Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllpath); assembly.ManifestModule.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine); peKind.Dump();
心得
方法乍看之下有好幾個,但實際使用上可以正確判讀出是否需要 32 bit 模式的並不多,嚴格說起來只有 PowerShell 跟 c# 的方法可以滿足要求,CorFlag 實際使用上有的 dll 可以正確判讀有的則不行,而 c# 與 PowerShell 相比,PowerShell 的訊息仍然相對模糊,c# 整體的訊息非常直覺,但 PowerShell 不用編譯的優點則是 C# 望塵莫及的
透過將幾個方式測試一輪順便紀錄,到時有需要就視情況取用即可,雖然花了一些時間,但日後再次用到時就划算了(應該)
參考資訊
文章作者 Yowko Tsai
上次更新 2021-11-03
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。