为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)
Posted
技术标签:
【中文标题】为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)【英文标题】:Writing a Cross-Platform (32-bit and 64-bit compatible) Program for Windows (like AnyCPU in .NET) 【发布时间】:2011-01-10 03:28:58 【问题描述】:.NET 中的“AnyCPU”功能如何工作让我感到困惑:如果系统是 32 位,它将可执行文件加载为本机 32 位,如果系统是 64 位,则加载为 64 位(您可以通过任务管理器轻松确认)。显然,这并非不可能。
问题是,微软究竟是如何做到这一点的? Windows 最初并不知道 .NET 框架,因此 Windows PE 加载器不可能在 PE 头中为 CLR 头寻找任何额外的功能;此功能一定是由某种内核模式扩展添加的。但是 .NET 框架似乎没有安装这样的东西......我完全不知道同一个可执行文件如何同时是本机 32 位和 64 位,特别是因为 mscoree.dll 的反汇编没有'甚至不显示对未记录本机函数的引用。
有没有人知道和/或合理猜测这是如何做到的?这显然是可能的(所以没有说“不可能”之类的话),这让我想尝试编写一个 native 跨平台 EXE...
编辑:
作为旁注,请考虑您如何无法在 64 位 Windows PE 环境中运行 32 位可执行文件...得到某种方式来扩展或修改 PE 加载程序有某种“插件”,对吧?
【问题讨论】:
有一些程序(例如 Process Explores)会执行此操作,我会分发一个 32 位可执行文件,如果可能,它会启动一个 64 位映像。例如。除了 32 位 PE,“AnyCPU”可执行文件是什么? @pst:我完全了解这些,但不,它们是不同的。 AnyCPU 可执行文件从它们在 64 位操作系统上启动的那一刻起就是 64 位的——没有解包,也没有像“让我们将此字节码代码 JIT 为 64 位,然后重新启动 64 位进程”之类的东西。这就是让我感到困惑的原因。 【参考方案1】:您的问题是基于误解。这是错误:
Windows 最初并不知道 .NET 框架
实际上,从 Windows XP 开始,Windows IS aware of the .NET executable format。 XP 是第一个支持 64 位的 Windows 版本。
因此 PE 标头被标记为 32 位,并且本机导入表引用 32 位 mscoree
,这在 Windows 2000 和更早版本上会导致加载 32 位 .NET。 DllMain
for mscoree
开始 JITting 应用程序代码并修改主应用程序的入口点。
Windows XP 及更高版本在了解 .NET 元数据后,会识别出它是 AnyCPU
并加载相应的框架。
Here's probably more than you ever wanted to know about the process.
所以不,没有原生的AnyCPU
exe。虽然可以在 32 位 PE 中嵌入 16 位 DOS 程序,但不能同时拥有 32 位和 64 位 .exe
【讨论】:
.NET 框架不是在 XP 发布之后出现的吗(至少,我以为我记得的)?我以为XP was released in 2001 和.NET in 2002... @Lambert:开发时期重叠,.NET 开发在 2002 年首次发布之前大约 5 年开始,因此微软有足够的时间将钩子放入 XP。正如我所说,Windows 2000 只有 32 位。无论如何,您应该考虑几年后 Windows XP 64 位版本的发布日期,因为它是第一个需要这种“魔力”的版本。 啊……这就解释了。 (是的,很抱歉,我在您发布之前删除了关于我的评论的 Windows 2000 部分,因为我记得它没有 64 位。)不是我正在寻找的答案,但绝对看起来是正确的;谢谢! :) @Lambert:添加了两个链接,您可能会喜欢阅读以了解更多详情。 @Ben:我已经阅读了第一个链接,但第二个链接是新的。起初我以为这会告诉我关于 WOW64 thunk 和所有这些的信息,而且我没有抱怨已经知道这些,因为 .NET 信息绝对是新的和有用的。感谢您发布这些!希望我能再给一个+1。 :)【参考方案2】:如果系统具有 WOW64 仿真层(Windows Vista+,不知道 XP),您实际上可以在 x86 可执行文件中包含 x64 代码。 http://vxheavens.com/lib/vrg02.html
我已经测试过这种技术,它适用于 Win7 和 WinVista。我在汇编中编写了一个小存根来解析导入并加载一些为 AMD64 编译的 C 代码。
微软只是说你不能来回转换,因为他们可能会改变它,但我怀疑这会改变,直到底层架构改变以允许像 128 位这样的东西也能运行......那时我怀疑 WOW64将在附近:),WOW128 ftl。
【讨论】:
以上是关于为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法让 Windows 64 位上的应用程序在 64 位和 32 位仿真层下执行代码?