I have a few projects that deal with external processes and reading their data from memory. I wrote this function to read a structure from memory at a given address in any external process. It is generic so that any structure can be read. To use this function you must know the structure layout and the proper address in the remote process. I have not gotten into how to find the proper address to read or how to search for the process to use. This example is merely to show how to read any structure from any process with a single function.
WindowsAPI Class
vb.net Code:
Imports System.Runtime.InteropServices Public Class WindowsAPI Public Const PROCESS_ALL_ACCESS = &H1F0FFF <DllImport("kernel32.dll")> _ Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, <Out()> ByVal lpBuffer As Byte(), ByVal nSize As UIntPtr, ByVal lpNumberOfBytesRead As IntPtr) As Boolean End Function <DllImport("kernel32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto, SetLastError:=True)> _ Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal iSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True)> _ Public Shared Function OpenProcess(ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Boolean, ByVal dwProcessId As Integer) As IntPtr End Function <DllImport("kernel32.dll", SetLastError:=True)> _ Public Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean End Function End Class
MemoryScanner Class
vb.net Code:
Imports System.Runtime.InteropServices Public Class MemoryReader Public Shared Function GetStructure(Of T)(ByVal TargetProcess As Process, ByVal Address As Integer) As T 'Create a variable to store the number of bytes written Dim lpBytesWritten As Integer = 0 'Allocate memory to hold the structure Dim buffer As IntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(GetType(T))) 'Open the process for reading Dim procPtr As IntPtr = WindowsAPI.OpenProcess(WindowsAPI.PROCESS_ALL_ACCESS, False, TargetProcess.Id) 'Read the data into the previously created buffer WindowsAPI.ReadProcessMemory(procPtr, New IntPtr(Address), buffer, Marshal.SizeOf(GetType(T)), lpBytesWritten) 'Marshal the pointer to the return structure type Dim retValue As T = CType(Marshal.PtrToStructure(buffer, GetType(T)), T) 'Free up the allocated memory Marshal.FreeCoTaskMem(buffer) 'Close the process handle WindowsAPI.CloseHandle(procPtr) 'Return the object Return retValue End Function End Class
Example usage
vb.net Code:
Imports System.Runtime.InteropServices Public Class Class1 'This is an example structure. <StructLayout(LayoutKind.Sequential)> _ Public Structure SomeStruct Dim ID As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=24)> _ Dim Name As String End Structure Public Function GetStructure() As SomeStruct 'Get a process object 'Obviously this is not how it would be done, but for this 'example it will suffice Dim p As Process = Process.GetProcessById(100) 'Now we will read the structure form memory address 1000000 in or fake process Return MemoryReader.GetStructure(Of SomeStruct)(p, 1000000) End Function End Class




Reply With Quote