web-dev-qa-db-ja.com

外部メモリアドレスへのアクセス

Windows 10のような最新のオペレーティングシステムは、プロセスのメモリアドレスを分離するので、Cheat Engineがこれらのアドレスを取得して値を変更できるようにするにはどうすればよいですか?

このフォーラムでは、「外部アドレスへのポインタを取得する方法」という質問をすでに受けています。答えは、OSがプログラムのアドレスを分離しているため不可能です。

2
S3jp4kCZE
char buffer[4096];
SIZE_T bytesRead;
HANDLE proc = OpenProcess(PROCESS_VM_READ, FALSE, <PID>);
ReadProcessMemory(proc, <address_in_other_program>, buffer, 4096, &bytesRead);

ここでは多くのものを省略します。たとえば、VM_READ権限でターゲットプロセスを実際に開くことができるかどうかを判断するエラーチェックなどですが、それは本当に簡単です。仮想メモリは1つのプロセスを意味するわけではありませんできない別のメモリにアクセスします。これは、各プロセスのアドレス空間が(デフォルトで)独自のものであることを意味し、他の誰かにアクセスしたい場合は、それのための。

Windowsでは、デフォルトで、同じユーザーとして同じ整合性レベルで実行されているすべてのプロセスが、互いのメモリへの読み取りアクセスを取得できます(整合性の高いプロセスは整合性の低いプロセスも読み取ることができますが、その逆はできません)。プロセスは、自身のACL、または同じまたは厳密に低い特権で実行されている他のACLのACLを変更できます。これは、何らかの理由で必要な場合に、別のユーザーアクセスで実行するプロセスを許可するために使用できます。管理者(およびSeDebugPrivilegeを使用している他のユーザー)もany他のプロセスのメモリにアクセスできます(特別な「デバッグしないでください!」フラグを持つ少数のプロセスを除く)。これが、管理者として起動されたデバッガーが(ほとんど)何でもデバッグできる理由です。

このコードサンプルでは、​​他のプロセスのPIDを取得することと、読み取るアドレスを取得することの2つの重要なステップも省略されていることに注意してください。 PIDは非常に簡単です(特に秘密にされているわけではなく、同じユーザーとして実行されているプロセスは誰でも簡単に列挙できます)が、ベースアドレスを取得するのはより困難です。これは、デバッグシンボルを使用するか、OSの現在のASLRマスク(再起動のたびに変更されますが、マシンで実行されているすべてのプロセスで同じです)を使用して、予想されるベースアドレスをXORするだけで実行できますが、それに努力。ターゲットプロセスにマップされていないアドレスを要求すると、ReadProcessMemory呼び出しは失敗します。

補足として、APIはWindows固有ですが、コンセプトは異なります。デバッグをサポートするすべてのOSには、別のプロセスのメモリを読み取る方法があります。これには、Linux、MacOSなどが含まれます。プロセス間メモリアクセスのデフォルトのアクセス許可は異なる場合がありますが、十分に特権のあるプロセスでは常に可能です。

2
CBHacking