ReadProcessMemory keeps returning 0
我目前正在开发一个业余爱好项目,通过VB.NET在我的G15键盘上的游戏中显示健康信息。
当我通过API调用使用ReadProcessMemory时,它始终返回零。 MSDN文档使我使用Marshal.GetLastWin32Error()调用来找出问题所在,并返回1400:无效的窗口句柄。
我现在对函数的第一个参数是否需要窗口句柄或进程ID感到困惑。无论如何,我都尝试过使用FindWindow和在应用程序运行时对进程ID进行硬编码(从任务管理器中获取)。
我尝试了三种不同的游戏,《城市恐怖》,《侠盗猎车手:SA》和用于Windows的3D弹球,从名为Cheat Engine的应用程序获取内存地址;他们似乎都失败了。
这是我正在使用的代码:
API调用:
1 2 3 4 5 6 7 | 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 |
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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)) |
有人可以向我解释为什么它不起作用吗?预先感谢。
首先,您的方法签名错误,Single = Float,而原始参数为LPBUF类型。
使用此方法签名:
1 2 3 4 5 6 7 8 9 | <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函数打开的句柄,而不是窗口句柄。
消息299:只有部分ReadProcessMemory或WriteProcessMemory请求完成,这表示我尝试读取的内存受到保护。
感谢您的帮助,我将把arul的答案标记为答案。
谢谢您,我已经解决了我的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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请求已完成。
有人对我应该如何解决此问题有任何想法吗?