1

まず、これが重複しているように見えますが、他の質問を調べても解決策が見つからなかったので、聞いてください.

相対仮想アドレスを動的メモリアドレス、つまり複数レベルのポインターの読み取りに変換する機能があります (以下を参照)。すべてのアクセス権を持つリモート プロセスへの有効なハンドル、プロセスのベース アドレス (4194304 または 0x400000) へのポインター、rva (29128148 または 0x1BC75D4)、およびオフセット ({ 20, 48, 12 } 、{ 0x14、0x30、0xC })。ベースアドレスを rva に追加する行は、正しい 33322452 または 0x1FC75D4 を返します (チートエンジンで検証済み)。ループの最初の反復では、前述のアドレスで RPM() を呼び出し、BitConverter.ToInt32() への呼び出しは -134118400 または正しい 0xF8018400 を返します。dynamicMemoryAddress の新しい値は、そのアドレスと、-134118380 または 0xF8018414 の値を持つ IntPtr を生成する最初のオフセット (0x14) を追加することによって設定されます。

ただし、RPM() が 2 回目の繰り返しで新しい dynamicMemoryAddress (0xF8018414) の値で呼び出されると、関数は失敗ステータスを返します。GetLastError() を呼び出すと、998 または ERROR_NOACCESS (メモリ位置への無効なアクセス) が返されます。Cheat Engine で 0xF8018414 を参照すると、正しい値があり、ページの保護値が PAGE_READ_WRITE であるため、十分なアクセス権があるように見えても、最初の呼び出しが成功するのに 2 番目の呼び出しが失敗する理由がわかりません。

デバッグの目的で、RPM() への呼び出しの直前に VirtualQueryEx() への呼び出しを挿入しました。最初の反復は成功し、MemoryBasicInformation 構造体は正しく設定され、2 回目の反復では構造体は完全に空になります。

私はこの問題で 2 日間立ち往生しており、機知に富んでいます。どんな助けも大歓迎です。私は x64 Windows 7 で実行していますが、関連するプロセスはすべて x86 です。

private static IntPtr ConvertRVAToDMA(RemoteProcess rProcess, IntPtr baseAddress, IntPtr relativeVirtualAddress, Int32[] offsets)
        {
            Process.EnterDebugMode();
            byte[] buffer = new byte[Marshal.SizeOf(new IntPtr())];
            int tmpNewBaseAddress;
            IntPtr bytesRead = new IntPtr();

            IntPtr dynamicMemoryAddress = new IntPtr(baseAddress.ToInt32() + relativeVirtualAddress.ToInt32());

            try
            {
                for (int i = 0; i < (offsets.Length); i++)
                {
                    if (!WinApis.ReadProcessMemory(rProcess.Handle, dynamicMemoryAddress, buffer, Marshal.SizeOf(new IntPtr()), out bytesRead))
                    {
                        dynamicMemoryAddress = IntPtr.Zero;
                        break;
                    }

                    tmpNewBaseAddress = BitConverter.ToInt32(buffer, 0);
                    if (tmpNewBaseAddress == 0)
                    {
                        dynamicMemoryAddress = IntPtr.Zero;
                        break;
                    }

                    dynamicMemoryAddress = IntPtr.Add((IntPtr)tmpNewBaseAddress, offsets[i]);
                }
            }
            catch (Exception ex)
            {
                dynamicMemoryAddress = IntPtr.Zero;
            }
            Process.LeaveDebugMode();
            return dynamicMemoryAddress;
        }
4

0 に答える 0