ReadProcessMemory продолжает возвращать 0

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
4 194
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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, а не дескриптор окна.

Спасибо, арул, я вроде как решил свою проблему.

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.

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

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

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

Другие вопросы по теме