2008-12-06 2 views
1

В настоящее время я разрабатываю небольшой проект хобби для отображения информации о здоровье в игре на моей клавиатуре G15 через VB.NET.ReadProcessMemory продолжает возвращаться 0

Когда я использую ReadProcessMemory через вызов API, он продолжает возвращать ноль. В документации MSDN мне было предложено использовать вызов Marshal.GetLastWin32Error(), чтобы выяснить, что не так, и возвращает 1400: INVALID WINDOW HANDLE.

Теперь я запутался в том, нужен ли первый аргумент функции дескриптору окна или идентификатору процесса. Несмотря на это, я попытался использовать FindWindow и hardcoding идентификатор процесса во время работы приложения (получение его из диспетчера задач).

Я пробовал три разные игры, Urban Terror, Grand Theft Auto: SA и 3D пинбол для Windows, получая адреса памяти из приложения под названием 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)) 

Может кто-нибудь, пожалуйста, объясните мне, почему он не работает ? Заранее спасибо.

ответ

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, а не оконной ручки.

+0

Я попробую это, спасибо. – RodgerB 2008-12-06 22:53:11

1

Спасибо, арул, у меня есть проблемы с исправлением.

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 была завершена.

Есть ли у кого-нибудь идеи относительно того, как я должен исправить эту проблему?

1

сообщение 299: только часть запроса ReadProcessMemory или WriteProcessMemory была завершена, так как память, которую я пыталась прочитать, была защищена.

Спасибо за вашу помощь, я собираюсь отметить ответ arul в качестве ответа.