11 #if DEBUGGER && (__linux__ || __BSD__)
13 #include <sys/ptrace.h>
14 #include <sys/types.h>
24 #define RzIOPTRACE_OPID(x) (((RzIOPtrace *)(x)->data)->opid)
25 #define RzIOPTRACE_PID(x) (((RzIOPtrace *)(x)->data)->pid)
26 #define RzIOPTRACE_FD(x) (((RzIOPtrace *)(x)->data)->fd)
27 static void open_pidmem(RzIOPtrace *iop);
38 #if __linux__ && defined(__GLIBC__)
39 #ifndef PTRACE_GETSIGINFO
40 #define PTRACE_GETSIGINFO 0x4202
45 procpidmem is buggy.. running
this sometimes results
in ffff
49 #define USE_PROC_PID_MEM 0
51 static int __waitpid(
int pid) {
53 return (waitpid(
pid, &st, 0) != -1);
56 #define debug_read_raw(io, x, y) rz_io_ptrace((io), PTRACE_PEEKTEXT, (x), (void *)(y), RZ_PTRACE_NODATA)
57 #define debug_write_raw(io, x, y, z) rz_io_ptrace((io), PTRACE_POKEDATA, (x), (void *)(y), (rz_ptrace_data_t)(z))
58 #if __OpenBSD__ || __NetBSD__ || __KFBSD__
59 typedef int ptrace_word;
61 typedef size_t ptrace_word;
73 for (
x = 0;
x < words;
x++) {
75 at = (
ut32 *)((
size_t)at +
sizeof(
ut32));
96 if (RzIOPTRACE_PID(
desc) != RzIOPTRACE_OPID(
desc)) {
100 open_pidmem((RzIOPtrace *)
desc->data);
102 RzIOPTRACE_OPID(
desc) = RzIOPTRACE_PID(
desc);
117 int res = debug_os_read_at(io, RzIOPTRACE_PID(
desc), (
ut32 *)aligned_buf,
len,
addr);
126 ptrace_word *
buf = (ptrace_word *)pbuf;
127 ut32 words = sz /
sizeof(ptrace_word);
128 ut32 last = sz %
sizeof(ptrace_word);
129 ptrace_word
x, *at = (ptrace_word *)(
size_t)
addr;
134 for (
x = 0;
x < words;
x++) {
135 int rc = debug_write_raw(io,
pid, at++,
buf[
x]);
141 lr = debug_read_raw(io,
pid, (
void *)at);
143 if (debug_write_raw(io,
pid, (
void *)at,
lr)) {
151 if (!
fd || !
fd->data) {
154 return ptrace_write_at(io, RzIOPTRACE_PID(
fd),
buf,
len, io->
off);
157 static void open_pidmem(RzIOPtrace *iop) {
160 snprintf(pidmem,
sizeof(pidmem),
"/proc/%d/mem", iop->pid);
161 iop->fd = open(pidmem,
O_RDWR);
167 eprintf (
"Warning: Cannot open /proc/%d/mem. "
168 "Fallback to ptrace io.\n", iop->pid);
175 static void close_pidmem(RzIOPtrace *iop) {
183 if (!strncmp(
file,
"ptrace://", 9)) {
186 if (!strncmp(
file,
"attach://", 9)) {
192 static inline bool is_pid_already_attached(
RzIO *io,
int pid) {
193 #if defined(__linux__)
194 siginfo_t sig = { 0 };
195 return rz_io_ptrace(io, PTRACE_GETSIGINFO,
pid,
NULL, &sig) != -1;
196 #elif defined(__FreeBSD__)
197 struct ptrace_lwpinfo
info = { 0 };
199 return rz_io_ptrace(io, PT_LWPINFO,
pid, &
info,
len) != -1;
200 #elif defined(__OpenBSD__) || defined(__NetBSD__)
201 ptrace_state_t
state = { 0 };
203 return rz_io_ptrace(io, PT_GET_PROCESS_STATE,
pid, &
state,
len) != -1;
220 if (!is_pid_already_attached(io,
pid)) {
224 eprintf(
"ptrace_attach: Operation not permitted\n");
228 eprintf(
"ptrace_attach: Operation not permitted\n");
231 perror(
"ptrace: Cannot attach");
232 eprintf(
"ERRNO: %d (EINVAL)\n", errno);
239 }
else if (!__waitpid(
pid)) {
245 RzIOPtrace *riop =
RZ_NEW0(RzIOPtrace);
250 riop->pid = riop->tid =
pid;
282 RzIOPtrace *riop =
desc->data;
285 if (errno ==
ESRCH) {
294 RzIOPtrace *iop = (RzIOPtrace *)
fd->data;
297 if (!strcmp(
cmd,
"")) {
300 if (!strcmp(
cmd,
"help")) {
302 " R!ptrace - use ptrace io\n"
303 " R!mem - use /proc/pid/mem io if possible\n"
304 " R!pid - show targeted pid\n"
305 " R!pid <#> - select new pid\n");
306 }
else if (!strcmp(
cmd,
"ptrace")) {
308 }
else if (!strcmp(
cmd,
"mem")) {
310 }
else if (!strncmp(
cmd,
"pid", 3)) {
314 if (
pid > 0 &&
pid != iop->pid) {
317 iop->pid = iop->tid =
pid;
331 RzIOPtrace *iop = (RzIOPtrace *)
fd->data;
341 .desc =
"Ptrace and /proc/pid/mem (if available) io plugin",
343 .uris =
"ptrace://,attach://",
361 #ifndef RZ_PLUGIN_INCORE
RzBinInfo * info(RzBinFile *bf)
const lzma_allocator const uint8_t * in
static static fork const void static count close
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
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
RZ_API void Ht_() free(HtName_(Ht) *ht)
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
static int __close(RzIODesc *fd)
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
static int __getpid(RzIODesc *fd)
RZ_API RzLibStruct rizin_plugin
struct rz_io_plugin_t rz_io_plugin_ptrace
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
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
while(len< limit &&buf1[len]==buf2[len])++len
RZ_API void rz_free_aligned(void *p)
RZ_API void * rz_malloc_aligned(size_t size, size_t alignment)
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_sys_pid_to_path(int pid)
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
int read(izstream &zs, T *x, Items items)