В дополнение к procfs также можно получить доступ к другой памяти процесса, используя process_vm_writev и process_vm_readv
Эта программа будет читать заданное количество байтов с заданного адреса данного процесса (удалены некоторые проверки ошибок для улучшения читаемости):
#define _GNU_SOURCE
#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int remote_process_read(pid_t remote_pid, void *address, char *buffer, size_t len)
{
struct iovec local[1] = {};
struct iovec remote[1] = {};
int errsv = 0;
ssize_t nread = 0;
local[0].iov_len = len;
local[0].iov_base = (void *)buffer;
remote[0].iov_base = address;
remote[0].iov_len = local[0].iov_len;
nread = process_vm_readv(remote_pid, local, 2, remote, 1, 0);
if (nread != local[0].iov_len)
{
errsv = errno;
fprintf(stderr, "Failed reading. process_vm_readv returned: %ld. Errno: %d\n", nread, errsv);
return errsv;
}
return errno;
}
enum
{
ARG_APP_NAME = 0,
ARG_PID,
ARG_ADDRESS,
ARG_BYTES_TO_READ,
ARG_COUNT
};
int main(int argc, char *argv[])
{
pid_t remote_pid = 0;
size_t len = 0;
int ret = 1;
char *buffer = NULL;
void *remote_address = NULL;
if (ARG_COUNT != argc)
{
fprintf(stderr, "Usage: %s <PID> <address (hex)> <num of bytes to read (hex)>\n", argv[ARG_APP_NAME]);
goto clean;
}
remote_pid = strtol(argv[ARG_PID], NULL, 10);
remote_address = (void *)strtoul(argv[ARG_ADDRESS], NULL, 16);
len = strtoul(argv[ARG_BYTES_TO_READ], NULL, 16);
buffer = malloc(len);
if (0 != remote_process_read(remote_pid, remote_address, buffer, len))
{
goto clean;
}
printf("Read Successfully!\n");
for (size_t i = 0; i < len; i++)
{
printf("%02X", buffer[i]);
}
printf("\n");
ret = 0;
clean:
free(buffer);
return ret;
}
person
Yosef Arbiv
schedule
19.10.2019