Domanda

Attualmente sto sviluppando un piccolo progetto hobby per visualizzare informazioni sulla salute in un gioco sulla mia tastiera G15 tramite VB.NET.

Quando utilizzo ReadProcessMemory tramite una chiamata API, continua a restituire zero. La documentazione MSDN mi ha fatto riferimento per utilizzare la chiamata Marshal.GetLastWin32Error () per scoprire cosa non va e restituisce 1400: MANIGLIA FINESTRA NON VALIDA.

Ora sono confuso sul fatto che il primo argomento della funzione voglia un handle di finestra o un ID processo. Indipendentemente da ciò, ho provato sia con FindWindow sia a codificare l'ID del processo mentre l'applicazione è in esecuzione (ottenerlo dal task manager).

Ho provato tre diversi giochi, Urban Terror, Grand Theft Auto: SA e 3D flipper per Windows, ottenendo gli indirizzi di memoria da un'applicazione chiamata Cheat Engine; sembrano tutti fallire.

Ecco il codice che sto usando per farlo:

Chiamata 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

Metodo:

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

Qualcuno potrebbe spiegarmi perché non funziona? Grazie in anticipo.

È stato utile?

Soluzione

Innanzitutto, la firma del metodo è errata, Single = Float mentre il parametro originale è del tipo LPBUF.

Usa questa firma del metodo:

<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

In secondo luogo, credo che l'handle hProcess prevede un handle aperto dalla funzione OpenProcess, non l'handle della finestra.

Altri suggerimenti

Grazie arul, ho risolto il mio 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

Ora ritiene che l'handle sia valido e tenta di leggere la memoria dei processi, ma viene visualizzato il messaggio di errore 299: È stata completata solo una parte di una richiesta ReadProcessMemory o WriteProcessMemory.

Qualcuno ha qualche idea su come dovrei procedere per risolvere questo problema?

messaggio 299: solo una parte di una richiesta ReadProcessMemory o WriteProcessMemory è stata completata significa che la memoria che stavo cercando di leggere era protetta.

Grazie per tutto il tuo aiuto, segnerò la risposta di Arul come risposta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top