0

I'm having some trouble reading from an arbitrary memory address using Chez Scheme's FFI and the kernel32/user32.dll's ReadProcessMemory function. I got the process handle and everything fine, but I'm struggling with quite a few aspects of the read function itself:

(define (read-process-memory handle address size)
  ((foreign-procedure "ReadProcessMemory" (iptr iptr string int iptr) iptr)
   handle address byte-array size output-ptr))

(define address (make-ftype-pointer iptr #x14a24d63660))

(read-process-memory process-handle address 4)

From this I get Exception in read-process-memory: invalid foreign-procedure argument #<ftype-pointer iptr 1417957226080>, but I'm pretty sure I'm approaching a lot of things about this wrong.

Thanks in advance

General Grievance
  • 4,555
  • 31
  • 31
  • 45
ArooBaito
  • 1
  • 2

1 Answers1

0

This works:

(define (read-process-memory handle address size)
  (let ((temp-buffer (foreign-alloc size)))
    (set! success ((foreign-procedure "ReadProcessMemory" (unsigned-32 unsigned-32 uptr unsigned-32 u8*) boolean)
            handle address temp-buffer size #f))
    (set! result (foreign-ref 'unsigned-32 temp-buffer 0))
    (foreign-free temp-buffer)))

Like other implementations, the process-handle and the address can just be unsigned-32's rather than a pointer, so I switched those types, same for the size although that wasn't necessary. The return type should be a boolean, not a pointer, I wasn't paying attention. The boolean indicates the success of the memory read.

Although passing in a string for the buffer works in some implementations, in Chez it does not mutate the string, most likely because it's not passed by reference. The proper solution is to make it accept a uptr instead, (foreign-alloc the size you need, and since that will pass in its own address, it will be mutated correctly and then you can get the answer back with (foreign-ref, which I store in result, then free the allocated memory.

Also it's worth mentioning the address in my original question is a 64-bit address, so an unsigned-64 needs to be used in order to properly access that address.

ArooBaito
  • 1
  • 2