title: Read/WriteProcessMemory in Ruby
body: <p>I have been experimenting with reading and writing process memory in Ruby in hopes to move some old C++ programs to a more dynamic language. However I've not been having an easy time moving over. I've done some reading but I can't find much on my specific problem. I probably have some pretty fundamental mistakes below as I'm not too sure how pointer management works in Ruby-ffi.</p>
  
  <p>Anyway, I currently have the <code>ffi</code> gem installed and have been using that to grab functions. This is what I have:</p>
  
  <pre><code>module Memory
    PROC_READ = 0x10
    PROC_WRITE = 0x20
    PROC_RW = PROC_READ | PROC_WRITE
  
    extend FFI::Library
  
    ffi_lib 'kernel32'
  
    # HANDLE WINAPI OpenProcess(DWORD, BOOL, DWORD)
    attach_function :open, :OpenProcess, [:uint, :bool, :uint], :pointer
  
    # BOOL WINAPI CloseHandle(HANDLE)
    attach_function :close, :CloseHandle, [:pointer], :bool
  
    # BOOL WINAPI ReadProcessMemory(HANDLE, LPCVOID, out LPVOID, SIZE_T, out SIZE_T)
    attach_function :read, :ReadProcessMemory, [:pointer, :pointer, :pointer, :int, :int], :bool
  
    # BOOL WINAPI WriteProcessMemory(HANDLE, LPCVOID, LPVOID, SIZE_T, out SIZE_T)
    attach_function :write, :WriteProcessMemory, [:pointer, :pointer, :pointer, :int, :int], :bool
  
    # DWORD WINAPI GetLastError(void)
    attach_function :error, :GetLastError, [], :uint
  end
  </code></pre>
  
  <p>It seems that when I call Memory.open I get a correct handle. I'm not quite sure, but here's the output of a variable storing the result in-case I'm wrong.</p>
  
  <pre><code>#&lt;FFI::Pointer address=0x00000000000150&gt;
  </code></pre>
  
  <p>Here's the full code I have currently:</p>
  
  <pre><code># 1048 is a fixed pid currently
  handle = Memory::open(Memory::PROC_RW, false, 1048)
  puts "GetLastError: #{Memory::error()}"
  
  # Address to read from
  loc = 0x057C75F8
  
  out = 0
  read = 0
  
  # Supposed to be the address of out to store the value read
  val = FFI::MemoryPointer.new :uint, out
  
  # Supposed to be a pointer to loc which holds the address to read from
  addr = FFI::MemoryPointer.new :pointer, loc
  
  res = Memory::read(handle, addr, val, 4, read)
  
  puts "GetLastError: #{Memory::error()}"
  puts "ReadProcessMemory: #{res}"
  puts read
  puts out
  
  Memory::close(handle)
  </code></pre>
  
  <p>This prints out the following:</p>
  
  <pre><code>GetLastError: 0
  GetLastError: 0
  ReadProcessMemory: false
  0
  0
  </code></pre>
  
  <p>I know I must be doing something fundamentally wrong with the pointer variables. If I change <code>addr</code> to an <code>FFI::Pointer</code> of type <code>:uint</code> and value <code>loc</code> then ReadProcessMemory returns <code>true</code>, but the <code>out</code> and <code>read</code> variables do not change.</p>
  
  <p>I hope this has been clear enough. I can try to clarify if something seems like it's missing.</p>