title: Reading memory from an application I do not own in C++ (example in vb.net)
body: <p>A couple of months ago, before I started learning C++, I made an application in VB.net that reads memory from an external program. This could be anything, from notepad to windows media player etc.</p>
  
  <p>I have been trying to find a way to do the exact same thing in C++, but to my suprise I can't find anything straightforward on the subject. All google comes up with is threads on several forums, where the general response is "Windows doesn't allow you to read from memory you do not own". But if it works in VB.net, it can work in C++ too.</p>
  
  <p>Don't be fooled by the amount of code, it's extremely straightforward.</p>
  
  <p><strong>Declarations</strong></p>
  
  <pre><code>Imports System.Math
  Imports System.Threading
  Imports System.Runtime.InteropServices
  
  //Guess what this does ;D
  Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer
  
  //Allows us to read a float from the memory.
  Private Declare Function ReadProcessMemory Lib "kernel32" _
  Alias "ReadProcessMemory" (ByVal hProcess As Integer, _
                             ByVal lpBaseAddress As Integer, _
                             ByRef lpBuffer As Single, _
                             ByVal nSize As Integer, _
                             ByRef lpNumberOfBytesWritten As Integer) As Integer
  
  //Allows us to read an integer or string from the memory. String will require a loop.
  Private Declare Function ReadProcessMemoryInt Lib "kernel32" _
      Alias "ReadProcessMemory" (ByVal hProcess As Integer, _
                                 ByVal lpBaseAddress As Integer, _
                                 ByRef lpBuffer As Integer, _
                                 ByVal nSize As Integer, _
                                 ByRef lpNumberOfBytesWritten As Integer) As Integer
  
  //Allows us to find a memory address when provided with a pointer and offsets
  Private Declare Function ReadProcessMemoryPointer Lib "kernel32" Alias "ReadProcessMemory" ( _
     ByVal hProcess As IntPtr, _
     ByVal lpBaseAddress As IntPtr, _
     &lt;Out()&gt; ByVal lpBuffer() As Byte, _
     ByVal dwSize As Integer, _
     ByRef lpNumberOfBytesRead As Integer) As Boolean
  
  //Close a handle
  Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
  
  //Shortcut to get read &amp; write access to an application
  Const PROCESS_ALL_ACCESS = &amp;H1F0FFF
  </code></pre>
  
  <p><strong>Functions using these Declarations</strong></p>
  
  <pre><code>//Function to get string from memory
  Public Function memstring(ByVal address As Long, ByVal length As Int32, ByVal processHandle As IntPtr)
      Dim stringinmemory As Long
      Dim ret1 As Byte() = Nothing
      Dim tStr(length) As Char
      Dim retStr As String = ""
      For i As Int32 = 0 To length - 1
          ReadProcessMemoryInt(processHandle, address + i, stringinmemory, 1, 0)
          ret1 = BitConverter.GetBytes(stringinmemory)
          tStr(i) = System.Text.Encoding.ASCII.GetString(ret1) : retStr += tStr(i)
      Next
      Return retStr
  End Function
  
  //Function to get float from memory. I don't know what those comments are all about, it's been a long time since I used this code.
  Public Function memfloat(ByVal address As Long, ByVal processHandle As IntPtr)
      Dim floatvalueinmemory As Single
      ReadProcessMemory(processHandle, address, floatvalueinmemory, 4, 0)
      //Floatvalueinmemory didn't give the desired result, so going to try to TryParse
      Dim letstryagain As Single
      Single.TryParse(floatvalueinmemory, letstryagain)
      //Unfortunately returns the same result as floatvalueinmemory did
      Return CStr(letstryagain)
  End Function
  
  //Function to get int from memory
  Public Function memInt(ByVal address As Long, ByVal processHandle As IntPtr)
      Dim intvalueinmemory As Integer
      ReadProcessMemoryInt(processHandle, address, intvalueinmemory, 4, 0)
      Return CStr(intvalueinmemory)
  End Function
  
  //Function to find a memory address when provided with a pointer and offsets
  Private Function FindAddress(ByVal pHandle As IntPtr, ByVal BaseAddress As IntPtr, ByVal StaticPointer As IntPtr, ByVal Offsets() As IntPtr) As IntPtr
      // Create a buffer that is 4 bytes on a 32-bit system or 8 bytes on a 64-bit system.
      Dim tmp(IntPtr.Size - 1) As Byte
      Dim Address As IntPtr = BaseAddress
      // We must check for 32-bit vs 64-bit.
      If IntPtr.Size = 4 Then
          Address = New IntPtr(Address.ToInt32 + StaticPointer.ToInt32)
      Else
          Address = New IntPtr(Address.ToInt64 + StaticPointer.ToInt64)
      End If
      // Loop through each offset to find the address
      For i As Integer = 0 To Offsets.Length - 1
          ReadProcessMemoryPointer(pHandle, Address, tmp, IntPtr.Size, 0)
          If IntPtr.Size = 4 Then
              Address = BitConverter.ToInt32(tmp, 0) + Offsets(i).ToInt32()
          Else
              Address = BitConverter.ToInt64(tmp, 0) + Offsets(i).ToInt64()
          End If
      Next
      Return Address
  End Function
  </code></pre>
  
  <p><strong>Example usage</strong></p>
  
  <pre><code>Sub somesub()
      //Get process handle.
      Dim myProcesses As Process() = Process.GetProcessesByName("SomeProgram")
      Dim processHandle As IntPtr = OpenProcess(PROCESS_ALL_ACCESS, 0, myProcesses(0).Id)
  
      //We'll need the base address when we need to find an address through pointers.
      BaseAddressSet = myProcesses(0).MainModule.BaseAddress
  
      //Get float from memory.
      somefloat = memfloat(&amp;H12980D8, processHandle)
  
      //Get string from memory.
      somestring = memstring(&amp;H12955E0, 15, processHandle)
  
      //Get float from memory through a pointer.
      Dim sptr As IntPtr = &amp;HF28EE4 //Static pointer for float address we want to get
      Dim Offsets As IntPtr() = {&amp;H61C, &amp;H19C, &amp;H2AC, &amp;HDC, &amp;H198} //Offsets for float address we want to get
      Dim addr As IntPtr = FindAddress(processHandle, BaseAddressSet, sptr, Offsets)
      somefloat = memfloat(addr, processHandle)
  
      //All done.
      CloseHandle(processHandle)
   End Sub
  </code></pre>
  
  <p><strong>Footer</strong></p>
  
  <pre><code>Partial Public Class NativeMethods
      &lt;DllImport("user32.dll")&gt; _
      Public Shared Function ReadProcessMemory(ByVal hProcess As System.IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As System.IntPtr, ByVal nSize As UInteger, ByVal lpNumberOfBytesRead As IntPtr) As Boolean
      End Function
  End Class
  </code></pre>
  
  <p>Please advise on how to do this in C++, or where I can learn how to do this.</p>