1

状況

こんにちは、2 つの問題があります。
状況は、プロセスにコードを挿入してターゲットを操作するためのツールも提供するWindows 用の Java API を作成していることです。たとえば、jar を別の jar に注入するなど、すでにInjection-partを実装しています。この時点で、私の jar が呼び出され (ターゲットがすでに実行中に)、完全な静的コンテキストで開始されます。

目標と問題

ここから、2 つの目標があります。

  1. ターゲット オブジェクトとやり取りしたいので、参照が必要です。多くのオブジェクトでは、インスタンスへの静的アクセスを提供しているため、これはすでに可能です。たとえば、awt.Frames#getFrames()は、作成されたすべての Frame オブジェクトへのアクセスを提供します。しかし、ヒープ上の任意のオブジェクトにアクセスできる可能性があれば素晴らしいことです。「 Heap#getAllObjectInstances() 」のようなもの。
  2. オブジェクト インスタンスが与えられたら、このオブジェクトの任意の関数に接続したいと思います。たとえば、BufferStrategy#show()が呼び出されるたびに、最初に別のメソッドを呼び出すようにします。

そこで、問題点を次のようにまとめます。

  1. 静的コンテキストから任意のオブジェクト参照を取得するには?
  2. 任意の関数に接続する方法は?

備考

私がこれまでに行ったこと、発言、アイデア:

  1. JDI (Java Debugger Interface) は、VirtualMachine#allClasses() -> ReferenceType#instances(0)を介してそのようなメソッドを提供します。しかし、JDI では、追加のデバッグ パラメータを使用してターゲット JVMを開始する必要がありますが、これはオプションではありません低レベルに降りてメモリツールでヒープを分析することもできますが、誰かがより高レベルのアプローチを知っていることを願っています. 私はJNA/JNIに精通しているので、Windows API を使用することも選択肢の 1 つですが、そのようなツールは知りません。
  2. 最後の手段は、非常に低レベルのアプローチである C コードでIAT フックを使用することです。これは避けたいと思います。この時点でオブジェクト参照があると想定できるので、Reflection APIはオブジェクト メソッドを変更するメソッドを提供するのでしょうか? または、少なくとも単にフックメカニズムを提供しますか?

対象となるコードを変更することは、私にとって選択肢ではないことに注意してください。そして、それはすでに実行時であるため、ByteCode-Manipulation もオプションになる可能性があります。

シナリオ

これが役立つシナリオ:
ターゲットは、jar としてデプロイされたgameです。BufferStrategyクラスを使用して、 Double-Buffer-Strategyでレンダリングします。BufferStrategy#show()で画像を表示します。ゲーム内に jar を挿入し、追加情報を含むオーバーレイを描画します。このために、使用されているBufferStrategyへの参照を取得し、そのshowメソッドに接続します。drawOverlay -methodが呼び出されるたびに呼び出されるように、元のshow-methodに戻します。

4

1 に答える 1

4

必要なのは、JVMTI エージェント ( JVM Tool Interfaceを利用するネイティブ ライブラリ) です。

Attach APIを使用して、実行中の VM にエージェントを動的に接続できます。VirtualMachine.loadAgentPath
を参照してください。

  1. 特定のクラスのすべてのインスタンスを取得するには、JVMTI のIterateOverInstancesOfClass関数を使用します。
    詳細については、関連する質問を参照してください。

  2. 外部クラスのメソッドをインターセプトするには、JVMTI RetransformClasses APIが必要です 。同じことは、Java レベルの計測 API を使用しても実現できます。 Instrumentation.retransformClassesを参照してください。

JVMTI レベルのメソッド インターセプトの例についてはdemo/jvmti/mtrace、Oracle JDK デモおよびサンプル パッケージを参照してください。

Byte Buddyのようなバイトコード操作ライブラリを使用すると、Java レベルの計測がより簡単になります。

于 2016-06-27T00:21:17.770 に答える