<p>I've been trying to understand how to read the memory of other processes on Mac OS X, but I'm not having much luck. I've seen many examples online using <code>ptrace</code> with <code>PEEKDATA</code> and such, however it doesn't have that option on BSD <sup>[<a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/ptrace.2.html" rel="noreferrer"><code>man ptrace</code></a>]</sup>.</p>

<pre><code>int pid = fork();
if (pid &gt; 0) {
    // mess around with child-process's memory
}
</code></pre>

<p>How is it possible to read from and write to the memory of another process on Mac OS X?</p>

[{'answer_id': 10676, 'author': 'Derek Park', 'author_id': 872, 'author_profile': 'https://Stackoverflow.com/users/872', 'pm_score': 4, 'selected': False, 'text': '<p>Matasano Chargen had a good post a while back on porting some debugging code to OS X, which included learning how to read and write memory in another process (among other things).</p>\n\n<p><a href="http://replay.web.archive.org/20090627062246/http://www.matasano.com/log/1100/what-ive-been-doing-on-my-summer-vacation-or-it-has-to-work-otherwise-gdb-wouldnt/" rel="nofollow noreferrer">It has to work, otherwise GDB wouldn\'t</a>:</p>\n\n<blockquote>\n  <p>It turns out Apple, in their infinite wisdom, had gutted <code>ptrace()</code>. The OS X man page lists the following request codes:</p>\n  \n  <ul>\n  <li><code>PT_ATTACH</code> — to pick a process to debug</li>\n  <li><code>PT_DENY_ATTACH</code> — so processes can stop themselves from being debugged<br>\n  [...]</li>\n  </ul>\n  \n  <p>No mention of reading or writing memory or registers. Which would have been discouraging if the man page had not also mentioned <code>PT_GETREGS</code>, <code>PT_SETREGS</code>, <code>PT_GETFPREGS</code>, and <code>PT_SETFPREGS</code> in the error codes section. So, I checked <code>ptrace.h</code>. There I found:</p>\n  \n  <ul>\n  <li><code>PT_READ_I</code> — to read instruction words</li>\n  <li><code>PT_READ_D</code> — to read data words</li>\n  <li><code>PT_READ_U</code> — to read U area data if you’re old enough to remember what the U area is<br>\n  [...]</li>\n  </ul>\n  \n  <p>There’s one problem solved. I can read and write memory for breakpoints. But I still can’t get access to registers, and I need to be able to mess with EIP.</p>\n</blockquote>\n'}, {'answer_id': 10829, 'author': 'Chris Hanson', 'author_id': 714, 'author_profile': 'https://Stackoverflow.com/users/714', 'pm_score': 1, 'selected': False, 'text': "<p>Manipulating a process's memory behind its back is a Bad Thing and is fraught with peril.  That's why Mac OS X (like any Unix system) has protected memory, and keeps processes isolated from one another.</p>\n\n<p>Of course it can be done:  There are facilities for shared memory between processes that explicitly cooperate.  There are also ways to manipulate other processes' address spaces as long as the process doing so has explicit right to do so (as granted by the security framework).  But that's there for people who are writing debugging tools to use.  It's not something that should be a normal — or even rare —\xa0occurrence for the vast majority of development on Mac OS X.</p>\n"}, {'answer_id': 63033, 'author': 'Trance Diviner', 'author_id': 7365, 'author_profile': 'https://Stackoverflow.com/users/7365', 'pm_score': 4, 'selected': False, 'text': '<p>Use <code>task_for_pid()</code> or other methods to obtain the target process’s task port.  Thereafter, you can directly manipulate the process’s address space using <code>vm_read()</code>, <code>vm_write()</code>, and others.</p>\n'}, {'answer_id': 64276, 'author': 'Scott Marcy', 'author_id': 8168, 'author_profile': 'https://Stackoverflow.com/users/8168', 'pm_score': 3, 'selected': False, 'text': '<p>It you\'re looking to be able to share chunks of memory between processes, you should check out shm_open(2) and mmap(2). It\'s pretty easy to allocate a chunk of memory in one process and pass the path (for shm_open) to another and both can then go crazy together. This is a lot safer than poking around in another process\'s address space as Chris Hanson mentions. Of course, if you don\'t have control over both processes, this won\'t do you much good.</p>\n\n<p>(Be aware that the max path length for shm_open appears to be 26 bytes, although this doesn\'t seem to be documented anywhere.)</p>\n\n<pre><code>// Create shared memory block\nvoid* sharedMemory = NULL;\nsize_t shmemSize = 123456;\nconst char* shmName = "mySharedMemPath";        \nint shFD = shm_open(shmName, (O_CREAT | O_EXCL | O_RDWR), 0600);\nif (shFD &gt;= 0) {\n    if (ftruncate(shFD, shmemSize) == 0) {\n        sharedMemory = mmap(NULL, shmemSize, (PROT_READ | PROT_WRITE), MAP_SHARED, shFD, 0);\n        if (sharedMemory != MAP_FAILED) {\n            // Initialize shared memory if needed\n            // Send \'shmemSize\' &amp; \'shmemSize\' to other process(es)\n        } else handle error\n    } else handle error\n    close(shFD);        // Note: sharedMemory still valid until munmap() called\n} else handle error\n\n...\nDo stuff with shared memory\n...\n\n// Tear down shared memory\nif (sharedMemory != NULL) munmap(sharedMemory, shmemSize);\nif (shFD &gt;= 0) shm_unlink(shmName);\n\n\n\n\n\n// Get the shared memory block from another process\nvoid* sharedMemory = NULL;\nsize_t shmemSize = 123456;              // Or fetched via some other form of IPC\nconst char* shmName = "mySharedMemPath";// Or fetched via some other form of IPC\nint shFD = shm_open(shmName, (O_RDONLY), 0600); // Can be R/W if you want\nif (shFD &gt;= 0) {\n    data = mmap(NULL, shmemSize, PROT_READ, MAP_SHARED, shFD, 0);\n    if (data != MAP_FAILED) {\n        // Check shared memory for validity\n    } else handle error\n    close(shFD);        // Note: sharedMemory still valid until munmap() called\n} else handle error\n\n\n...\nDo stuff with shared memory\n...\n\n// Tear down shared memory\nif (sharedMemory != NULL) munmap(sharedMemory, shmemSize);\n// Only the creator should shm_unlink()\n</code></pre>\n'}, {'answer_id': 2095086, 'author': 'fixermark', 'author_id': 57720, 'author_profile': 'https://Stackoverflow.com/users/57720', 'pm_score': 1, 'selected': False, 'text': "<p>In general, I would recommend that you use regular open() to open a temporary file. Once it's open in both processes, you can unlink() it from the filesystem and you'll be set up much like you would be if you'd used shm_open. The procedure is extremely similar to the one specified by Scott Marcy for shm_open.</p>\n\n<p>The disadvantage to this approach is that if the process that will be doing the unlink() crashes, you end up with an unused file and no process has the responsibility of cleaning it up. This disadvantage is shared with shm_open, because if nothing shm_unlinks a given name, the name remains in the shared memory space, available to be shm_opened by future processes.</p>\n"}, {'answer_id': 19105476, 'author': 'user2284570', 'author_id': 2284570, 'author_profile': 'https://Stackoverflow.com/users/2284570', 'pm_score': 2, 'selected': False, 'text': '<p>You want to do Inter-Process-Communication with the shared memory method. For a summary of other commons method, see <a href="https://en.wikipedia.org/wiki/Inter-process_communication#Main_IPC_methods" rel="nofollow noreferrer" title="short brief of main IPC methods">here</a></p>\n\n<p>It didn\'t take me long to find what you need in this <a href="http://books.google.fr/books?id=V8xQAAAAMAAJ&amp;q=Unix+System+V:+Programmer&#39;s+Reference+Manual&amp;dq=Unix+System+V:+Programmer&#39;s+Reference+Manual&amp;hl=fr&amp;sa=X&amp;ei=yq1KUuSYN-WX1AXY04HABw&amp;ved=0CEgQ6AEwAQ" rel="nofollow noreferrer" title="AT&amp;T Unix System V: Programmer&#39;s Reference Manual">book</a> which contains all the APIs which are common to all UNIXes today (which many more than I thought). You should buy it in the future. This book is a set of (several hundred) printed man pages which are rarely installed on modern machines.\nEach man page details a C function.</p>\n\n<p>It didn\'t take me long to find <strong><em>shmat()</em></strong> <strong><em>shmctl()</em></strong>; <strong><em>shmdt()</em></strong> and <strong><em>shmget()</em></strong> in it. I didn\'t search extensively, maybe there\'s more.</p>\n\n<p>It looked a bit outdated, but: YES, the base user-space API of modern UNIX OS back to the old 80\'s.</p>\n\n<p>Update: most functions described in the book are part of the POSIX C headers, you don\'t need to install anything. There are few exceptions, like with "curses", the original library.</p>\n'}, {'answer_id': 19236711, 'author': 'user2284570', 'author_id': 2284570, 'author_profile': 'https://Stackoverflow.com/users/2284570', 'pm_score': 2, 'selected': False, 'text': '<p>I have definitely found a short implementation of what you need (only one source file (main.c)).\nIt is specially designed for XNU.</p>\n<p>It is in the top ten result of Google search with the following keywords « dump process memory os x »</p>\n<p>The source code is <a href="https://github.com/gdbinit/readmem" rel="nofollow noreferrer" title="readmem">here</a></p>\n<p>but from a strict point of virtual address space point de vue, you should be more interested with this question: <a href="https://stackoverflow.com/questions/2179416/os-x-generate-core-dump-without-bringing-down-the-process">OS X: Generate core dump without bringing down the process?</a> (look also <a href="https://web.archive.org/web/20200103164014/https://osxbook.com/book/bonus/chapter8/core/" rel="nofollow noreferrer">this</a>)</p>\n<p>When you look at gcore source code, it is quite complex to do this since you need to deal with treads and their state...</p>\n<p>On most Linux distributions, the gcore program is now part of the GDB package. I think the OSX version is installed with xcode/the development tools.</p>\n<p><em><strong>UPDATE: wxHexEditor is an editor which can edit devices. IT CAN also edit process memory the same way it does for regular files. It work on all UNIX machines.</strong></em></p>\n'}, {'answer_id': 24985204, 'author': 'Jona', 'author_id': 2029914, 'author_profile': 'https://Stackoverflow.com/users/2029914', 'pm_score': 3, 'selected': False, 'text': '<p>I know this thread is 100 years old, but for people coming here from a search engine:</p>\n\n<p><a href="https://github.com/jona-t4/xnumem" rel="noreferrer">xnumem</a> does exactly what you are looking for, manipulate and read inter-process memory.</p>\n\n<pre><code>// Create new xnu_proc instance\nxnu_proc *Process = new xnu_proc();\n\n// Attach to pid (or process name)\nProcess-&gt;Attach(getpid());\n\n// Manipulate memory\nint i = 1337, i2 = 0;\ni2 = process-&gt;memory().Read&lt;int&gt;((uintptr_t)&amp;i);\n\n// Detach from process\nProcess-&gt;Detach();\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/10668', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1114/']