2017-08-13 1 views
2

私はjavaでゲームのクライアントをコーディングしようとしています(正直言って、Minecraft)。しかし、これはMinecraftにのみ適用されるものではなく、一般的にJava仮想マシンアーキテクチャに適用されるので、私は推測します。基本的に、私はメモリアドレスを見つけるためにチートエンジンを使用しています、そして、私はプレーヤーの健康価値に対応するように見えるアドレスを見つけました。実行時にJava(より具体的にはjavaw)のメモリを外部に変更できますか?

問題を修正することは不可能なので、私は間違ったことをしていますか、またはJVMのメモリの変更を制限するメカニズムがありますか?

ちょっとした背景:私はC#を使ってメモリをプロセス間で読み書きしています。私がこれを達成する方法は、kernel.dllによって提供される外部関数を使用することです(詳細はこちら:https://stackoverflow.com/a/4623200/6817922)。私のようなコードでプログラムを実行すると、しかし

public static bool Write(IntPtr address, byte[] value) 
{ 
    if(ProcessToEdit == null) // If the process is not valid: return with no attempt to edit 
    { 
     return false; 
    } 
    int bytesWritten = 0; 
    // Writes the byte[] value to a specified address 
    return WriteProcessMemory(ProcessPointer, address, value, (uint)value.LongLength, out bytesWritten) 
} 

Write(0xCDD9BEA0, new byte[] { 20 }); // 0xCDD9BEA0 is the memory address of health. 

プログラムが正しく実行され、関数「書き込み」があることを返す私はまた、書き込みタスクを簡素化する機能を持っていますメモリアドレスに正常に書き込まれましたが、(ゲームが更新されなかったため、またチートエンジンインターフェイスを実行しなかったために)失敗しました。これは、JVMプロセスを変更しようとした場合にのみ発生します。たとえば、プロセス「メモ帳」のテキストを編集すると、正しく編集され、チートエンジンと同様にプログラムに変更が表示されます。

さらに進んでJVMプロセスでは、チートエンジンがメモリアドレスを変更することさえできません。すぐにリセットされます。だから問題はまだ残っています:JVMにメモリが外部から変更されないようにするメカニズムはありますか?

答えて

1

はい、ユーザーに十分な権限(Administratorなど)がある場合は、Javaプロセスのメモリを変更できます。これは基本的にOS機能です。 JVMはこれを防ぐために何もしません(そしてできません)。

さらに、JVMはこのような変更を伴うアシストでもできます。実行中のJVMプロセスにエージェントを接続するには、public APIがあります。エージェントは標準のJNIJVM TIインターフェイスを使用して、ロードされたクラスにアクセスしたり、オブジェクトフィールドを変更したり、任意のJavaメソッドなどを呼び出すことができます。

私はチートエンジンがあなたのケースでうまくいかない理由は言えません。エンジンが必要ですが、これが起こり得るいくつかの理由が考えられます。

たとえば、変更しようとする値がレジスタにキャッシュされ、メモリから読み取られません。値が(レジスタ内で)変更されるたびにメモリに書き戻されるため、の値が「リセット」になっていることがわかります。

また、Javaオブジェクトにメモリ内の固定アドレスがあるとは限りません。ガベージコレクタはヒープを介してオブジェクトを移動する可能性があり、これによりチートエンジンの仕事はより困難になります。

実行時にJavaアプリケーションをパッチする正しい方法は、JNI/JVM TI/Instrumentation APIのような標準APIを使用して、Java以外のユーティリティでは実行できないすべてのケースを処理することです。

関連する問題