.net JITコンパイラをだまして別のメソッドを実行する方法はありますか?
-
04-07-2019 - |
質問
さて、私のアプリケーションは(x86)命令をメモリに発行し、ページを実行可能にするとします。発行された命令ストリームを指すように、JITされていないメソッドのメソッドスタブを変更する方法はありますか?
例:
メモリ内にx86命令ストリームを作成しましたが、これは任意の処理を行います。さらに、メソッド 'int Target()'があると仮定します。まだ呼び出していないので、コンパイルされていません。次の方法があります:
- ターゲットのスタブへのポインターを取得
- 発行された命令ストリームを指すようにします。
.Netのほとんどすべてのセキュリティ機能は、このようなハイジャックを防止するように設計されていることを認識しています。しかし、たとえば、ホスティングAPIを介して可能ですか?
解決
はい、できます!
mscorjitのgetJitメソッドをフックします。 そして、どのメソッドでもJittingが必要になるたびに尋ねられます。 好きなものを渡すことができます。 一部の.netプロテクターはこのように機能します。
他のヒント
これは、プロファイリングAPIを介して可能です。使用したことはありませんが、TypeMockで同様の目的で使用されています。
編集:MSDNブログに素敵な投稿があったと思うので、探しに行きましょう。
編集2:Doh、最初のヒット!
おっしゃるように、これは簡単ではなく、不可能な場合もあります。正しく覚えていれば、コードにはコンパイルされていないメソッドのJITコンパイラのアドレスが含まれます。そのため、このメソッドを呼び出そうとすると、JITコンパイラーがジョブを実行し、新しくコンパイルされたメソッドにアドレスを挿入します。このアドレスを変更できる場合は、独自のコードへの呼び出しを挿入できる場合があります。これを検出せずに行う方法は、私を超えています。 CLRがこの種の改ざんを検出することを期待しています。
MSILを変更しようとしていないので、プロファイリングAPIはこの場合(Leppieが示唆するように)役に立たないと思います。そうでないと思われる場合は、この記事は、 TypeMockが実行していることを実装する必要があります。
メモリを直接試してみることはありませんし、代わりにプロファイラAPIを使用できるかどうかもわかりません-いくつかの例がありますが、実際のドキュメントはありません。 MSDNマガジンの記事をご覧ください- .NETでMSILコードを書き換えますフレームワークプロファイリングAPI