I'm looking for an efficient way to access(for both read and write operations) the memory space of my ptraced child process. The size of blocks being accessed may vary from several bytes up to several megabytes in size, so using the ptrace call with PTRACE_PEEKDATA
and PTRACE_POKEDATA
which read only one word at a time and switch context every time they're called seems like a pointless waste of resources. The only one alternative solution I could find, though, was the /proc/<pid>/mem
file, but it has long since been made read only.
Is there any other (relatively simple) way to do that job? The ideal solution would be to somehow share the address space of my child process with its parent and then use the simple memcpy call to copy data I need in both directions, but I have no clues how to do it and where to begin.
Any ideas?
Consider injecting of some debug function into ptraced process and calling it via ptrace_setregs. Something like the way how gdb can run any function of ptraced process.
Also you can try to inject some code into process via LD_PRELOAD. You can even try to make in work without ptrace, using signals.
upd1: Gdb injection or "inferior function call" is rather complicated. See function call_function_by_hand in file gdb-6.6.50.20070809›gdb›infcall.c here: http://sources.debian.net/src/gdb/7.6.2-1/gdb/infcall.c?hl=462#L462
For reading, your best bet is to parse the
/proc/<pid>/maps
file for the virtual addresses of the memory regions of interest.You can then read these by opening
/proc/<pid>/mem
and performread()
call with a large buffer on areas of interest.For writing, I've yet to find an easy way to write entire blocks, I believe this has to do with locking and stability for the child process, calls through
ptrace()
can guarantee this, but direct access to another process' memory cannot. I typically write a wrapper aroundptrace(PTRACE_POKEDATA, ...)
to mirror Windows'WriteProcessMemory()
.If this is Linux (which the tags suggest it is), you can share the entirety of the child's address space with the parent by using
clone()
with theCLONE_VM
flag. As the two processes share the same VM space, all modifications will be immediately visible between the two, with essentially zero overhead.This does mean you can't then
exec()
in the child; as it will replace the VM space of both processes.If you're in control of the child process, maybe you could add a debug interface that allows you to write to the memory in question?
Are you in control of the child process and its sourcecode? If so, you could consider using Shared memory.
clone or mmap are what you are looking for. mmap a temp file between the two processes and use that memory space for passing data back and forth.