ReadProcessMemory ne cesse de renvoyer 0
-
19-08-2019 - |
Question
Je suis en train de développer un petit projet amateur pour afficher des informations sur la santé dans un jeu sur mon clavier G15 via VB.NET.
Lorsque j'utilise ReadProcessMemory via un appel d'API, il ne cesse de renvoyer zéro. La documentation MSDN m’a renvoyé à l’utilisation de l’appel Marshal.GetLastWin32Error () pour rechercher l’erreur et renvoie 1400: INVALID WINDOW HANDLE.
Je ne sais plus trop si le premier argument de la fonction veut un handle de fenêtre ou un identifiant de processus. Quoi qu’il en soit, j’ai essayé à la fois avec FindWindow et de coder en dur l’identificateur de processus pendant que l’application est en cours d’exécution (en le récupérant du gestionnaire de tâches).
J'ai essayé trois jeux différents, Urban Terror, Grand Theft Auto: SA et 3D Pinball pour Windows, en obtenant les adresses de mémoire d'une application appelée Cheat Engine; ils semblent tous échouer.
Voici le code que j'utilise pour le faire:
Appel d'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
Méthode:
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))
Quelqu'un pourrait-il m'expliquer, s'il vous plaît, pourquoi cela ne fonctionne pas? Merci d'avance.
La solution
Tout d'abord, votre signature de méthode est incorrecte, Single = Float alors que le paramètre d'origine est du type LPBUF.
Utilisez cette signature de méthode:
<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
Deuxièmement, je pense que le descripteur hProcess attend un descripteur ouvert par la fonction OpenProcess, et non le descripteur de fenêtre.
Autres conseils
Merci arul, j'ai en quelque sorte résolu mon problème.
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
Maintenant, il pense que le descripteur est valide et tente de lire la mémoire du processus, mais le message d'erreur 299 s'affiche: seule une partie d'une requête ReadProcessMemory ou WriteProcessMemory a été complétée.
Quelqu'un at-il une idée de la façon dont je devrais procéder pour résoudre ce problème?
message 299: Seule une partie d'une demande ReadProcessMemory ou WriteProcessMemory a été complétée signifie que la mémoire que je tentais de lire était protégée.
Merci pour toute votre aide, je vais marquer la réponse d’Arul comme étant la réponse.