mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-19 12:22:43 +00:00
* Implemented 'dd' command for UNIX and FreeBSD
This commit is contained in:
parent
bff20dd916
commit
25b590e21f
@ -4555,13 +4555,12 @@ static int cmd_debug(void *data, const char *input) {
|
||||
} else r_debug_trace_list (core->dbg, -1);
|
||||
break;
|
||||
case 'd':
|
||||
eprintf ("TODO: dd: file descriptors\n");
|
||||
switch (input[1]) {
|
||||
case 0:
|
||||
// r_debug_desc_list()
|
||||
case '\0':
|
||||
r_debug_desc_list (core->dbg, 0);
|
||||
break;
|
||||
case '*':
|
||||
// r_debug_desc_list(1)
|
||||
r_debug_desc_list (core->dbg, 1);
|
||||
break;
|
||||
case 's':
|
||||
// r_debug_desc_seek()
|
||||
@ -4581,6 +4580,13 @@ static int cmd_debug(void *data, const char *input) {
|
||||
case ' ':
|
||||
// open file
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
r_cons_printf ("Usage: dd[*sdrw-?]\n"
|
||||
" dd list filedescriptors\n"
|
||||
" dd* list filedescriptors (in radare commands)\n"
|
||||
" dd? show this help\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
|
@ -4,6 +4,26 @@
|
||||
|
||||
#include <r_debug.h>
|
||||
|
||||
R_API RDebugDesc *r_debug_desc_new (int fd, char* path, int perm, int type, int off) {
|
||||
RDebugDesc *desc = R_NEW (RDebugDesc);
|
||||
if (desc) {
|
||||
desc->fd = fd;
|
||||
desc->path = strdup (path);
|
||||
desc->perm = perm;
|
||||
desc->type = type;
|
||||
desc->off = off;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
R_API void r_debug_desc_free (RDebugDesc *p) {
|
||||
if (p) {
|
||||
if (p->path)
|
||||
free (p->path);
|
||||
free (p);
|
||||
}
|
||||
}
|
||||
|
||||
R_API int r_debug_desc_open(RDebug *dbg, const char *path) {
|
||||
if (dbg && dbg->h && dbg->h->desc.open)
|
||||
return dbg->h->desc.open (path);
|
||||
@ -42,8 +62,25 @@ R_API int r_debug_desc_write(RDebug *dbg, int fd, ut64 addr, int len) {
|
||||
|
||||
R_API int r_debug_desc_list(RDebug *dbg, int rad) {
|
||||
int count = 0;
|
||||
// callback or rlist? i would prefer rlist here..
|
||||
//RList *list = dbg->h->desc.list ();
|
||||
// TODO: loop here
|
||||
RList *list;
|
||||
RListIter *iter;
|
||||
RDebugDesc *p;
|
||||
|
||||
if (rad) {
|
||||
if (dbg && dbg->printf)
|
||||
dbg->printf ("TODO \n");
|
||||
} else {
|
||||
if (dbg && dbg->h && dbg->h->desc.list) {
|
||||
list = dbg->h->desc.list (dbg->pid);
|
||||
r_list_foreach (list, iter, p) {
|
||||
dbg->printf ("%i 0x%"PFMT64x" %c%c%c %s\n", p->fd, p->off,
|
||||
(p->perm & R_IO_READ)?'r':'-',
|
||||
(p->perm & R_IO_WRITE)?'w':'-',
|
||||
p->type, p->path);
|
||||
}
|
||||
r_list_destroy (list);
|
||||
free (list);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
@ -1493,7 +1493,7 @@ static RList *r_debug_native_map_get(RDebug *dbg) {
|
||||
int i, perm, unk = 0;
|
||||
char *pos_c;
|
||||
char path[1024], line[1024];
|
||||
char region[100], region2[100], perms[5], null[16];
|
||||
char region[100], region2[100], perms[5];
|
||||
FILE *fd;
|
||||
if (dbg->pid == -1) {
|
||||
eprintf ("r_debug_native_map_get: No selected pid (-1)\n");
|
||||
@ -1532,6 +1532,7 @@ static RList *r_debug_native_map_get(RDebug *dbg) {
|
||||
if (pos_c) strncpy (path, pos_c, sizeof (path)-1);
|
||||
else path[0]='\0';
|
||||
#else
|
||||
char null[16];
|
||||
sscanf (line, "%s %s %s %s %s %s",
|
||||
®ion[2], perms, null, null, null, path);
|
||||
|
||||
@ -1733,7 +1734,9 @@ static int r_debug_native_kill(RDebug *dbg, boolt thread, int sig) {
|
||||
#endif
|
||||
}
|
||||
|
||||
struct r_debug_desc_plugin_t r_debug_desc_plugin_native;
|
||||
static int r_debug_native_init(RDebug *dbg) {
|
||||
dbg->h->desc = r_debug_desc_plugin_native;
|
||||
#if __WINDOWS__
|
||||
return w32_dbg_init ();
|
||||
#else
|
||||
@ -1764,6 +1767,121 @@ static int r_debug_native_bp(void *user, int add, ut64 addr, int hw, int rwx) {
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
static RList *r_debug_desc_native_list (int pid) {
|
||||
RList *ret;
|
||||
RDebugDesc *desc;
|
||||
int perm, type;
|
||||
#if __KFBSD__
|
||||
int mib[4];
|
||||
size_t len;
|
||||
char *buf, *bp, *eb;
|
||||
struct kinfo_file *kve;
|
||||
|
||||
len = 0;
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_FILEDESC;
|
||||
mib[3] = pid;
|
||||
|
||||
if (sysctl(mib, 4, NULL, &len, NULL, 0) != 0)
|
||||
return NULL;
|
||||
len = len * 4 / 3;
|
||||
buf = malloc(len);
|
||||
if (buf == NULL)
|
||||
return (NULL);
|
||||
if (sysctl(mib, 4, buf, &len, NULL, 0) != 0) {
|
||||
free (buf);
|
||||
return NULL;
|
||||
}
|
||||
bp = buf;
|
||||
eb = buf + len;
|
||||
ret = r_list_new ();
|
||||
if (ret) {
|
||||
ret->free = (RListFree) r_debug_desc_free;
|
||||
while (bp < eb) {
|
||||
kve = (struct kinfo_file *)(uintptr_t)bp;
|
||||
bp += kve->kf_structsize;
|
||||
if (kve->kf_fd < 0) // Skip root and cwd. We need it ??
|
||||
continue;
|
||||
switch (kve->kf_vnode_type) {
|
||||
case KF_VTYPE_VREG: type = 'r'; break;
|
||||
case KF_VTYPE_VDIR: type = 'd'; break;
|
||||
case KF_VTYPE_VBLK: type = 'b'; break;
|
||||
case KF_VTYPE_VCHR: type = 'c'; break;
|
||||
case KF_VTYPE_VLNK: type = 'l'; break;
|
||||
case KF_VTYPE_VSOCK: type = 's'; break;
|
||||
case KF_VTYPE_VFIFO: type = 'f'; break;
|
||||
case KF_VTYPE_VBAD: type = 'x'; break;
|
||||
case KF_VTYPE_VNON:
|
||||
case KF_VTYPE_UNKNOWN:
|
||||
default: type = '-'; break;
|
||||
}
|
||||
perm = (kve->kf_flags & KF_FLAG_READ)?R_IO_READ:0;
|
||||
perm |= (kve->kf_flags & KF_FLAG_WRITE)?R_IO_WRITE:0;
|
||||
desc = r_debug_desc_new (kve->kf_fd, kve->kf_path, perm, type,
|
||||
kve->kf_offset);
|
||||
if (desc == NULL)
|
||||
break;
|
||||
r_list_append (ret, desc);
|
||||
}
|
||||
}
|
||||
free (buf);
|
||||
#elif __linux__
|
||||
char path[1024], file[2048], buf[1024];
|
||||
struct dirent *de;
|
||||
DIR *dd;
|
||||
struct stat st;
|
||||
|
||||
snprintf (path, sizeof (path), "/proc/%i/fd/", pid);
|
||||
dd = opendir(path);
|
||||
if (dd==NULL) {
|
||||
printf("Cannot open /proc\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = r_list_new ();
|
||||
if (ret) {
|
||||
ret->free = (RListFree) r_debug_desc_free;
|
||||
while((de = (struct dirent *)readdir(dd))) {
|
||||
if (de->d_name[0]=='.')
|
||||
continue;
|
||||
strncpy (file, path, sizeof (file));
|
||||
strncat (file, de->d_name, sizeof (file));
|
||||
memset (buf, 0, sizeof (buf));
|
||||
readlink(file, buf, sizeof (buf));
|
||||
type = perm = 0;
|
||||
if (stat(file, &st) != -1) {
|
||||
type = st.st_mode & S_IFIFO ? 'P':
|
||||
st.st_mode & S_IFSOCK ? 'S':
|
||||
st.st_mode & S_IFCHR ? 'C':'-';
|
||||
}
|
||||
if (lstat(path, &st) != -1) {
|
||||
if (st.st_mode & S_IRUSR)
|
||||
perm |= R_IO_READ;
|
||||
if (st.st_mode & S_IWUSR)
|
||||
perm |= R_IO_WRITE;
|
||||
}
|
||||
//TODO: Offset
|
||||
desc = r_debug_desc_new (atoi (de->d_name), buf, perm, type, 0);
|
||||
if (desc == NULL)
|
||||
break;
|
||||
r_list_append (ret, desc);
|
||||
}
|
||||
closedir(dd);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int r_debug_desc_native_open (const char *path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct r_debug_desc_plugin_t r_debug_desc_plugin_native = {
|
||||
.open = r_debug_desc_native_open,
|
||||
.list = r_debug_desc_native_list,
|
||||
};
|
||||
|
||||
struct r_debug_plugin_t r_debug_plugin_native = {
|
||||
.name = "native",
|
||||
#if __i386__
|
||||
|
@ -86,6 +86,14 @@ typedef struct r_debug_map_t {
|
||||
int user;
|
||||
} RDebugMap;
|
||||
|
||||
typedef struct r_debug_desc_t {
|
||||
int fd;
|
||||
char *path;
|
||||
int perm;
|
||||
int type;
|
||||
ut64 off;
|
||||
} RDebugDesc;
|
||||
|
||||
typedef struct r_debug_trace_t {
|
||||
RList *traces;
|
||||
int count;
|
||||
@ -143,7 +151,7 @@ typedef struct r_debug_desc_plugin_t {
|
||||
int (*write)(int fd, ut64 addr, int len);
|
||||
int (*seek)(int fd, ut64 addr);
|
||||
int (*dup)(int fd, int newfd);
|
||||
RList* (*list)();
|
||||
RList* (*list)(int pid);
|
||||
} RDebugDescPlugin;
|
||||
|
||||
/* TODO: pass dbg and user data pointer everywhere */
|
||||
@ -248,6 +256,8 @@ R_API void r_debug_map_free(RDebugMap *map);
|
||||
R_API void r_debug_map_list(RDebug *dbg, ut64 addr);
|
||||
|
||||
/* descriptors */
|
||||
R_API RDebugDesc *r_debug_desc_new (int fd, char* path, int perm, int type, int off);
|
||||
R_API void r_debug_desc_free (RDebugDesc *p);
|
||||
R_API int r_debug_desc_open(RDebug *dbg, const char *path);
|
||||
R_API int r_debug_desc_close(RDebug *dbg, int fd);
|
||||
R_API int r_debug_desc_dup(RDebug *dbg, int fd, int newfd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user