我正在开发一个小爱好项目,通过VB.NET在G15键盘上的游戏中显示健康信息。
当我通过API调用使用ReadProcessMemory时,它会一直返回零。 MSDN文档提到我使用Marshal.GetLastWin32Error()调用来找出错误并返回1400:INVALID WINDOW HANDLE。
我现在对该函数的第一个参数是否需要窗口句柄或进程ID感到困惑。无论如何,我已经尝试使用FindWindow并在应用程序运行时对进程ID进行硬编码(从任务管理器获取)。
我尝试了三种不同的游戏,Urban Terror,侠盗猎车手:SA和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))
有人可以向我解释为什么它不起作用?提前谢谢。
答案 0 :(得分:3)
首先,您的方法签名是错误的,Single = Float,而原始参数是LPBUF类型。
使用此方法签名:
<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函数打开的句柄,而不是窗口句柄。
答案 1 :(得分: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请求的一部分。
有没有人对如何解决此问题有任何想法?
答案 2 :(得分:1)
消息299:只完成了ReadProcessMemory或WriteProcessMemory请求的一部分意味着我试图读取的内存受到保护。
感谢您的帮助,我将把arul的答案标记为答案。