首页 / 知识

关于C#:在OS X中读取其他进程的内存?

2023-04-12 04:28:00

关于C#:在OS X中读取其他进程的内存?

Reading Other Process' Memory in OS X?

我一直在尝试了解如何在Mac OS X上读取其他进程的内存,但是我运气不高。我在网上看到了很多使用ptracePEEKDATA的示例,但是在BSD [man ptrace]上没有该选项。

1
2
3
4
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不能:

It turns out Apple, in their infinite wisdom, had gutted ptrace(). The OS X man page lists the following request codes:

  • PT_ATTACH a€" to pick a process to debug
  • PT_DENY_ATTACH a€" so processes can stop themselves from being debugged
    [...]

No mention of reading or writing memory or registers. Which would have been discouraging if the man page had not also mentioned PT_GETREGS, PT_SETREGS, PT_GETFPREGS, and PT_SETFPREGS in the error codes section. So, I checked ptrace.h. There I found:

  • PT_READ_I a€" to read instruction words
  • PT_READ_D a€" to read data words
  • PT_READ_U a€" to read U area data if youa€?re old enough to remember what the U area is
    [...]

Therea€?s one problem solved. I can read and write memory for breakpoints. But I still cana€?t get access to registers, and I need to be able to mess with EIP.


我知道此线程已有100年历史,但对于来自搜索引擎的用户来说:

xnumem可以完全满足您的需求,可以操纵和读取进程间内存。

1
2
3
4
5
6
7
8
9
10
11
12
// 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();

如果您希望能够在进程之间共享内存块,则应检出shm_open(2)和mmap(2)。在一个进程中分配一块内存,然后将路径(用于shm_open)传递给另一个进程,这很容易,然后两者都可能在一起发疯。这比Chris Hanson提到的在另一个进程的地址空间中浏览要安全得多。当然,如果您不能同时控制这两个过程,那对您没有多大帮助。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 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()

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

它是使用以下关键字的Google搜索结果的前十名?转储进程内存os x ??

源代码在这里

但是从严格的虚拟地址空间angular出发,您应该对以下问题更感兴趣:OS X:在不降低进程的情况下生成核心转储? (也看这个)

当您查看gcore源代码时,执行此操作非常复杂,因为您需要处理踏步及其状态...

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

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


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

我很快就在本书中找到了所需的内容,其中包含了当今所有UNIX通用的所有API(比我想象的要多得多)。您将来应该购买。这本书是一套(数百本)印刷手册页,很少在现代机器上安装。
每个手册页都有一个C函数。

我很快就找到了shmat()shmctl(); shmdt()和shmget()。我没有进行广泛的搜索,也许还有更多。

它看起来有些过时,但是:是的,现代UNIX OS的基本用户空间API可以追溯到80年代。

更新:本书中描述的大多数功能都是POSIX C标头的一部分,您无需安装任何东西。很少有例外,例如原始库" curses"。


通常,我建议您使用常规的open()打开一个临时文件。一旦在两个进程中都将其打开,则可以将其从文件系统中取消link(),并且将进行设置,就像使用shm_open一样。该过程与Scott Marcy为shm_open指定的过程极为相似。

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


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

当然可以做到:在显式合作的进程之间存在共享内存的功能。只要操作具有明确的操作权限(由安全框架授予),也可以使用其他方法来操作其他进程的地址空间。但这正是编写调试工具以供使用的人员的地方。对于Mac OS X上的绝大多数开发来说,这都不应该是正常的甚至是罕见的事情。


读取进程内存选项

最新内容

相关内容

热门文章

推荐文章

标签云

猜你喜欢