Rizin
unix-like reverse engineering framework and cli tools
io_procpid.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2010-2016 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_userconf.h>
5 
6 #include <rz_io.h>
7 #include <rz_lib.h>
8 #include <rz_cons.h>
9 
10 #if __linux__
11 
12 #include <sys/ptrace.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <errno.h>
16 
17 typedef struct {
18  int fd;
19  int pid;
20 } RzIOProcpid;
21 
22 #define RzIOPROCPID_PID(x) (((RzIOProcpid *)(x)->data)->pid)
23 #define RzIOPROCPID_FD(x) (((RzIOProcpid *)(x)->data)->fd)
24 
25 static int __waitpid(int pid) {
26  int st = 0;
27  return (waitpid(pid, &st, 0) != -1);
28 }
29 
30 static int debug_os_read_at(int fdn, void *buf, int sz, ut64 addr) {
31  if (lseek(fdn, addr, 0) < 0) {
32  return -1;
33  }
34  return read(fdn, buf, sz);
35 }
36 
37 static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int len) {
38  memset(buf, 0xff, len); // TODO: only memset the non-readed bytes
39  return debug_os_read_at(RzIOPROCPID_FD(fd), buf, len, io->off);
40 }
41 
42 static int procpid_write_at(int fd, const ut8 *buf, int sz, ut64 addr) {
43  if (lseek(fd, addr, 0) < 0) {
44  return -1;
45  }
46  return write(fd, buf, sz);
47 }
48 
49 static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int len) {
50  return procpid_write_at(RzIOPROCPID_FD(fd), buf, len, io->off);
51 }
52 
53 static bool __plugin_open(RzIO *io, const char *file, bool many) {
54  return (!strncmp(file, "procpid://", 10));
55 }
56 
57 static RzIODesc *__open(RzIO *io, const char *file, int rw, int mode) {
58  char procpidpath[64];
59  int fd;
60  if (__plugin_open(io, file, 0)) {
61  int pid = atoi(file + 10);
62  if (file[0] == 'a') {
63  int ret = ptrace(PTRACE_ATTACH, pid, 0, 0);
64  if (ret == -1) {
65  switch (errno) {
66  case EPERM:
67  eprintf("Operation not permitted\n");
68  break;
69  case EINVAL:
70  perror("ptrace: Cannot attach");
71  eprintf("ERRNO: %d (EINVAL)\n", errno);
72  break;
73  }
74  } else if (!__waitpid(pid)) {
75  eprintf("Error in waitpid\n");
76  }
77  }
78  snprintf(procpidpath, sizeof(procpidpath), "/proc/%d/mem", pid);
79  fd = rz_sys_open(procpidpath, O_RDWR, 0);
80  if (fd != -1) {
81  RzIOProcpid *riop = RZ_NEW0(RzIOProcpid);
82  if (!riop) {
83  close(fd);
84  return NULL;
85  }
86  riop->pid = pid;
87  riop->fd = fd;
88  RzIODesc *d = rz_io_desc_new(io, &rz_io_plugin_procpid, file, true, 0, riop);
89  d->name = rz_sys_pid_to_path(riop->pid);
90  return d;
91  }
92  /* kill children */
93  eprintf("Cannot open /proc/%d/mem of already attached process\n", pid);
94  (void)ptrace(PTRACE_DETACH, pid, 0, 0);
95  }
96  return NULL;
97 }
98 
99 static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
100  return offset;
101 }
102 
103 static int __close(RzIODesc *fd) {
104  int ret = ptrace(PTRACE_DETACH, RzIOPROCPID_PID(fd), 0, 0);
105  RZ_FREE(fd->data);
106  return ret;
107 }
108 
109 static char *__system(RzIO *io, RzIODesc *fd, const char *cmd) {
110  RzIOProcpid *iop = (RzIOProcpid *)fd->data;
111  if (!strncmp(cmd, "pid", 3)) {
112  int pid = atoi(cmd + 3);
113  if (pid > 0) {
114  iop->pid = pid;
115  }
116  io->cb_printf("%d\n", iop->pid);
117  } else {
118  eprintf("Try: 'R!pid'\n");
119  }
120  return NULL;
121 }
122 
124  .name = "procpid",
125  .desc = "Open /proc/[pid]/mem io",
126  .license = "LGPL3",
127  .uris = "procpid://",
128  .open = __open,
129  .close = __close,
130  .read = __read,
131  .check = __plugin_open,
132  .lseek = __lseek,
133  .system = __system,
134  .write = __write,
135 };
136 
137 #else
139  .name = NULL
140 };
141 #endif
142 
143 #ifndef RZ_PLUGIN_INCORE
145  .type = RZ_LIB_TYPE_IO,
146  .data = &rz_io_plugin_procpid,
148 };
149 #endif
size_t len
Definition: 6502dis.c:15
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static fork write
Definition: sflib.h:33
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep lseek
Definition: sflib.h:113
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_bfdbg.c:84
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
Definition: io_bfdbg.c:151
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
Definition: io_bfdbg.c:159
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_bfdbg.c:38
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_bfdbg.c:142
static int __close(RzIODesc *fd)
Definition: io_bfdbg.c:130
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
Definition: io_bochs.c:90
RzIOPlugin rz_io_plugin_procpid
Definition: io_procpid.c:138
RZ_API RzLibStruct rizin_plugin
Definition: io_procpid.c:144
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid ptrace
Definition: sflib.h:57
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
RZ_API int rz_sys_open(const char *path, int perm, int mode)
Definition: sys.c:1740
RZ_API char * rz_sys_pid_to_path(int pid)
Definition: sys.c:920
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_VERSION
Definition: rz_version.h:8
#define EINVAL
Definition: sftypes.h:132
#define O_RDWR
Definition: sftypes.h:488
#define EPERM
Definition: sftypes.h:111
@ PTRACE_ATTACH
Definition: sftypes.h:617
@ PTRACE_DETACH
Definition: sftypes.h:621
#define d(i)
Definition: sha256.c:44
Definition: gzappend.c:170
const char * name
Definition: rz_io.h:115
const char * version
Definition: rz_io.h:117
Definition: rz_io.h:59
ut64 off
Definition: rz_io.h:61
PrintfCallback cb_printf
Definition: rz_io.h:91
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int addr
Definition: z80asm.c:58
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115