【问题标题】:Read/WriteProcessMemory in RubyRuby 中的读/写进程内存
【发布时间】:2013-11-25 15:15:22
【问题描述】:

我一直在尝试在 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,但outread 变量不会改变。

我希望这已经足够清楚了。我可以尝试澄清是否缺少某些东西。

【问题讨论】:

    标签: ruby winapi ffi readprocessmemory


    【解决方案1】:

    在阅读了 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
    

    我希望这对将来的某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 2015-12-22
      • 2014-01-31
      相关资源
      最近更新 更多