为Windows编写跨平台(32位和64位兼容)程序(如.NET中的AnyCPU)

为Windows编写跨平台(32位和64位兼容)程序(如.NET中的AnyCPU),.net,winapi,cross-platform,executable,portable-executable,.net,Winapi,Cross Platform,Executable,Portable Executable,NET中的“AnyCPU”功能是如何工作的一直困扰着我:如果系统是32位的,它将可执行文件作为本机32位加载,如果系统是64位的,它将作为64位加载(您可以很容易地通过任务管理器确认)。所以很明显,这不是不可能的 问题是,微软究竟是如何做到这一点的?Windows最初不知道.NET framework,因此Windows PE加载程序不可能在PE头中查找CLR头的任何额外功能;此功能必须是通过某种内核模式扩展添加的。但是.NET框架似乎没有安装这样的东西。。。我完全不知道同一个可执行文件如何可以

NET中的“AnyCPU”功能是如何工作的一直困扰着我:如果系统是32位的,它将可执行文件作为本机32位加载,如果系统是64位的,它将作为64位加载(您可以很容易地通过任务管理器确认)。所以很明显,这不是不可能的

问题是,微软究竟是如何做到这一点的?Windows最初不知道.NET framework,因此Windows PE加载程序不可能在PE头中查找CLR头的任何额外功能;此功能必须是通过某种内核模式扩展添加的。但是.NET框架似乎没有安装这样的东西。。。我完全不知道同一个可执行文件如何可以同时是本机32位和64位,特别是因为mscoree.dll的反汇编甚至不显示对未记录本机函数的引用

是否有人知道和/或合理猜测这是如何做到的?这显然是可能的(所以不要说“这不可能”),这让我想尝试编写一个本机跨平台的EXE


编辑:


作为一个旁注,考虑如何在64位Windows PE环境中不能运行32位可执行文件…一定有办法用某种“插件”来扩展或修改PE加载程序,对吧?

你的问题是基于误解。这里有一个错误:

Windows最初不知道.NET框架

实际上,自从Windows XP以来。XP是第一个支持64位的Windows版本

因此PE头标记为32位,本机导入表引用32位的mscoree,在Windows 2000及更早版本上,它导致加载32位的.NET
DllMain
for
mscoree
开始JITting应用程序代码并修改主应用程序的入口点

Windows XP及更高版本意识到.NET元数据,识别出它是
AnyCPU
,并加载相应的框架


因此,没有本机的
AnyCPU
exe。虽然您可以在32位PE中嵌入16位DOS程序,但您不能同时拥有32位和64位.exe。如果系统具有WOW64仿真层(Windows Vista+,不知道XP),那么您实际上可以在x86可执行文件中包含x64代码

我已经测试了这项技术,它可以在Win7和WinVista上运行。我在汇编中编写了一个小存根来解析导入并加载一些为AMD64编译的C代码


微软只是说你不能来回转换,因为他们可能会改变它,但我怀疑这会改变,直到底层架构改变,允许128位这样的东西运行。。。此时,我怀疑WOW64是否会出现:),WOW128 ftl。

有一些程序(例如Process Explores)可以做到这一点,如果可能的话,可以发布一个32位可执行文件,启动一个64位映像。例如,“AnyCPU”可执行文件除了32位PE之外还有其他功能吗?@pst:我完全知道这些功能,但不,它们是不同的。任何CPU可执行文件从64位操作系统上启动的那一刻起就是64位的——没有解包,也没有什么像“让我们将字节码JIT成64位,然后重新启动64位进程。”这让我感到困惑。XP发布后,.NET framework不是出现了吗(至少,我记得是这样的)?我想,…@Lambert:开发周期重叠,.NET开发在2002年首次发布之前大约5年就开始了,所以微软有足够的时间将钩子放到XP中。正如我所说,Windows 2000只有32位。无论如何,这是Windows XP 64位版本的发布日期,几年后,你应该考虑,因为它是第一个需要这种“魔力”的版本。啊。。。这就解释了。(是的,很抱歉,在你发布之前,我删除了关于我评论的Windows 2000部分,因为我记得它没有64位。)这不是我想要的答案,但看起来绝对正确;谢谢!:)@兰伯特:添加了两个链接,您可能会喜欢阅读以了解更多详细信息。@Ben:我已经阅读了第一个链接,但第二个是新的。起初,我以为这会告诉我关于WOW64 thunks的事情,幸好我没有抱怨我已经知道了这些,因为.NET信息绝对是新的和有用的。谢谢你发布这些!但愿我能再给你一个+1.:)