我一直在努力了解如何阅读Mac OS X上其他进程的内存,但我没有太多运气。我在ptrace
使用PEEKDATA
这样的网上看过很多例子,但在BSD [man ptrace
] 上没有这个选项。
int pid = fork();
if (pid > 0) {
// mess around with child-process's memory
}
如何在Mac OS X上读取和写入另一个进程的内存?
答案 0 :(得分:13)
使用task_for_pid()
或其他方法获取目标进程的任务端口。此后,您可以使用vm_read()
,vm_write()
和其他人直接操作流程的地址空间。
答案 1 :(得分:10)
Matasano Chargen在将一些调试代码移植到OS X上时发布了一篇很好的帖子,其中包括学习如何在另一个进程中读取和写入内存(以及其他内容)。
It has to work, otherwise GDB wouldn't:
事实证明,苹果凭借其无限的智慧,已经内疚
ptrace()
。 OS X手册页列出了以下请求代码:
PT_ATTACH
- 选择要调试的流程PT_DENY_ATTACH
- 因此进程可以阻止自己进行调试 [...]没有提及读或写内存或寄存器。如果手册页还没有在错误代码部分中提到
PT_GETREGS
,PT_SETREGS
,PT_GETFPREGS
和PT_SETFPREGS
,那么这会令人沮丧。所以,我检查了ptrace.h
。在那里我找到了:
PT_READ_I
- 阅读说明字PT_READ_D
- 阅读数据字PT_READ_U
- 如果您已经足够大,可以记住U区的数据,那么就可以读取U区数据 [...]解决了一个问题。我可以为断点读写内存。但是我仍然无法访问寄存器,我需要能够使用EIP。
答案 2 :(得分:5)
您希望能够在进程之间共享内存块,您应该查看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()
答案 3 :(得分:5)
我知道这个帖子已有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<int>((uintptr_t)&i);
// Detach from process
Process->Detach();
答案 4 :(得分:2)
您希望使用共享内存方法进行进程间通信。有关其他公共方法的摘要,请参阅here
我需要很长时间才能找到你需要的内容book,其中包含了当今所有UNIX通用的所有API(比我想象的要多得多)。你应该在将来购买它。本书是一套(数百个)印刷的手册页,很少安装在现代机器上。 每个手册页都详细介绍了C函数。
我花了很长时间才找到 shmat() shmctl() ;其中包含 shmdt() 和 shmget() 。我没有广泛搜索,也许还有更多。
它看起来有点过时,但是:是的,现代UNIX操作系统的基本用户空间API回到了旧的80年代。
更新:本书中描述的大多数功能都是POSIX C标头的一部分,您无需安装任何东西。几乎没有例外,比如“curses”,原始库。
答案 5 :(得分:2)
我肯定找到了你需要的简短实现(只有一个源文件(main.c))。 它专为XNU设计。
使用以下关键字«dump process memory os x»
进入谷歌搜索的前十名结果源代码为here
但是从严格的虚拟地址空间点来看,你应该对这个问题更感兴趣:OS X: Generate core dump without bringing down the process?(另见this)
当你查看gcore源代码时,执行此操作非常复杂,因为你需要处理踏板及其状态......
在大多数Linux发行版中,gcore程序现在是GDB包的一部分。我认为OSX版本是用xcode /开发工具安装的。
更新:wxHexEditor是一个可以编辑设备的编辑器。它也可以像处理常规文件一样编辑进程内存。它适用于所有UNIX计算机。
答案 6 :(得分:1)
一般情况下,我建议您使用常规open()打开临时文件。一旦它在两个进程中都打开,你就可以将它与文件系统取消链接(),就像你使用shm_open一样。该程序与Scott Marcy为shm_open指定的程序非常相似。
这种方法的缺点是,如果将要执行unlink()的进程崩溃,您最终会得到一个未使用的文件,并且没有进程负责清理它。这个缺点与shm_open共享,因为如果没有shm_unlinks给定的名称,该名称将保留在共享内存空间中,可供将来的进程shm_opened。
答案 7 :(得分:0)
在背后操纵一个进程的记忆是一件坏事,并且充满了危险。这就是为什么Mac OS X(像任何Unix系统一样)都有保护内存,并使进程彼此隔离的原因。
当然可以做到:在明确合作的进程之间有共享内存的工具。只要这样做的过程有明确的权利(由安全框架授予),也有办法操纵其他进程的地址空间。但是那些正在编写调试工具的人可以使用。对于Mac OS X上的绝大多数开发而言,这不应该是正常的 - 甚至是罕见的。