The easiest operation to perform is to access the process's address space. (Since threads exist in the context of a process and have access to everything within a process, there's no need to consider threads in this discussion.)
You can use the read(), write(), and lseek() functions to access the process's address space. The read() function transfers bytes from the current position within the process to the program issuing the read(), and write() transfers bytes from the program to the process.