ReadProcessMemory keeps returning 0

I am currently developing a small hobby project to display in-game health information on my G15 keyboard via VB.NET.

When I use ReadProcessMemory via an API call, it keeps returning zero. The MSDN documentation suggested that I use the Marshal.GetLastWin32Error () call to find out what is wrong and it returns 1400: INVALID WINDOW HANDLE.

Now I am confused about whether the first argument of the function is needed by the window handle or the process ID. Regardless, I tried to use FindWindow and hardcoding the process id while the application was running (getting it from the task manager).

I've tried three different games: Urban Terror, Grand Theft Auto: SA, and 3D pinball for Windows, getting memory addresses from an application called Cheat Engine; they all seem to fail.

Here's the code I'm using to do this:

API call:

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

      

Method:

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))

      

Can someone please explain to me why it is not working? Thanks in advance.

+1


source to share


3 answers


First, your method signature is incorrect, Single = Float, whereas the original parameter is of type LPBUF.

Use this method signature:



<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

      

Second, I believe that the hProcess handle expects a handle opened by an OpenProcess function, not a window handle.

+3


source


Thank you, arul, I have a problem.

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

      



Now it thinks the handle is valid and tries to read the process memory, but I get error 299: Only a portion of the ReadProcessMemory or WriteProcessMemory request completed.

Does anyone have any ideas as to how I should fix this problem?

+1


source


message 299: Only part of the ReadProcessMemory or WriteProcessMemory request was completed because the memory I was trying to read was protected.

Thanks for your help, I'm going to mark arul's answer as an answer.

+1


source







All Articles