Hi, i'm having trouble with a memory reader, it doesn't work with a address bigger than a INTEGER, i tried to change a lot of things to LONG but none works.
How to update the code to work with 64bit address?
Module
Option Strict On
Imports System.Runtime.InteropServices
Imports System.Text
Module MemoryModule
<DllImport("kernel32.dll")>
Private Function OpenProcess(ByVal dwDesiredAccess As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), ByVal nSize As IntPtr, <Out()> ByRef lpNumberOfBytesWritten As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <Out()> ByVal lpBuffer() As Byte, ByVal dwSize As IntPtr, ByRef lpNumberOfBytesRead As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Const PROCESS_VM_WRITE As UInteger = &H20
Private Const PROCESS_VM_READ As UInteger = &H10
Private Const PROCESS_VM_OPERATION As UInteger = &H8
'Target process name
Public TargetProcess As String = "XXXXXXXXXXX"
Public TargetIdd As Integer = 0
Public ProcessHandle As IntPtr = IntPtr.Zero
Public LastKnownPID As Integer = -1
Public handle_s As System.Diagnostics.Process
Public bAddress As Int64
Public ic As Int64
Public ch As Int64
Public AdrPrincipal As String = "2787AE0"
Public AdrCharN As String = "2787AE0"
Private Declare Function ReadMemoryByte Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Byte, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Byte
Private Declare Function ReadMemoryInteger Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Integer, Optional ByVal Size As Integer = 4, Optional ByRef Bytes As Integer = 0) As Integer
Private Declare Function ReadMemoryFloat Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Single, Optional ByVal Size As Integer = 4, Optional ByRef Bytes As Integer = 0) As Single
Private Declare Function ReadMemoryDouble Lib "kernel32" Alias "ReadProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Double, Optional ByVal Size As Integer = 8, Optional ByRef Bytes As Integer = 0) As Double
Private Declare Function WriteMemoryByte Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Byte, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Byte
Private Declare Function WriteMemoryInteger Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Integer, Optional ByVal Size As Integer = 4, Optional ByRef Bytes As Integer = 0) As Integer
Private Declare Function WriteMemoryFloat Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Single, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Single
Private Declare Function WriteMemoryDouble Lib "kernel32" Alias "WriteProcessMemory" (ByVal Handle As Integer, ByVal Address As Integer, ByRef Value As Double, Optional ByVal Size As Integer = 2, Optional ByRef Bytes As Integer = 0) As Double
Public Function ReadMemory(Of T)(ByVal address As Integer) As T
Return ReadMemory(Of T)(address, 0, False)
End Function
Public Function ReadMemory(ByVal address As Integer, ByVal length As Integer) As Byte()
Return ReadMemory(Of Byte())(address, length, False)
End Function
Private Function ProcessIDExists(ByVal pID As Integer) As Boolean
For Each p As Process In Process.GetProcessesByName(TargetProcess)
If p.Id = pID Then Return True
Next
Return False
End Function
Public Function ReadInteger(ByVal TargetIdd As Integer, ByVal Address As Integer) As Integer
Dim Value As Integer
Dim Handle As Integer = CInt(Process.GetProcessById(TargetIdd).Handle)
If Handle <> 0 Then
ReadMemoryInteger(Handle, Address, Value)
End If
Return Value
End Function
Public Function UpdateProcessHandle() As Boolean
If LastKnownPID = -1 OrElse Not ProcessIDExists(LastKnownPID) Then
If ProcessHandle <> IntPtr.Zero Then CloseHandle(ProcessHandle)
Dim p() As Process = Process.GetProcessesByName(TargetProcess)
If p.Length = 0 Then Return False
LastKnownPID = CInt(Form1.ComboBox1.Text)
ProcessHandle = OpenProcess(PROCESS_VM_READ Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, False, CInt(Form1.ComboBox1.Text))
If ProcessHandle = IntPtr.Zero Then Return False
End If
Return True
End Function
Public Function ReadMemory(Of T)(ByVal address As Integer, ByVal length As Integer, ByVal unicodeString As Boolean) As T
Dim buffer() As Byte
If GetType(T) Is GetType(String) Then
If unicodeString Then buffer = New Byte(length * 2 - 1) {} Else buffer = New Byte(length - 1) {}
ElseIf GetType(T) Is GetType(Byte()) Then
buffer = New Byte(length - 1) {}
Else
buffer = New Byte(Marshal.SizeOf(GetType(T)) - 1) {}
End If
If Not UpdateProcessHandle() Then Return Nothing
Dim success As Boolean = ReadProcessMemory(ProcessHandle, New IntPtr(address), buffer, New IntPtr(buffer.Length), IntPtr.Zero)
If Not success Then Return Nothing
If GetType(T) Is GetType(Byte()) Then Return CType(CType(buffer, Object), T)
If GetType(T) Is GetType(String) Then
If unicodeString Then Return CType(CType(Encoding.Unicode.GetString(buffer), Object), T)
Return CType(CType(Encoding.ASCII.GetString(buffer), Object), T)
End If
Dim gcHandle As GCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned)
Dim returnObject As T
returnObject = CType(Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject, GetType(T)), T)
gcHandle.Free()
Return returnObject
End Function
Private Function GetObjectBytes(ByVal value As Object) As Byte()
If value.GetType() Is GetType(Byte()) Then Return CType(value, Byte())
Dim buffer(Marshal.SizeOf(value) - 1) As Byte
Dim ptr As IntPtr = Marshal.AllocHGlobal(buffer.Length)
Marshal.StructureToPtr(value, ptr, True)
Marshal.Copy(ptr, buffer, 0, buffer.Length)
Marshal.FreeHGlobal(ptr)
Return buffer
End Function
Public Function WriteMemory(ByVal address As Integer, ByVal value As Object) As Boolean
Return WriteMemory(address, value, False)
End Function
Public Function WriteMemory(ByVal address As Integer, ByVal value As Object, ByVal unicode As Boolean) As Boolean
If Not UpdateProcessHandle() Then Return False
Dim buffer() As Byte
If TypeOf value Is String Then
If unicode Then buffer = Encoding.Unicode.GetBytes(value.ToString()) Else buffer = Encoding.ASCII.GetBytes(value.ToString())
Else
buffer = GetObjectBytes(value)
End If
Dim result As Boolean = WriteProcessMemory(ProcessHandle, New IntPtr(address), buffer, New IntPtr(buffer.Length), IntPtr.Zero)
Return result
End Function
End Module
Using
If Not ComboBox1.Text = "Lista de Clientes" Then
If UpdateProcessHandle() Then
Button1.Text = "Selecionado!"
ComboBox1.Enabled = False
ProcID = ComboBox1.Text
'Here when it will read, show error that the address is not integer
'&H19A07B80080
Dim myhp() As Byte = ReadMemory(CType(ReadInteger(ProcID, &H19A07B80080), String), 8)
Label16.Text = BitConverter.ToDouble(myhp, 0)
End If
End If