1

私は現在、VB.NET を介して G15 キーボードのゲームに健康情報を表示する小さな趣味のプロジェクトを開発しています。

API 呼び出しを介して ReadProcessMemory を使用すると、0 が返され続けます。MSDN のドキュメントでは、Marshal.GetLastWin32Error() 呼び出しを使用して何が問題なのかを調べるように指示されており、1400: INVALID WINDOW HANDLE が返されます。

関数の最初の引数がウィンドウ ハンドルまたはプロセス ID のどちらを必要としているかについて混乱しています。とにかく、アプリケーションの実行中にFindWindowとプロセスIDのハードコーディングの両方を試しました(タスクマネージャーから取得します)。

私は 3 つの異なるゲーム、Urban Terror、Grand Theft Auto: SA、Windows 用の 3D ピンボールを試し、Cheat Engine と呼ばれるアプリケーションからメモリ アドレスを取得しました。それらはすべて失敗しているようです。

これを行うために使用しているコードは次のとおりです。

API 呼び出し:

Private Declare Function ReadProcessMemory Lib "kernel32" ( _
ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByRef lpBuffer As Single, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer _
) As Integer

方法:

Dim address As Integer
address = &HA90C62&
Dim valueinmemory As Integer

Dim proc As Process = Process.GetCurrentProcess
For Each proc In Process.GetProcesses
    If proc.MainWindowTitle = "3D Pinball for Windows - Space Cadet" Then
        If ReadProcessMemory(proc.Handle.ToInt32, address, valueinmemory, 4, 0) = 0 Then
            MsgBox("aww")
        Else
            MsgBox(CStr(valueinmemory))
        End If
    End If
Next

Dim lastError As Integer
lastError = Marshal.GetLastWin32Error()
MessageBox.Show(CStr(lastError))

誰かがなぜそれが機能しないのか説明してもらえますか? 前もって感謝します。

4

3 に答える 3

3

まず、元のパラメーターが LPBUF 型であるのに、メソッド シグネチャが間違っています。Single=Float です。

このメソッド シグネチャを使用します。

<DllImport("kernel32.dll", SetLastError=true)> _
Public Shared Function ReadProcessMemory( _
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
<Out()>ByVal lpBuffer() As Byte, _
ByVal dwSize as Integer, _
ByRef lpNumberOfBytesRead as Integer
) As Boolean
End Function

次に、hProcess ハンドルは、ウィンドウ ハンドルではなく、OpenProcess 関数によって開かれたハンドルを想定していると思います。

于 2008-12-06T22:49:55.073 に答える
1

メッセージ 299 : ReadProcessMemory または WriteProcessMemory 要求の一部のみが完了しました。これは、読み取ろうとしていたメモリが保護されたことを意味します。

ご協力いただきありがとうございます。arulの回答を回答としてマークします。

于 2008-12-08T23:02:01.770 に答える
1

ありがとう、arul、私は自分の問題を解決しました。

Dim address As Integer
address = &HA90C62&
Dim floatvalueinmemory() As Byte

Dim proc As Process = Process.GetCurrentProcess
For Each proc In Process.GetProcesses
    If proc.MainWindowTitle = "3D Pinball for Windows - Space Cadet" Then
        Dim winhandle As IntPtr = OpenProcess(PROCESS_ACCESS.PROCESS_VM_READ, True, proc.Id)

        If ReadProcessMemory(winhandle, address, floatvalueinmemory, 4, 0) = 0 Then
            Dim lastError As Integer
            lastError = Marshal.GetLastWin32Error()
            MessageBox.Show(CStr(lastError))
            MsgBox("aww")
        Else
            MsgBox("woo")
        End If

        CloseHandle(winhandle)
    End If
Next

ハンドルが有効であると判断し、プロセス メモリの読み取りを試みますが、エラー メッセージ 299 が表示されます。 ReadProcessMemory または WriteProcessMemory 要求の一部のみが完了しました。

この問題を解決するためにどのように進めるべきかについて、誰かアイデアはありますか?

于 2008-12-06T23:46:28.377 に答える