58

.NETでは、「プラットフォームターゲット:任意のCPU」コンパイラオプションを使用すると、.NETアセンブリをx64マシンでは64ビット、x86マシンでは32ビットとして実行できます。'Platform Target:x86'コンパイラオプションを使用して、x64マシン上でアセンブリを強制的にx86として実行することもできます。

'Any CPU'フラグを使用してアセンブリを実行することは可能ですが、x86またはx64 CLRのどちらで実行する必要があるかを判断しますか?通常、この決定は、基盤となるシステムのビット数に基づいて、CLR / OSローダーによって行われます(私の理解ではそうです)。

実行中の他のプロセスと対話(読み取り:コードを挿入)できるC#.NETアプリケーションを作成しようとしています。x64プロセスは、他のx64プロセスにのみ注入でき、x86でも同じです。理想的には、JITコンパイルとAny CPUオプションを利用して、単一のアプリケーションを使用してx64またはx86プロセス(x64マシン上)に注入できるようにしたいと思います。

アイデアは、アプリケーションが任意のCPUとしてコンパイルされるということです。x64マシンでは、x64として実行されます。ターゲットプロセスがx86の場合、それ自体を再起動し、CLRにx86として実行させる必要があります。これは可能ですか?

4

4 に答える 4

61

CorFlagsアプリケーションを使用して、アプリケーションがどのように実行され、静的に変更されるかを確認できます。アプリケーションがどのように実行されるかを確認するには、次を使用します。

corflags <PathToExe>

アプリケーションの実行方法を変更するには、次を使用します。

corflags /32bit+  <PathToExe>

これにより、EXEファイルが32ビットプロセスとして実行されます。アセンブリの実行方法に関する情報は、PEヘッダーに保存されます。StackOverflowの質問を参照してください。ネイティブDLLファイルがx64またはx86としてコンパイルされているかどうかを確認するにはどうすればよいですか。

実行時にコードを挿入する場合は、 C ++ /COMで.NETプロファイラーを作成する必要があります。詳細については、.NET内部:プロファイリングAPIおよびプロファイリング(アンマネージAPIリファレンス)を参照してください。

JitCompilationStartedコールバックを実装し、そこで作業を行う必要があります。この方向に進む場合は、挿入DLLファイルをx86とx64の両方としてビルドする必要があります。次の環境変数が設定されると、ネイティブDLLファイルがCLRによってロードされます。

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

正しく設定されている場合、64ビットバージョンは64ビットプロセスを参照し、32ビットバージョンは32ビットプロセスを参照します。

于 2009-10-02T12:52:01.657 に答える
9

これを試してからしばらく経ちましたが、アセンブリを呼び出すプロセスのビット数によって、x86 または x64 として JIT されるかどうかが決まると思います。

したがって、小さなコンソール アプリケーションを作成し、それを x86 としてビルドし、別のアプリケーションを x64 としてビルドした場合、いずれかを実行すると、プロセスに読み込まれた他のアセンブリが 32 ビットまたは 64 ビットとして実行されます。もちろん、これは 64 ビット マシンで実行していることを前提としています。

于 2009-10-02T01:21:27.760 に答える
6

2 つ (実際には 3 つ) のバイナリを作成して、同様のことを行いました。挿入しようとしているプロセスが 32 ビットか 64 ビットかを 1 つ検出しました。このプロセスは、32 ビットまたは 64 ビット バージョンのインジェクション バイナリを起動します (前述のように再起動するのではなく)。

面倒に思えますが、これは、出力バイナリのコピーを作成し、 CorFlagsユーティリティを使用してコピーを強制的に 32 ビットとして実行するビルド後のイベントを使用して、ビルド時に簡単に実現できます。この方法では、CorFlags ユーティリティをアプリケーションにデプロイする必要はありません。これは、何らかの理由でおそらく合法ではありません。

これはあなたの最初のアイデアと非常に似ていると思います.2行のビルドイベントを除いて、実際にはそれ以上の作業は必要ありません.

于 2010-03-15T20:06:13.043 に答える
6

これについてお手伝いできるかどうかわかりません。しかし、これは私の経験です。

ホスト アプリケーションA.exe(x86 としてコンパイル) があり、ホスト アプリケーションからクライアント アプリケーションB.exe( としてコンパイルANY CPU) があります。そして、 System.Diagnostic.Processクラスを使用してB.exeから起動します。A.exe

問題は、x64 マシンに 2 つを配置するA.exeと、 x86 として実行されますが、 x64B.exeとして実行されます。

ただし、A.exeアセンブリ c (c.dllとしてコンパイルされますAny CPU) を呼び出し、さらにB.exeも呼び出すc.dllと、c.dll はそれを呼び出したアプリケーションに従います。つまり、64 ビット マシンでは、呼び出すとdll のA.exeように動作しますが、呼び出すと のように動作します。x86B.exex64

于 2009-10-02T03:30:14.263 に答える