title: Reading Memory Address from a process with a Static Address and Offsets in Python
body: <p>I'm trying to read another process' memory in Python and I have the static address of the program and all the offsets. I'm using the <code>win32api</code> to do this. I can already read a process' memory with an address without offsets but I don't know how to use offsets. </p>
  
  <p>I've already tried the script in <a href="https://stackoverflow.com/a/25148501/5533085">this answer</a> but it returns -1. I've changed the <code>PROCESS_ALL_ACCESS</code> to <code>win32con.PROCESS_VM_READ</code> and even then it returns -1. </p>
  
  <p>How do I use the offsets with <code>ReadProcessMemory</code>?</p>
  
  <p>Here is the code I'm using: </p>
  
  <pre class="lang-py prettyprint-override"><code>import win32api
  import win32process
  import win32con
  import ctypes
  import ctypes.wintypes as wintypes
  
  
  def get_process_by_name(process_name):
      """Find the process id of the given
      process name and returns the process id."""
  
      process_name = process_name.lower()
  
      # Enumerate all processes
      processes = win32process.EnumProcesses()
  
      for process_id in processes:
          # If process_id is the same as this program, skip it
          if process_id == -1:
              continue
  
          # Try to read the process memory
          try:
              p_handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, True, process_id)
  
              # Try to read the modules of the process
              try:
                  modules = win32process.EnumProcessModules(p_handle)
  
                  for module_id in modules:
                      name = str(win32process.GetModuleFileNameEx(p_handle, module_id))
  
                      if name.lower().find(process_name) != -1:
                          return process_id
              finally:
                  win32api.CloseHandle(p_handle)
          except:
              pass
  
  
  def read_process_memory(process_id, address, offsets, size_of_data=4):
  
      p_handle = ctypes.windll.kernel32.OpenProcess(win32con.PROCESS_VM_READ, False, p_id)
  
      data = ctypes.c_uint(size_of_data)
      bytesRead = ctypes.c_uint(size_of_data)
  
      current_address = address
  
      if offsets:
          # Do something to the offsets
          ctypes.windll.kernel32.ReadProcessMemory(p_handle, current_address, ctypes.byref(data), ctypes.sizeof(data), ctypes.byref(bytesRead))
  
      else:
          ctypes.windll.kernel32.ReadProcessMemory(p_handle, current_address, ctypes.byref(data), ctypes.sizeof(data), ctypes.byref(bytesRead))
  
  
      # Close the handle to the process
      ctypes.windll.kernel32.CloseHandle(p_handle)
  
      return data.value
  
  p_id = get_process_by_name("program.exe")
  
  # Without offsets it works fine
  address = 0x2ADB1818
  val = read_process_memory(p_id, address, None)
  print(val)
  
  
  # Does not point to the correct address
  address = 0x00571160
  offsets = [0xD84, 0x1B8, 0x38, 0x5C, 0x24, 0xF4, 0x1D08]
  for offset in offsets:
      address += offset
  
  val = read_process_memory(p_id, address, offsets)
  print(val)
  </code></pre>