在“任何 CPU”上强制 x86 CLR .NET 程序集

发布于 2024-08-06 22:37:57 字数 487 浏览 4 评论 0 原文

在 .NET 中,“平台目标:任何 CPU”编译器选项允许 .NET 程序集在 x64 计算机上以 64 位运行,在 x86 计算机上以 32 位运行。还可以使用“平台目标:x86”编译器选项强制程序集在 x64 计算机上作为 x86 运行。

是否可以运行带有“任何 CPU”标志的程序集,但确定它应该在 x86 还是 x64 CLR 中运行?通常这个决定是由 CLR/OS 加载器(据我的理解)根据底层系统的位数做出的。

我正在尝试编写一个 C# .NET 应用程序,它可以与其他正在运行的进程交互(读取:将代码注入到其中)。 x64进程只能注入其他x64进程,x86也是如此。理想情况下,我想利用 JIT 编译和 Any CPU 选项来允许使用单个应用程序注入 x64 或 x86 进程(在 x64 计算机上)。

这个想法是应用程序将被编译为任何CPU。在 x64 机器上,它将作为 x64 运行。如果目标进程是 x86,它应该重新启动自身,强制 CLR 将其作为 x86 运行。这可能吗?

In .NET, the 'Platform Target: Any CPU' compiler option allows a .NET assembly to run as 64 bit on a x64 machine, and 32 bit on an x86 machine. It is also possible to force an assembly to run as x86 on an x64 machine using the 'Platform Target: x86' compiler option.

Is it possible to run an assembly with the 'Any CPU' flag, but determine whether it should be run in the x86 or x64 CLR? Normally this decision is made by the CLR/OS Loader (as is my understanding) based on the bitness of the underlying system.

I am trying to write a C# .NET application that can interact with (read: inject code into) other running processes. x64 processes can only inject into other x64 processes, and the same with x86. Ideally, I would like to take advantage of JIT compilation and the Any CPU option to allow a single application to be used to inject into either x64 or x86 processes (on an x64 machine).

The idea is that the application would be compiled as Any CPU. On an x64 machine, it would run as x64. If the target process is x86, it should relaunch itself, forcing the CLR to run it as x86. Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

筑梦 2024-08-13 22:37:57

您可以使用 CorFlags 应用程序。要了解应用程序将如何运行,请使用:

corflags <PathToExe>

要更改应用程序将如何运行,请使用:

corflags /32bit+  <PathToExe>

这将使 EXE 文件作为 32 位进程运行。有关程序集如何运行的信息存储在 PE 标头中。请参阅 Stack Overflow 问题如何查找本机 DLL 文件是编译为 x64 还是 x86?

如果你想在运行时注入代码,你必须编写一个 .NET 分析器C++/COM。
请参阅.NET 内部结构:分析 API< /em> 和分析(非托管 API 参考)< /em> 了解更多详细信息。

您需要实现 JitCompilationStarted 回调并在那里完成您的工作。如果您朝这个方向发展,则必须将注入 DLL 文件构建为 x86 和 x64。 ,CLR 将加载本机 DLL 文件:

Cor_Enable_Profiling=0x1
COR_PROFILER={CLSID-of-your-native-DLL-file}

设置以下环境变量后 如果设置正确,那么 64 位版本将“看到”64 位进程,32 位版本将“看到”32 位进程。

You can find out how an application will run and change it statically using the CorFlags application. To find out how the application will run, use:

corflags <PathToExe>

To change how the application will run, use:

corflags /32bit+  <PathToExe>

This will make the EXE file run as a 32-bit process. The information about how the assembly should run is stored in the PE header. See Stack Overflow question How to find if a native DLL file is compiled as x64 or x86?.

If you want to inject code at run time, you have to write a .NET profiler in C++/COM.
See .NET Internals: The Profiling API and Profiling (Unmanaged API Reference) for more details.

You'll need to implement the JitCompilationStarted callback and do your work there. If you go in this direction, you'll have to build the injecting DLL file both as x86 and x64. The native DLL files will be loaded by the CLR once the following environment variables will be set:

Cor_Enable_Profiling=0x1
COR_PROFILER={CLSID-of-your-native-DLL-file}

If you have it set correctly then the 64-bit version will 'see' the 64 bit processes and the 32-bit version will 'see' the 32-bit processes.

烟火散人牵绊 2024-08-13 22:37:57

我尝试这个已经有一段时间了,但我相信调用程序集的进程的位数决定了它是否会被 JIT 为 x86 还是 x64。

因此,如果您编写一个小型控制台应用程序并将其构建为 x86,另一个构建为 x64,则运行其中一个或另一个将导致加载到进程中的其他程序集以 32 或 64 位运行。当然,这是假设您在 64 位计算机上运行。

It has been a while since I tried this, but I believe that the bitness of the process that calls the assembly determines whether it will be JITed as x86 or x64.

So if you write a small console application and build it as x86, and another as x64, running one or the other will cause other assemblies loaded into the process to run as 32 or 64 bit. This, of course, assumes you are running on a 64 bit machine.

攀登最高峰 2024-08-13 22:37:57

我不确定我是否可以帮助你解决这个问题。但这是我的经验。

我有一个主机应用程序,A.exe(编译为 x86),还有一个客户端应用程序,B.exe(编译为 ANY CPU),来自主机应用程序。我使用 A.exe 启动 B.exe。 Diagnostics.process.aspx" rel="noreferrer">System.Diagnostic.Process 类。

现在的问题是,如果我将两者放在 x64 计算机上,则 A.exe 将作为 x86 运行,B.exe 将作为 x64 运行< /强>。

但是,如果 A.exe 调用程序集 c(c.dll,编译为 Any CPU),并且 B.exe< /code> 也会调用 c.dll,然后 c.dll 将跟随调用它的应用程序。换句话说,在64位机器上,当A.exe调用它时,它的行为就像x86 dll,而当B.exe调用它时,它的行为类似于 x64。

I'm not sure whether I can help you with this. But this is my experience.

I have a host application,A.exe ( compiled as x86), and I have a client application, B.exe ( compiled as ANY CPU), from the host application. And I launch B.exe from A.exe, using the System.Diagnostic.Process class.

The issue now is if I put the two on a x64 machine, then A.exe will run as x86, whereas the B.exe will run as x64.

But if A.exe calls assembly c ( c.dll, which is compiled as Any CPU), and B.exe also calls c.dll, then c.dll will follow the application that calls it. In other words, in 64 bit machine when A.exe calls it, it will behave like x86 dll, whereas when B.exe calls it, it will behave like x64.

忘东忘西忘不掉你 2024-08-13 22:37:57

我通过创建两个(实际上是三个)二进制文件做了类似的事情。我检测了我尝试注入的进程是 32 位还是 64 位。然后,此过程将启动注入二进制文件的 32 位或 64 位版本(而不是像您提到的那样重新启动自身)。

这听起来很混乱,但您可以在构建时通过构建后事件轻松实现此目的,该事件会复制输出二进制文件并使用 CorFlags 实用程序强制副本以 32 位运行。这样,您就不必在应用程序中部署 CorFlags 实用程序,无论如何,这可能由于某种原因是不合法的。

我认为这与您最初的想法非常相似,除了两行构建事件之外,实际上不需要更多的工作。

I've done something similar by creating two (really three) binaries. I had one detect whether the process I was trying to inject into was 32 or 64-bit. This process will then launch either the 32-bit or 64-bit version of your injection binary (as opposed to relaunching itself like you mentioned).

It sounds messy, but you can easily achieve this at build time with a post-build event that makes a copy of your output binary and uses the CorFlags utility to force the copy to run as 32-bit. This way you don't have to deploy the CorFlags utility with your application, which probably isn't legal for some reason anyway.

I think this is quite similar to your initial idea and really doesn't require more work except for a two-line build event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文