none
How do I read and export a processes memory addresses + their strings? RRS feed

  • Question

  • I need to scan through a processes memory and check if certain strings exist, how would I do this in vb.net?

    With a program like ProcessHacker, you can specify a process to view it's memory, then search through that memory for all available strings + their memory addresses.

    I already have a memory class, i'm just not sure how I could use it to view all of the process memory, with the class I can search for a specific address and then retrieve the string from that address, but I'd like this process to be automatic as memory addresses change each time the process is started.

    Any help would be greatly appreciated!

    I previously had images to try and explain what I mean, however my account is not allowed to post images/links.

    Here is my memory class:
    Imports System.Runtime.ConstrainedExecution
    Imports System.Runtime.InteropServices
    Imports System.Security
    Imports System.Text
    
    Public NotInheritable Class mem
    
    #Region "WinAPI"
        <DllImport("kernel32.dll", SetLastError:=True)>
        Public Shared Function ReadProcessMemory(
        ByVal hProcess As Integer,
        ByVal lpBaseAddress As Integer,
        <Out()> ByVal lpBuffer As Byte(),
        ByVal dwSize As Integer,
        ByRef lpNumberOfBytesRead As Integer) As Boolean
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)>
        Public Shared Function WriteProcessMemory(
        ByVal hProcess As Integer,
        ByVal lpBaseAddress As Integer,
        ByVal lpBuffer As Byte(),
        ByVal nSize As Int32,
        <Out()> ByRef lpNumberOfBytesWritten As Integer) As Boolean
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)>
        Public Shared Function OpenProcess(
        ByVal dwDesiredAcces As Integer,
        ByVal bInheritHandle As Boolean,
        ByVal processID As Integer
         ) As Integer
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)>
        <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)>
        <SuppressUnmanagedCodeSecurity>
        Public Shared Function CloseHandle(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    #End Region
    
        Private Shared pProcess As Process()
        Private Shared ProcHandle As Integer
    
        Public Shared Function Setup(ProcessName As String) As Boolean
            pProcess = Process.GetProcessesByName(ProcessName)
            If pProcess.Length > 0 Then
                ProcHandle = OpenProcess(2035711, False, pProcess(0).Id)
            End If
            Return False
        End Function
    
        Public Shared Function rdMem(Offset As Integer, Size As Integer) As Byte()
            Dim buffer As Byte() = New Byte(Size - 1) {}
            ReadProcessMemory(ProcHandle, Offset, buffer, Size, 0)
            Return buffer
        End Function
    
        Public Shared Sub WrtMem(pOffset As Integer, pBytes As Byte())
            WriteProcessMemory(ProcHandle, pOffset, pBytes, pBytes.Length, 0)
        End Sub
    
        Public Shared Function rdInt(pOffset As Integer) As Integer
            Return BitConverter.ToInt32(rdMem(pOffset, 4), 0)
        End Function
    
        Public Shared Sub WrtInt(pOffset As Integer, pBytes As Integer)
            WrtMem(pOffset, BitConverter.GetBytes(pBytes))
        End Sub
    
        Public Shared Function rdFloat(pOffset As Integer) As Single
            Return BitConverter.ToSingle(rdMem(pOffset, 4), 0)
        End Function
    
        Public Shared Sub WrtFloat(pOffset As Integer, pBytes As Single)
            WrtMem(pOffset, BitConverter.GetBytes(pBytes))
        End Sub
    
        Public Shared Sub WrtByte(pOffset As Integer, pBytes As Byte)
            WrtMem(pOffset, BitConverter.GetBytes(CShort(pBytes)))
        End Sub
    
        Public Shared Function ReadMemory(Of T)(address As Integer) As T
            Dim buffer As Byte()
            Dim length As Integer = Marshal.SizeOf(GetType(T))
    
            If GetType(T) Is GetType(Byte()) Then
                buffer = New Byte(length - 1) {}
            Else
                buffer = New Byte(Marshal.SizeOf(GetType(T)) - 1) {}
            End If
    
            If Not ReadProcessMemory(ProcHandle, New IntPtr(address), buffer, New IntPtr(buffer.Length), IntPtr.Zero) Then Return Nothing
    
            If GetType(T) Is GetType(Byte()) Then Return CType(CType(buffer, Object), T)
    
            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
    
        Public Shared Function rdString(address As Integer) As String
            Dim buffer As Byte() = New Byte(27) {}
            ReadProcessMemory(ProcHandle, address, buffer, buffer.Length, 0)
            Return Encoding.Unicode.GetString(buffer).Trim
        End Function
    
        Public Shared Function rdStringASCII(address As Integer) As String
            Dim buffer As Byte() = New Byte(27) {}
            ReadProcessMemory(ProcHandle, address, buffer, buffer.Length, 0)
            Return Encoding.ASCII.GetString(buffer).Trim
        End Function
    
        Public Shared Sub WriteStruct(Of T)(address As Integer, mystruct As T)
            Dim Ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(mystruct))
            Dim ByteArray(Marshal.SizeOf(mystruct) - 1) As Byte
    
            Marshal.StructureToPtr(mystruct, Ptr, False)
    
            Marshal.Copy(Ptr, ByteArray, 0, Marshal.SizeOf(mystruct))
            Marshal.FreeHGlobal(Ptr)
    
            WrtMem(address, ByteArray)
        End Sub
    End Class


    • Edited by User5070 Tuesday, November 14, 2017 7:04 PM
    Tuesday, November 14, 2017 7:02 PM

All replies

  • Hi User5070,

    According to your description, you can get specific processes and fins a string in memory, If you want to get all processes that currently running, you can use Process.GetProcesses, then you loop these processes to get memory

     For Each OneProcess As Process In Process.GetProcesses
    
            Next

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 16, 2017 9:58 AM
    Moderator
  • VB is not made for what you want to do. 

    The code you show is simple a kind of wrapper around different Win32 API's. 

    If you really want to follow a process in memory use then Intel Assembler.

    https://software.intel.com/en-us/articles/intel-sdm

    VB is a so called high level program language to solve human problems with a computer. 

    VB is not a low level program language to invest low level situation in memory. 


    Success
    Cor


    Thursday, November 16, 2017 10:28 AM