C 可以在Unix/Linux上读取虚拟内存吗?在窗户上呢?

C 可以在Unix/Linux上读取虚拟内存吗?在窗户上呢?,c,operating-system,debian,virtual-memory,mach,C,Operating System,Debian,Virtual Memory,Mach,我正在和马赫一起研究Debian GNU/Hurd。我被要求编写一个程序,给定一个PID和一个地址,在地址上执行vm\u read,并打印结果 这是我写的代码: #include <mach_error.h> #include <mach/mig_errors.h> #include <mach/thread_status.h> #include <mach/processor_info.h> #include <mach/i386/vm_p

我正在和马赫一起研究Debian GNU/Hurd。我被要求编写一个程序,给定一个PID和一个地址,在地址上执行
vm\u read
,并打印结果

这是我写的代码:

#include <mach_error.h>
#include <mach/mig_errors.h>
#include <mach/thread_status.h>
#include <mach/processor_info.h>
#include <mach/i386/vm_param.h>
#include <stdio.h>
#include <stdlib.h>
#include <hurd.h>
#include <string.h>

int main(int argc, char * argv[]) {

    if(argc != 3) {
        printf ("Wrong arguments: ./vm_read PID address\n");
        exit(1);
    }
    
    int res;
    mach_port_t target_task = pid2task(atoi(argv[1]));

    vm_address_t addr = atoi(argv[2]);
    vm_offset_t *data;
    mach_msg_type_number_t data_count;
    res = vm_read (target_task, addr, sizeof(int), &data, &data_count);

    if (res != KERN_SUCCESS) {
            printf ("Error reading virtual mem (0x%x), %s \n", res, 
            mach_error_string(res));
            exit(1);
    }
    printf("done\n");

    for (int i=0; i<data_count; ++i){
        printf("byte %d : %x\n",i,((char*)data)[i]);
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
如果(argc!=3){
printf(“错误参数:./vm_读取PID地址\n”);
出口(1);
}
国际关系;
mach_port_t target_task=pid2task(atoi(argv[1]);
vm_address_t addr=atoi(argv[2]);
vm_offset_t*数据;
马赫数信息类型数据计数;
res=vm\u read(target\u task、addr、sizeof(int)、data和data\u count);
如果(res!=KERN_SUCCESS){
printf(“读取虚拟内存(0x%x)时出错,%s\n”,res,
马赫误差字符串(res);
出口(1);
}
printf(“完成”\n);

对于(int i=0;i对于Windows,如果需要从进程读取内存,则需要在获取进程句柄时请求进程\u VM\u read(ReadProcessMemory是合适的调用)。为了获得该句柄,通常更容易使用OpenProcess自己启动进程。

对于Windows,如果需要从进程中读取内存,则需要在获取进程句柄时请求进程VM读取(ReadProcessMemory是合适的调用)。为了获得该句柄,通常更容易使用OpenProcess自己启动进程。

在UNIX上没有访问另一个进程内存的标准方法,但在Linux上,可以通过读取特殊文件/proc/pid/mem来实现:

charmemfile[32];
snprintf(memfile,sizeof(memfile),“/proc/%s/mem”,argv[1]);
int mfd=打开(仅限内存文件);
如果(mfd<0){
perror(“无法打开pid/mem文件”);
退出(1);}
if(lseek(多功能显示器,(关闭)strtoull(argv[2],0,0),寻道设置){
perror(“无法寻求解决”);
退出(1);}

如果(read(mfd,&data,sizeof(data))在UNIX上没有访问另一个进程内存的标准方法,但在Linux上,可以通过读取特殊文件/proc/pid/mem来实现:

charmemfile[32];
snprintf(memfile,sizeof(memfile),“/proc/%s/mem”,argv[1]);
int mfd=打开(仅限内存文件);
如果(mfd<0){
perror(“无法打开pid/mem文件”);
退出(1);}
if(lseek(多功能显示器,(关闭)strtoull(argv[2],0,0),寻道设置){
perror(“无法寻求解决”);
退出(1);}

如果(read(mfd,&data,sizeof(data))我很好奇,这可能会失败吗?一个进程读取另一个进程的内存似乎是一个安全问题,除非他们有特殊权限。@wxz:open调用将失败(使用EPERM)如果您没有读取目标进程地址空间的权限。获取或不获取权限的确切方式受各种功能控制和所有权的影响。“正常”linux安装程序只授予普通进程的所有者读取权限,而不授予其他任何权限。具有特殊权限的进程本身通常不可读,即使所有者也不可读。我很好奇,这可能会失败吗?一个进程读取另一个进程的内存似乎是一个安全问题,除非它们具有特殊权限。@wxz:open调用将失败l(使用EPERM)如果您没有读取目标进程地址空间的权限。获取或不获取权限的确切方式受各种功能控制和所有权的影响。“正常”linux安装程序为普通进程的所有者提供读取权限,而不是其他权限。具有特殊权限的进程本身通常不可读,即使所有者也不可读。
char memfile[32];
snprintf(memfile, sizeof(memfile), "/proc/%s/mem", argv[1]);
int mfd = open(memfile, O_RDONLY);
if (mfd < 0) {
    perror("Can't open pid/mem file");
    exit(1); }
if (lseek(mfd, (off_t)strtoull(argv[2], 0, 0), SEEK_SET) {
    perror("Can't seek to address");
    exit(1); }
if (read(mfd, &data, sizeof(data)) <= 0) {
    fprintf(stderr, "No data at address %s\n", argv[2]);
    exit(1); }