Как передать указатели в Ruby и FFI? - PullRequest
0 голосов
/ 25 января 2019

Я думаю, что я неправильно использую указатели, а GetLastError() не сообщает мне об ошибке более подробно.

Я действительно не знаю, как работают указатели, между FFI::Pointer и FFI::MemoryPointer

require 'ffi'

module Win32
    extend FFI::Library

    PROCESS_VM_READ = 0x0010
    PROCESS_VM_WRITE = 0x0020
    PROCESS_ALL_ACCESS = PROCESS_VM_READ | PROCESS_VM_WRITE

    ffi_lib 'kernel32'
    ffi_convention :stdcall

    attach_function :OpenProcess, [:uint, :bool, :uint], :pointer
    attach_function :CloseHandle, [:pointer], :bool
    attach_function :ReadProcessMemory, [:pointer, :pointer, :pointer, :size_t, :pointer], :int
    attach_function :WriteProcessMemory, [:pointer, :pointer, :pointer, :size_t, :pointer], :int
    attach_function :GetLastError, [], :uint

    class << self
        def read(handle, address)
            addr = FFI::Pointer.new(:pointer, address)
            buffer = FFI::MemoryPointer.new(:pointer)
            if ReadProcessMemory(handle, addr, buffer, 4, nil) == 0
                puts "Error: #{GetLastError()}"
            end
            return buffer.get_int(0)
        end
        def write(handle, address, value)
            addr = FFI::Pointer.new(:pointer, address)
            buffer = FFI::MemoryPointer.new(:long, 4)
            buffer.put_int(0, value)
            if WriteProcessMemory(handle, addr, buffer, 4, nil) == 0
                "Error: #{GetLastError()}"
            end
        end
    end
end

pid = 4984
handle = Win32.OpenProcess(Win32::PROCESS_ALL_ACCESS, false, pid)

puts Win32.read(handle, 0x0192D514) # => 45
puts Win32.write(handle, 0x0192D514, 20) # => Error: 0
puts Win32.read(handle, 0x0192D514) # => 45

Win32.CloseHandle(handle)

Выход:

45
Error: 0
45

1 Ответ

0 голосов
/ 27 января 2019

Я нашел проблему, это было разрешение доступа дескриптора, измените:

handle = Win32.OpenProcess(Win32::PROCESS_ALL_ACCESS, false, pid)

до

handle = Win32.OpenProcess(Win32::PROCESS_VM_OPERATION | Win32::PROCESS_ALL_ACCESS, false, pid)

и добавьте в модуль Win32:

PROCESS_VM_OPERATION = 0x0008

Надеюсь, это кому-нибудь поможет, спасибо!

...