.NET SDK中CorFlags.Exe的用法

CorFlags .NET Framework 中一个用于查看.NET 可执行文件(PE) 的运行参数的 非常有用的工具,但是这个工具输出的结果不是特别直观,文档中并没有做出解释,本文将用实际例子解释CORFLAGS 的用法。
首先我们来看一个一般的情况,随便写一个A.CS 文件,用CSC 编译,并用CorFlags 察看
> csc a.cs
> corflags a.exe

Microsoft (R) .NET Framework CorFlags Conversion Tool.Version2.0.50727.42

Copyright (c) Microsoft Corporation.All rights reserved.

Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags: 1
ILONLY : 1
32BIT : 0
Signed : 0
先解释一下每一项的意义:
项目
含义
对应
Version
Assembly 所对应的 Framework 版本
IMAGE_COR20_HEADER.dwMajorRuntimeVersion
IMAGE_COR20_HEADER.dwMinorRuntimeVersion
CLR Header
CLR 文件头的版本号
IMAGE_COR20_HEDER.MetaData
PE
PE 文件的类型,包含 PE32/PE32+
Magic=

IMAGE_NT_OPTIONAL_HDR32_MAGIC or

IMAGE_NT_OPTIONAL_HDR64_MAGIC
CorFlags
IMAGE_COR20_HEADER.Flags
CorFlags 根据这个值来解析下面的选项
ILONLY
是否仅仅包含 IL 代码, 0/1
COMIMAGE_FLAGS_ILONLY=0x1
32 BIT
是否仅以 32BIT 运行, 0/1
COMIMAGE_FLAGS_32BITREQUIRED=0x2
Signed
是否经过签名

COMIMAGE_FLAGS_STRONGNAMESIGNED =0x8

PE 文件的类型需要解释一下,Windows PE 文件也就是可执行文件,存在两种类型(以前还有LE 等等,已淘汰):PE32 PE32+
PE32 是既可以在32 位下运行,也可以在64 位下运行,而PE32+ 只能在64 位下面运行。这里有一点需要澄清的是,普通的PE32 文件,如果里面代码有非托管代码,那么只能以32 位运行,不管是在32 Windows 还是64 位的Windows 。但是如果PE32 中仅含有托管代码,那么在64 Windows 下面则可以以64 位运行,因为CLR 可以将托管代码编译为64Bit 并运行,并且将其作为PE32+ 对待。
对应不同的平台的托管代码对应的CorFlags 的结果是不一样的。
平台
PE32/PE32+
IL Only?
32-Bit?
Any CPU
PE32
1
0
Pure x86
PE32
1
1
Pure x64
PE32+
1
0
Mixed x86
PE32
0
0
Mixed x64
PE32+
0
0
Pure 指纯托管程序,而Mixed 指混合。
Any CPU 必然只能是IL Only ,不能含有平台相关的非托管代码。而x86 AnyCPU 一样,都是PE32 文件,区别在于文件头上的32-Bit 的标志设置为1 ,表明其只能以32-Bit 运行。X64 则必然是PE32+ ,可以包含64 位非托管代码。
举一个例子:

> corflags C:\windows\microsoft.net\Framework\v2.0.50727\System.dll

Microsoft (R) .NET Framework CorFlags Conversion Tool.Version2.0.50727.42

Copyright (c) Microsoft Corporation.All rights reserved.

Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags: 9
ILONLY : 1
32BIT : 0
Signed : 1

可以看到我机器上面32Bit.NET Framework 2.0 RTM版本里面的System.DLL是对应v2.0.50727版本的,属于PE32文件,是IL Only,不是32Bit的,因此这个是用AnyCPU来编译的。Corflags = 9 = COMIMAGE_FLAGS_ILONLY (1) + COMIMAGE_FLAGS_STRONGNAMESIGNED (8)

最后我们来看一个混合托管代码和非托管代码的例子:
>cl /clr a.cpp

Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762

for Microsoft (R) .NET Framework version 2.00.50727.1416

Copyright (C) Microsoft Corporation.All rights reserved.

a.cpp

Microsoft (R) Incremental Linker Version 8.00.50727.762

Copyright (C) Microsoft Corporation.All rights reserved.

/out:a.exe
a.obj
> corflags a.exe

Microsoft (R) .NET Framework CorFlags Conversion Tool.Version2.0.50727.42

Copyright (c) Microsoft Corporation.All rights reserved.

Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags: 0
ILONLY : 0
32BIT : 0
Signed : 0

可以看到用/CLR编译选项编译出来的C++/CLI的代码总是混合的,因此是 ILONLY=0,值得注意的是其32BIT=0,说明当ILONLY=0的时候,CLR不需要32BIT=0就可以判断出这个PE32文件必然要在32BIT下面运行。

CorFlags 除了可以输出这些信息之外,还可以一定程度上修改这些信息,用法比较简单,只要了解各个输出的含义就可以了。但是除非对相关信息的含义以及对目标程序非常了解,一般情况下最好不要修改这些信息,以避免出现无法预料的问题。

作者: 张羿(ATField)
Blog:
http://blog.csdn.net/atfield
http://blogs.msdn.com/yizhang
转载请注明出处

你可能感兴趣的:(C++,c,.net,windows,Microsoft)