我一直在尝试在Ruby中读取和编写进程内存,希望将一些旧的C ++程序转换为更动态的语言。但是我一直没有轻松过去。我已经做了一些阅读,但我找不到我的具体问题。我可能在下面有一些非常基本的错误,因为我不太确定指针管理在Ruby-ffi中是如何工作的。
无论如何,我目前安装了ffi
gem并且一直在使用它来获取功能。这就是我所拥有的:
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
似乎当我调用Memory.open时,我得到一个正确的句柄。我不太确定,但这里是存储结果的变量的输出,以防我错了。
#<FFI::Pointer address=0x00000000000150>
这是我目前的完整代码:
# 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)
这打印出以下内容:
GetLastError: 0
GetLastError: 0
ReadProcessMemory: false
0
0
我知道我必须做一些根本错误的指针变量。如果我将addr
更改为FFI::Pointer
类型的:uint
和值loc
,则ReadProcessMemory会返回true
,但out
和read
变量不会改变。
我希望这已经足够清楚了。我可以尝试澄清是否有遗漏。
答案 0 :(得分:5)
在阅读Github上的示例页面后,我终于能够找出指针的问题:
https://github.com/ffi/ffi/wiki/Examples
具体在“带MemoryPointer的输出参数”部分下。在阅读之后,我能够将我的代码更改为以下内容:
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)
我特定情况下的上述代码正确输出以下内容:
GetLastError: 0
GetLastError: 0
ReadProcessMemory: true
Bytes Read: 4
Value Read: 10
我希望这将有助于将来。