Pergunta

Atualmente, estou desenvolvendo um pequeno projeto de hobby para exibir informações de saúde em um jogo no meu teclado G15 através do VB.NET.

Quando uso o ReadProcessMemory por meio de uma chamada da API, ele continua retornando zero. A documentação do MSDN me encaminhou para usar a chamada marshal.getLastwin32error () para descobrir o que está errado e retorna 1400: identificador de janela inválido.

Agora estou confuso sobre se o primeiro argumento da função deseja um identificador de janela ou um ID do processo. Independentemente disso, tentei tanto com o FindWindow quanto o codificação do ID do processo enquanto o aplicativo está em execução (obtendo -o do gerenciador de tarefas).

Eu tentei três jogos diferentes, Terror Urbano, Grand Theft Auto: SA e 3D Pinball para Windows, obtendo os endereços de memória de um aplicativo chamado Cheat Engine; Todos eles parecem falhar.

Aqui está o código que estou usando para fazer isso:

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

Alguém poderia me explicar por que não está funcionando? Desde já, obrigado.

Foi útil?

Solução

Primeiro, a assinatura do seu método está errada, single = float enquanto o parâmetro original é do tipo LPBUF.

Use esta assinatura do 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, acredito que a alça do HPROCESS espera uma alça aberta pela função OpenProcess, não pela alça da janela.

Outras dicas

Obrigado Arul, eu meio que corrigi meu 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

Agora acredita que o identificador é válido e tenta ler a memória dos processos, mas recebo a mensagem de erro 299: apenas parte de uma solicitação ReadProcessMemory ou WriteProcessMemory foi concluída.

Alguém tem alguma idéia de como devo proceder para corrigir esse problema?

Mensagem 299: apenas parte de uma solicitação ReadProcessMemory ou WriteProcessMemory foi concluída significava que a memória que eu estava tentando ler estava protegida.

Obrigado por toda a sua ajuda, vou marcar a resposta de Arul como resposta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top