чтение и запись в памяти процесса на Linux - PullRequest
0 голосов
/ 05 ноября 2018

Я написал небольшую программу, которая читает и записывает память процесса, но я не могу понять, почему он не работает. это мой код:

#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 голосов
/ 05 ноября 2018

Есть несколько вещей, которые идут не так с вашим кодом.

Ваша основная проблема заключается в том, что вы пытаетесь читать со смещения 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 со смещениями, которые являются действительными и сопоставленными адресами в вашем процессе.

Например, если вы хотите прочитать память переменной buf через этот API, вы можете прочитать ее, обратившись к ее адресу:

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 */

Примечания:

  • PID не должен быть жестко запрограммирован, либо вы читаете его из getpid, либо используете /proc/self/mem
  • Нет смысла открывать файловый дескриптор для записи (proc API только для чтения)
  • Предлагаю вам также прочитать http://man7.org/linux/man-pages/man5/proc.5.html
...