为 Windows 编写跨平台(32 位和 64 位兼容)程序(如 .NET 中的 AnyCPU)
.NET 中的“AnyCPU”功能如何工作一直让我困惑:如果系统是 32 位,它会将可执行文件加载为本机 32 位,如果系统是 64 位,则加载为 64 位(您可以轻松确认)与任务管理器)。显然,这并非不可能。
问题是,微软到底是如何做到这一点的呢? Windows 最初并不了解 .NET 框架,因此 Windows PE 加载程序不可能在 PE 标头中为 CLR 标头查找任何额外功能;此功能必须是通过某种内核模式扩展添加的。但 .NET 框架似乎没有安装这样的东西...我完全不知道同一个可执行文件如何同时是本机 32 位和 64 位,特别是因为 mscoree.dll 的反汇编并没有甚至不显示对未记录的本机函数的引用。
有谁对这是如何完成的有任何了解和/或合理的猜测?这显然是可能的(所以不要说“这是不可能的”),这让我想尝试编写一个本机跨平台 EXE...
编辑:
作为旁注,考虑如何你不能在 64 位 Windows PE 环境中运行 32 位可执行文件...必须有某种方法可以使用某种“插件”来扩展或修改 PE 加载程序,对吗?
It's been baffling me how the "AnyCPU" feature in .NET works: It loads the executable as native 32-bit if the system is 32-bit, and as 64-bit if the system is 64-bit (which you can easily confirm with Task Manager). So obviously, this isn't impossible.
The question is, how exactly did Microsoft do this? Windows originally didn't know about the .NET framework, so the Windows PE Loader can't possibly look for any extra features in PE headers for the CLR header; this feature must have been added by some sort of kernel-mode extension. But the .NET framework seems to install no such thing... I'm at a complete loss at how the same executable can be native 32-bit and 64-bit at the same time, especially since a disassembly of mscoree.dll doesn't even show references to undocumented native functions.
Does anyone have any knowledge and/or reasonable guesses as to how this was done? It's obviously possible (so no saying things like "it's not possible"), and it makes me want to try to write a native cross-platform EXE...
Edit:
As a side note, consider how you can't run 32-bit executables in a 64-bit Windows PE environment... there's got to be some way to extend or modify the PE loader with some sort of "plugin", right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的问题是基于误解。这是错误:
实际上,从 Windows XP 开始, Windows 识别 .NET 可执行格式。 XP 是第一个支持 64 位的 Windows 版本。
因此,PE 标头被标记为 32 位,并且本机导入表引用 32 位
mscoree
,这在 Windows 2000 及更早版本上会导致加载 32 位 .NET。mscoree
的DllMain
启动对应用程序代码进行 JIT 操作并修改主应用程序的入口点。Windows XP 及更高版本了解 .NET 元数据,识别出它是 AnyCPU 并加载适当的框架。
这里可能比您想了解的更多信息< /a>.
所以不,没有本机
AnyCPU
exe。虽然您可以在 32 位 PE 中嵌入 16 位 DOS 程序,但您不能同时拥有 32 位和 64 位 .exeYour question is based on a misunderstanding. Here's the mistake:
Actually, since Windows XP, Windows IS aware of the .NET executable format. And XP was the first version of Windows to support 64-bits.
So the PE header is marked 32-bit and the native import table references the 32 bit
mscoree
, which on Windows 2000 and earlier, causes 32-bit .NET to be loaded.DllMain
formscoree
starts JITting the application code and modifies the entrypoint for the main application.Windows XP and later, being aware of the .NET metadata, recognizes that it is
AnyCPU
and loads the appropriate framework.Here's probably more than you ever wanted to know about the process.
So no, there is no native
AnyCPU
exe. Although you can embed a 16-bit DOS program in a 32-bit PE, you can't have a combined 32-bit and 64-bit .exe如果系统有 WOW64 模拟层(Windows Vista+,不知道 XP),您实际上可以在 x86 可执行文件中包含 x64 代码。 http://vxheavens.com/lib/vrg02.html
我已经测试了这种技术并且它有效在 Win7 和 WinVista 上。我在汇编中编写了一个小存根来解析导入并加载一些为 AMD64 编译的 C 代码。
微软只是说你不能来回转换,因为他们可能会改变它,但我怀疑这种情况会改变,直到底层架构发生变化以允许像 128 位这样的东西运行......那时我怀疑 WOW64 会出现:),WOW128 英尺。
You actually can have x64 code in an x86 executable if the system has a WOW64 emulation layer (Windows Vista+, dunno about XP). http://vxheavens.com/lib/vrg02.html
I have tested this technique and it works on Win7 as well as WinVista. I wrote a little stub in assembly to resolve imports and load up some C code that was compiled for AMD64.
Microsoft just says you can't transition back and forth because they might change it, but I doubt this will change until the underlying architecture changes to allow something like 128 bit to run as well... at that point I doubt WOW64 will be around :), WOW128 ftl.