Pregunta

Actualmente estoy desarrollando un pequeño proyecto de pasatiempo para mostrar información de salud en un juego en mi teclado G15 a través de VB.NET.

Cuando uso ReadProcessMemory a través de una llamada API, sigue devolviendo cero. La documentación de MSDN me refirió a usar la llamada Marshal.GetLastWin32Error () para averiguar qué está mal y devuelve 1400: MANGO DE VENTANA NO VÁLIDO.

Ahora estoy confundido acerca de si el primer argumento de la función quiere un identificador de ventana o una identificación de proceso. De todos modos, he intentado con FindWindow y codificar la identificación del proceso mientras la aplicación se está ejecutando (obteniéndola del administrador de tareas).

He probado tres juegos diferentes, Urban Terror, Grand Theft Auto: SA y 3D pinball para Windows, obteniendo las direcciones de memoria de una aplicación llamada Cheat Engine; todos parecen fallar.

Aquí está el código que estoy usando para hacerlo:

Llamada 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étodo:

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))

¿Podría alguien explicarme por qué no funciona? Gracias de antemano.

¿Fue útil?

Solución

Primero, la firma de su método es incorrecta, Single = Float mientras el parámetro original es del tipo LPBUF.

Utilice la firma de este método:

<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

Segundo, creo que el identificador hProcess espera un identificador abierto por la función OpenProcess, no el identificador de ventana.

Otros consejos

Gracias Arul, he solucionado mi problema.

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

Ahora cree que el identificador es válido e intenta leer la memoria de procesos, pero recibo el mensaje de error 299: solo se completó parte de una solicitud ReadProcessMemory o WriteProcessMemory.

¿Alguien tiene alguna idea de cómo debo proceder para solucionar este problema?

mensaje 299: solo una parte de una solicitud ReadProcessMemory o WriteProcessMemory se completó significaba que la memoria que intentaba leer estaba protegida.

Gracias por toda su ayuda, voy a marcar la respuesta de arul como la respuesta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top