在Linux上读写存储过程

时间:2018-11-05 11:00:06

标签: c memory process operating-system

我写了一个小程序来读写进程的内存,但是我不明白为什么它不起作用。 那是我的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>


int main()
{
pid_t pid=3169;
char mem_file_name[2048];
 int mem_fd;
 int offset=0;
 char buf[1005128];

sprintf(mem_file_name, "/proc/%d/mem", pid);
mem_fd = open(mem_file_name, O_RDWR,S_IRWXU);
printf("1 %s\n",strerror(errno));
ptrace(PTRACE_ATTACH, pid, NULL, NULL);
printf("2 %s\n",strerror(errno));
waitpid(pid, NULL, 0);
printf("3 %s\n",strerror(errno));
lseek(mem_fd, offset, SEEK_SET);
printf("4 %s\n",strerror(errno));
read(mem_fd, buf, _SC_PAGE_SIZE);
printf("5 %s\n",strerror(errno));
ptrace(PTRACE_DETACH, pid, NULL, NULL);
printf("6 %s\n",strerror(errno));
printf("%s\n",buf );
}

这是我的输出:

1 Success
2 Success
3 Success
4 Success
5 Input/output error
6 Input/output error

我用

编译
gcc -Wall -Wextra main.c

我以root权限运行

sudo ./a.out

在此示例中,我仅尝试从进程中读取内容,但无效。 我的想法是转储进程的内存,但我不知道为什么我看不懂。

ps我知道有一些工具可以转储进程的内存,但是我想创建一个用于锻炼的小型程序。

1 个答案:

答案 0 :(得分:1)

您的代码有几处出错。

您的主要问题是您试图从偏移量0读取,偏移量0是未映射到您的进程的进程地址0x00000000。

int offset=0;
...
lseek(mem_fd, offset, SEEK_SET);

这就像从您的内存中读取地址零:

int offset=0;
char* p = 0x0;
printf("%d data",p[offset]);

您只能通过/ proc / PID / mem读取内存中的偏移量,这些偏移量是进程中的有效地址和映射地址。

例如,如果您想通过此API读取buf变量的内存,则可以通过查找其地址来读取它:

lseek(mem_fd, (off_t)buf, SEEK_SET); /* note that on 64 bit you need to use lseek64 and off64_t */
read(mem_fd, buf, _SC_PAGE_SIZE); /* this should work */

注意: