I was finally able to figure out my problem with pointers after reading the example page on Github for the project:
https://github.com/ffi/ffi/wiki/Examples
Specifically under the "Output Parameters with MemoryPointer" section. After reading that I was able to change my code to the following:
require 'ffi'
module Memory
PROC_READ = 0x10
PROC_WRITE = 0x20
PROC_RW = PROC_READ | PROC_WRITE
extend FFI::Library
ffi_lib 'kernel32'
ffi_convention :stdcall
attach_function :open, :OpenProcess, [:uint, :bool, :uint], :pointer
attach_function :close, :CloseHandle, [:pointer], :bool
attach_function :read, :ReadProcessMemory, [:pointer, :pointer, :pointer, :size_t, :pointer], :bool
attach_function :write, :WriteProcessMemory, [:pointer, :pointer, :pointer, :size_t, :pointer], :bool
attach_function :error, :GetLastError, [], :uint
end
# 1048 is a fixed pid currently
handle = Memory::open(Memory::PROC_RW, false, 1048)
puts "GetLastError: #{Memory::error()}"
# Output parameters for ReadProcessMemory
out = FFI::MemoryPointer.new :pointer
read = FFI::MemoryPointer.new :pointer
# Pointer holding the location to read from
addr = FFI::Pointer.new :pointer, 0x057C75F8
res = Memory::read(handle, addr, out, 4, read)
# get_pointer(0) grabs the pointer to the value
# address holds the value we actually want (at least in this case)
read = read.get_pointer(0).address
out = out.get_pointer(0).address
puts "GetLastError: #{Memory::error()}"
puts "ReadProcessMemory: #{res}"
puts "Bytes Read: #{read}"
puts "Value Read: #{out}"
Memory::close(handle)
The above code in my specific case correctly outputs the following:
GetLastError: 0
GetLastError: 0
ReadProcessMemory: true
Bytes Read: 4
Value Read: 10
I hope this will help someone in the future.