在OS X中读取其他进程的内存?

我一直在努力了解如何阅读Mac OS X上其他进程的内存,但我没有太多运气。 我在网上看过很多使用ptracePEEKDATA等的例子,但它在BSD [ man ptrace ]上没有这个选项。

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

如何在Mac OS X上读取和写入另一个进程的内存?

使用task_for_pid()或其他方法获取目标进程的任务端口。 此后,您可以使用vm_read()vm_write()等来直接操作进程的地址空间。

Matasano Chargen在将一些调试代码移植到OS X时有一段很好的发布,其中包括学习如何在另一个进程中读取和写入内存(以及其他内容)。

它必须工作,否则GDB不会 :

事实certificate,苹果ptrace()其无限的智慧,已经摧毁了ptrace() 。 OS X手册页列出了以下请求代码:

  • PT_ATTACH – 选择要调试的进程
  • PT_DENY_ATTACH – 因此进程可以阻止自己被调试
    […]

没有提到读或写内存或寄存器。 如果手册页还没有在错误代码部分中提到PT_GETREGSPT_SETREGSPT_GETFPREGSPT_SETFPREGS ,那么这将是令人沮丧的。 所以,我查了一下ptrace.h 。 在那里我发现:

  • PT_READ_I – 读取指令字
  • PT_READ_D – 读取数据字
  • PT_READ_U – 如果你的年龄足够大,可以读取U区数据
    […]

有一个问题解决了。 我可以为断点读写内存。 但我仍然无法访问寄存器,我需要能够搞乱EIP。

你希望能够在进程之间共享内存块,你应该看看shm_open(2)和mmap(2)。 在一个进程中分配一块内存并将路径(对于shm_open)传递给另一个进程非常容易,然后两者都可以一起疯狂。 正如Chris Hanson所提到的,这比在另一个进程的地址空间中探索要安全得多。 当然,如果你无法控制这两个过程,这对你没什么好处。

(请注意,shm_open的最大路径长度似乎是26个字节,尽管这似乎没有在任何地方记录。)

 // Create shared memory block void* sharedMemory = NULL; size_t shmemSize = 123456; const char* shmName = "mySharedMemPath"; int shFD = shm_open(shmName, (O_CREAT | O_EXCL | O_RDWR), 0600); if (shFD >= 0) { if (ftruncate(shFD, shmemSize) == 0) { sharedMemory = mmap(NULL, shmemSize, (PROT_READ | PROT_WRITE), MAP_SHARED, shFD, 0); if (sharedMemory != MAP_FAILED) { // Initialize shared memory if needed // Send 'shmemSize' & 'shmemSize' to other process(es) } else handle error } else handle error close(shFD); // Note: sharedMemory still valid until munmap() called } else handle error ... Do stuff with shared memory ... // Tear down shared memory if (sharedMemory != NULL) munmap(sharedMemory, shmemSize); if (shFD >= 0) shm_unlink(shmName); // Get the shared memory block from another process void* sharedMemory = NULL; size_t shmemSize = 123456; // Or fetched via some other form of IPC const char* shmName = "mySharedMemPath";// Or fetched via some other form of IPC int shFD = shm_open(shmName, (O_RDONLY), 0600); // Can be R/W if you want if (shFD >= 0) { data = mmap(NULL, shmemSize, PROT_READ, MAP_SHARED, shFD, 0); if (data != MAP_FAILED) { // Check shared memory for validity } else handle error close(shFD); // Note: sharedMemory still valid until munmap() called } else handle error ... Do stuff with shared memory ... // Tear down shared memory if (sharedMemory != NULL) munmap(sharedMemory, shmemSize); // Only the creator should shm_unlink() 

我知道这个post已有100年的历史了,但对于那些来自搜索引擎的人来说:

xnumem完全符合您的要求,操作和读取进程间内存。

 // Create new xnu_proc instance xnu_proc *Process = new xnu_proc(); // Attach to pid (or process name) Process->Attach(getpid()); // Manipulate memory int i = 1337, i2 = 0; i2 = process->memory().Read((uintptr_t)&i); // Detach from process Process->Detach(); 

我肯定找到了你需要的简短实现(只有一个源文件(main.c))。 它专为XNU设计。

它是谷歌搜索的前十名结果,其中包含以下关键词«dump process memory os x»

源代码在这里

但是从严格的虚拟地址空间点来看,你应该对这个问题更感兴趣: OS X:生成核心转储而不会导致进程崩溃? (也看这个 )

当你看gcore源代码时,这样做非常复杂,因为你需要处理踏板及其状态……

在大多数Linux发行版中,gcore程序现在是GDB包的一部分。 我认为OSX版本是用xcode /开发工具安装的。

更新:wxHexEditor是一个可以编辑设备的编辑器。 它也可以像处理常规文件一样编辑进程内存。 它适用于所有UNIX计算机。

您希望使用共享内存方法进行进程间通信。 有关其他公共方法的摘要,请参见此处

我花了很长时间才找到你需要的本书 ,其中包含了当今所有UNIX所共有的所有API(比我想象的要多得多)。 你应该在将来购买它。 本书是一套(数百个)印刷的手册页,很少安装在现代机器上。 每个手册页都详细介绍了C函数。

我花了很长时间才找到shmat() shmctl() ; shmdt()shmget()在里面。 我没有广泛搜索,也许还有更多。

它看起来有点过时,但是:是的,现代UNIX OS的基本用户空间API回到了旧的80年代。

更新:本书中描述的大多数函数都是POSIX C头文件的一部分,您不需要安装任何东西。 几乎没有例外,例如“curses”,原始库。

一般情况下,我建议您使用常规open()打开临时文件。 一旦它在两个进程中都打开,你就可以将它与文件系统取消链接(),就像你使用shm_open一样。 该程序与Scott Marcy为shm_open指定的程序非常相似。

这种方法的缺点是,如果将要执行unlink()的进程崩溃,您最终会得到一个未使用的文件,并且没有进程负责清理它。 这个缺点与shm_open共享,因为如果没有shm_unlinks给定名称,该名称将保留在共享内存空间中,可供将来进程shm_opened。

在背后操纵一个进程的记忆是一件坏事,并且充满了危险。 这就是为什么Mac OS X(像任何Unix系统一样)具有受保护的内存,并使进程彼此隔离。

当然可以这样做:在明确合作的进程之间有共享内存的工具。 只要这样做的过程有明确的权利(由安全框架授予),也有办法操纵其他进程的地址空间。 但是那些正在编写调试工具的人可以使用。 对于Mac OS X上的绝大多数开发而言,这不应该是正常的 – 甚至是罕见的 – 。