在64位windows上存在着32位和64位两个版本的clr。本文介绍如何通过clr自带的工具(ldr64.exe/corflags.exe)指定托管程序“寄宿”的clr版本,并且和大家分享笔者研究这两个工具运作机理的过程以及使用的“秘密武器”(procmon/dumpbin)。
在过去的一年中,我的工作环境从32位windows(尽管cpu是64位的)渐渐迁徙到64位windows。在64位windows上安装的.NET会有两个分支,分别针对32位和64位环境,其主要的dll分别存储在了以下位置:
C:/Windows/Microsoft.NET/Framework/v2.0.50727/mscorwks.dll
C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorwks.dll
根据具体的.Net版本,上述路径中的版本号会有些微的差别。尽管两个clr的表现基本一致,但是由于工作平台的差别,也只能是求同存异。最明显的差别是:JIT出来的代码不同,一个是32位的本地代码,而另一个是64位的。
这就带来了一个问题,托管程序的到底是在哪一个clr中运行的呢?32位还是64位?在这里介绍两个工具,从不同的粒度上决定了32位clr还是64位clr。
1. ldr64.exe:在这里我特地强调了.exe,是因为臭名昭著的特洛伊木马ldr64.dll。大家以后看到这个名字的时候先不要兴奋,看清楚后缀再做打算。
ldr64的语法很简单,后面跟一个参数,只有两个可能的值,分别是set64和setwow。其意义很直接:ldr64 set64表示用64位的clr,ldr64 setwow表示用32位的clr。(如果你在诧异为什么不是ldr64 set32而是ldr64 setwow,那么我很荣幸的讲一个小故事:wow是windows on windows的简称,当64位的windows发布时,为了兼容32位windows,发明了wow这个概念,不过事实证明这个名字很容易引起歧义。)
ldr64是一个粒度很大的命令,具有全局影响。举例来说,在一个命令行窗口运行了ldr64以后,不管是从该命令行窗口还是其外的其他环境启动一个托管程序,都会遵照之前ldr64设定的结果。当然,也有例外:
2. corflags
corflags是修改托管二进制程序的工具。最常见的用法是corflags /32bit+ a.exe。其中,a.exe是托管程序的文件名,/32bit+是用来指定32位的运行时,与之相对的是/32bit-,其功能是取消该程序对32位运行时的绑定,可以通过32位或者是64位运行时运行。
到这里,我小结一下前面讲过的东西好让仅仅抱着解决问题而来的朋友们满意而去,ldr64.exe和corflags两个工具从不同的粒度指定32位或是64位运行时。而且一如我们的常识,当两者冲突的时候,力度小的工具corflags具有更高优先级。
接下来,我们来使用一些秘密武器,进一步了解ldr64.exe和corflags的工作原理。首先,请大家打开procmon(http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx)(这套工具是由在os界具有传奇色彩的Mark开发,Mark以前一直通过逆向工程的方法了解windows甚至是抨击windows,但是现在已经成为了windows团队中的一员,以后有机会我给大家好好八卦一下mark的传奇)。
在procmon中添加一个filter来观察ldr64.exe的行为,如图所示。
然后,运行C:/Windows/Microsoft.NET/Framework64/v2.0.50727/ldr64.exe setwow,观察procmon,发现一个很有趣的行为,如下图所示,
对了,ldr64所做的事情,就是修改这个这册表项。
接着,来看corflags。由于corflags操作的对象托管程序,而托管程序本身是一个二进制文件,所以祭出dumpbin。对一个任意的托管程序(假设a.exe),在执行corflags /32bit+ 和/32bit-之后,用dumpbin产生人类可以看懂的描述,进而比较其不同。操作如下所述:
corflags /32bit+ a.exe
dumpbin /all a.exe > 32.dmp
corflags /32bit- a.exe
dumpbin /all a.exe > any.dmp
windiff 32.dmp any.dmp
注:windiff是笔者手头的文件比较器,看官们可随意选用自己称手的比较器取而代之。
比较结果如图所示,corflags的效果一目了然:
/32bit+设置了托管程序的clr头,增添了一个需要32位运行时的要求。而/32bit-则做了相反的事情,把之前的置位复原。
今天借了ldr64.exe和corflags的机会,介绍了两个小工具procmon和dumpbin的使用,许多程序高手手边都有这些小巧玲珑但是功能强大的工具,从而事倍功半。