You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用vm_read读取其他进程内存时触发MACH_SEND_INVALID_DEST错误

解决macOS进程内存读取时的MACH_SEND_INVALID_DEST错误

嘿,我一眼就看到你代码里的核心问题了——task_for_pid的用法完全错了,这直接导致了MACH_SEND_INVALID_DEST错误。咱们一步步把问题拆明白,再把代码修好:

问题出在哪?

先看task_for_pid的函数签名:

kern_return_t task_for_pid(mach_port_t target_task, pid_t pid, mach_port_t *task_port);

它的返回值是操作的状态码(比如KERN_SUCCESS表示成功),而目标进程的task端口是通过第三个指针参数输出的。但你把返回值直接赋值给了task变量,这就导致task存的根本不是有效的进程端口,后续调用vm_read自然会因为"目标无效"报错。

另外还有几个小细节需要调整:

  • vm_read的参数顺序写错了,读取大小和输出内存指针的位置搞反了
  • 读完内存后没释放vm_read分配的缓冲区,会造成内存泄漏
  • macOS的权限限制:普通用户调用task_for_pid需要特殊权限,不然也会失败

修复后的完整代码

#include <stdio.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>

int main() {
    pid_t pid;
    printf("PID: ");
    scanf("%d", &pid);
    
    vm_address_t address;
    printf("Address (hex): ");
    scanf("%lx", &address);

    // 正确获取目标进程的task端口
    mach_port_t target_task;
    kern_return_t ret = task_for_pid(mach_task_self(), pid, &target_task);
    if (ret != KERN_SUCCESS) {
        fprintf(stderr, "Failed to get task for PID %d, error: 0x%x\n", pid, ret);
        return 1;
    }

    vm_offset_t read_buffer;
    mach_msg_type_number_t read_size = sizeof(int);
    ret = vm_read(target_task, address, read_size, &read_buffer, &read_size);
    if (ret != KERN_SUCCESS) {
        fprintf(stderr, "Failed to read memory, error: 0x%x\n", ret);
        mach_port_deallocate(mach_task_self(), target_task); // 先释放task端口再退出
        return 1;
    }

    // 把读取到的内存转成int类型输出
    int *value = (int *)read_buffer;
    printf("Read value: %d\n", *value);

    // 清理资源:释放vm_read分配的内存和task端口
    vm_deallocate(mach_task_self(), read_buffer, read_size);
    mach_port_deallocate(mach_task_self(), target_task);

    return 0;
}

运行时的注意事项

  1. 权限问题:macOS的SIP(系统完整性保护)会限制普通用户调用task_for_pid,你有两个解决办法:
    • 直接用sudo运行编译后的程序,比如sudo ./memory_reader
    • 给二进制文件添加权限:先创建一个entitlements.plist文件,内容如下:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
          <key>com.apple.security.task.forge</key>
          <true/>
      </dict>
      </plist>
      
      然后执行签名命令:
      sudo codesign --entitlements entitlements.plist -s - ./memory_reader
      
  2. 地址有效性:确保你输入的内存地址是目标进程中真实存在且可读的,不然会返回KERN_INVALID_ADDRESS之类的错误。

内容的提问来源于stack exchange,提问作者lego man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 18:02:25