Exemple #1
0
static void parseline (char *b) {
	char *e = strchr (b, '=');
	if (!e) return;
	if (*b=='#') return;
	*e++ = 0;
	if (*e=='$') e = r_sys_getenv (e);
	if (e == NULL) return;
	if (!strcmp (b, "program")) _args[0] = _program = strdup (e);
	else if (!strcmp (b, "connect")) _connect = strdup (e);
	else if (!strcmp (b, "listen")) _listen = strdup (e);
	else if (!strcmp (b, "stdout")) _stdout = strdup (e);
	else if (!strcmp (b, "stdin")) _stdin = strdup (e);
	else if (!strcmp (b, "input")) _input = strdup (e);
	else if (!strcmp (b, "chdir")) _chgdir = strdup (e);
	else if (!strcmp (b, "chroot")) _chroot = strdup (e);
	else if (!strcmp (b, "preload")) _preload = strdup (e);
	else if (!strcmp (b, "setuid")) _setuid = strdup (e);
	else if (!strcmp (b, "seteuid")) _seteuid = strdup (e);
	else if (!strcmp (b, "setgid")) _setgid = strdup (e);
	else if (!strcmp (b, "setegid")) _setegid = strdup (e);
	else if (!memcmp (b, "arg", 3)) {
		int n = atoi (b+3);
		if (n>=0 && n<NARGS) {
			_args[n] = strdup (e);
			r_str_escape (_args[n]);
		} else eprintf ("Out of bounds args index: %d\n", n);
	} else if (!strcmp (b, "timeout")) _timeout = atoi (e);
	else if (!strcmp (b, "setenv")) {
		char *v = strchr (e, '=');
		if (v) {
			*v++ = 0;
			r_sys_setenv (e, v);
		}
	}
}
Exemple #2
0
/* Print out the JSON body for memory maps in the passed map region */
static void print_debug_map_json(RDebug *dbg, RDebugMap *map, bool prefix_comma) {
	dbg->cb_printf ("%s{", prefix_comma ? ",": "");
	if (map->name && *map->name) {
		char *escaped_name = r_str_escape (map->name);
		dbg->cb_printf ("\"name\":\"%s\",", escaped_name);
		free (escaped_name);
	}
	if (map->file && *map->file) {
		char *escaped_path = r_str_escape (map->file);
		dbg->cb_printf ("\"file\":\"%s\",", escaped_path);
		free (escaped_path);
	}
	dbg->cb_printf ("\"addr\":%"PFMT64u",", map->addr);
	dbg->cb_printf ("\"addr_end\":%"PFMT64u",", map->addr_end);
	dbg->cb_printf ("\"type\":\"%c\",", map->user?'u':'s');
	dbg->cb_printf ("\"perm\":\"%s\"", r_str_rwx_i (map->perm));
	dbg->cb_printf ("}");
}
Exemple #3
0
static void printmetaitem(RAnal *a, RAnalMetaItem *d, int rad) {
	char *pstr, *str = r_str_escape (d->str);
	if (str) {
		if (d->type=='s' && !*str) {
			free (str);
			return;
		}
		if (d->type != 'C') {
			r_name_filter (str, 0);
			pstr = str;
		} else pstr = d->str;
//		r_str_sanitize (str);
		switch (rad) {
		case 'j':
			a->printf ("{\"offset\":%"PFMT64d", \"type\":\"%s\", \"name\":\"%s\"}",
				d->from, r_meta_type_to_string (d->type), str);
			break;
		case 0:
			a->printf ("0x%08"PFMT64x" %s\n",
				d->from, str);
		case 1:
		case '*':
		default:
			if (d->type == 'C') {
				a->printf ("\"%s %s\" @ 0x%08"PFMT64x"\n",
					r_meta_type_to_string (d->type), pstr, d->from);
			} else {
				a->printf ("%s %d 0x%08"PFMT64x" # %s\n",
					r_meta_type_to_string (d->type),
					d->size, d->from, pstr);
			}
			break;
		}
		free (str);
	}
}
Exemple #4
0
R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr) {
	char buffer[1024], *outputptr = NULL;
	char *inputptr = (char *)input;
	int pid, bytes = 0, status;
	int sh_in[2], sh_out[2], sh_err[2];

	if (len) *len = 0;
	if (pipe (sh_in))
		return R_FALSE;
	if (output) {
		if (pipe (sh_out)) {
			close (sh_in[0]);
			close (sh_in[1]);
			close (sh_out[0]);
			close (sh_out[1]);
			return R_FALSE;
		}
	}
	if (pipe (sh_err)) {
		close (sh_in[0]);
		close (sh_in[1]);
		return R_FALSE;
	}

	switch ((pid=fork ())) {
	case -1:
		return R_FALSE;
	case 0:
		dup2 (sh_in[0], 0); close (sh_in[0]); close (sh_in[1]);
		if (output) { dup2 (sh_out[1], 1); close (sh_out[0]); close (sh_out[1]); }
		if (sterr) dup2 (sh_err[1], 2); else close (2);
		close (sh_err[0]); close (sh_err[1]);
		exit (r_sandbox_system (cmd, 0));
	default:
		outputptr = strdup ("");
		if (!outputptr)
			return R_FALSE;
		if (sterr) {
			*sterr = strdup ("");
			if (!*sterr) {
				free (outputptr);
				return R_FALSE;
			}
		}
		if (output) close (sh_out[1]);
		close (sh_err[1]);
		close (sh_in[0]);
		if (!inputptr || !*inputptr)
			close (sh_in[1]);

		for (;;) {
			fd_set rfds, wfds;
			int nfd;

			FD_ZERO (&rfds);
			FD_ZERO (&wfds);
			if (output)
				FD_SET (sh_out[0], &rfds);
			if (sterr)
				FD_SET (sh_err[0], &rfds);
			if (inputptr && *inputptr)
				FD_SET (sh_in[1], &wfds);
			memset (buffer, 0, sizeof (buffer));
			nfd = select (sh_err[0] + 1, &rfds, &wfds, NULL, NULL);
			if (nfd < 0)
				break;
			if (output && FD_ISSET (sh_out[0], &rfds)) {
				if ((bytes = read (sh_out[0], buffer, sizeof (buffer)-1)) == 0) break;
				buffer[sizeof(buffer) - 1] = '\0';
				if (len) *len += bytes;
				outputptr = r_str_concat (outputptr, buffer);
			} else if (FD_ISSET (sh_err[0], &rfds) && sterr) {
				if (read (sh_err[0], buffer, sizeof (buffer)-1) == 0) break;
				buffer[sizeof(buffer) - 1] = '\0';
				*sterr = r_str_concat (*sterr, buffer);
			} else if (FD_ISSET (sh_in[1], &wfds) && inputptr && *inputptr) {
				bytes = write (sh_in[1], inputptr, strlen (inputptr));
				inputptr += bytes;
				if (!*inputptr) {
					close (sh_in[1]);
					/* If neither stdout nor stderr should be captured,
					 * abort now - nothing more to do for select(). */
					if (!output && !sterr) break;
				}
			}
		}
		if (output)
			close (sh_out[0]);
		close (sh_err[0]);
		close (sh_in[1]);
		waitpid (pid, &status, 0);
		if (status != 0) {
			char *escmd = r_str_escape (cmd);
			eprintf ("%s: failed command '%s'\n", __func__, escmd);
			free (escmd);
			return R_FALSE;
		}

		if (output) *output = outputptr;
		else free (outputptr);
		return R_TRUE;
	}
	return R_FALSE;
}
Exemple #5
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
    ut64 off;
    ut8 *buf;
    const char *arg;
    int wseek, i, size, len = strlen (input);
    char *tmp, *str, *ostr;
    RCore *core = (RCore *)data;
#define WSEEK(x,y) if(wseek)r_core_seek_delta(x,y)
    wseek = r_config_get_i (core->config, "cfg.wseek");
    str = ostr = strdup (input+1);

    switch (*input) {
    case 'p':
        if (input[1]==' ' && input[2]) {
            r_core_patch (core, input+2);
        } else {
            eprintf ("Usage: wp [rapatch-file]\n"
                     "TODO: rapatch format documentation here\n");
        }
        break;
    case 'r':
        off = r_num_math (core->num, input+1);
        len = (int)off;
        if (len>0) {
            buf = malloc (len);
            if (buf != NULL) {
                r_num_irand ();
                for (i=0; i<len; i++)
                    buf[i] = r_num_rand (256);
                r_core_write_at (core, core->offset, buf, len);
                WSEEK (core, len);
                free (buf);
            } else eprintf ("Cannot allocate %d bytes\n", len);
        }
        break;
    case 'A':
        switch (input[1]) {
        case ' ':
            if (input[2] && input[3]==' ') {
                r_asm_set_pc (core->assembler, core->offset);
                eprintf ("modify (%c)=%s\n", input[2], input+4);
                len = r_asm_modify (core->assembler, core->block, input[2],
                                    r_num_math (core->num, input+4));
                eprintf ("len=%d\n", len);
                if (len>0) {
                    r_core_write_at (core, core->offset, core->block, len);
                    WSEEK (core, len);
                } else eprintf ("r_asm_modify = %d\n", len);
            } else eprintf ("Usage: wA [type] [value]\n");
            break;
        case '?':
        default:
            r_cons_printf ("Usage: wA [type] [value]\n"
                           "Types:\n"
                           " r   raw write value\n"
                           " v   set value (taking care of current address)\n"
                           " d   destination register\n"
                           " 0   1st src register\n"
                           " 1   2nd src register\n"
                           "Example: wA r 0 # e800000000\n");
            break;
        }
        break;
    case 'c':
        switch (input[1]) {
        case 'i':
            r_io_cache_commit (core->io);
            r_core_block_read (core, 0);
            break;
        case 'r':
            r_io_cache_reset (core->io, R_TRUE);
            /* Before loading the core block we have to make sure that if
             * the cache wrote past the original EOF these changes are no
             * longer displayed. */
            memset (core->block, 0xff, core->blocksize);
            r_core_block_read (core, 0);
            break;
        case '-':
            if (input[2]=='*') {
                r_io_cache_reset (core->io, R_TRUE);
            } else if (input[2]==' ') {
                char *p = strchr (input+3, ' ');
                ut64 to, from = core->offset;
                if (p) {
                    *p = 0;
                    from = r_num_math (core->num, input+3);
                    to = r_num_math (core->num, input+3);
                    if (to<from) {
                        eprintf ("Invalid range (from>to)\n");
                        return 0;
                    }
                } else {
                    from = r_num_math (core->num, input+3);
                    to = from + core->blocksize;
                }
                r_io_cache_invalidate (core->io, from, to);
            } else {
                eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
                r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
            }
            /* See 'r' above. */
            memset (core->block, 0xff, core->blocksize);
            r_core_block_read (core, 0);
            break;
        case '?':
            r_cons_printf (
                "Usage: wc[ir*?]\n"
                " wc           list all write changes\n"
                " wc- [a] [b]  remove write op at curseek or given addr\n"
                " wc*          \"\" in radare commands\n"
                " wcr          reset all write changes in cache\n"
                " wci          commit write cache\n"
                "NOTE: Requires 'e io.cache=true'\n");
            break;
        case '*':
            r_io_cache_list (core->io, R_TRUE);
            break;
        case '\0':
            r_io_cache_list (core->io, R_FALSE);
            break;
        }
        break;
    case ' ':
        /* write string */
        len = r_str_escape (str);
        r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
        r_io_set_fd (core->io, core->file->fd);
        r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
        WSEEK (core, len);
        r_core_block_read (core, 0);
        break;
    case 't':
        if (*str != ' ') {
            eprintf ("Usage: wt file [size]\n");
        } else {
            tmp = strchr (str+1, ' ');
            if (tmp) {
                st64 sz = (st64) r_num_math (core->num, tmp+1);
                *tmp = 0;
                if (sz<1) eprintf ("Invalid length\n");
                else r_core_dump (core, str+1, core->offset, (ut64)sz);
            } else r_file_dump (str+1, core->block, core->blocksize);
        }
        break;
    case 'T':
        eprintf ("TODO: wT // why?\n");
        break;
    case 'f':
        arg = (const char *)(input+((input[1]==' ')?2:1));
        if ((buf = (ut8*) r_file_slurp (arg, &size))) {
            r_io_set_fd (core->io, core->file->fd);
            r_io_write_at (core->io, core->offset, buf, size);
            WSEEK (core, size);
            free(buf);
            r_core_block_read (core, 0);
        } else eprintf ("Cannot open file '%s'\n", arg);
        break;
    case 'F':
        arg = (const char *)(input+((input[1]==' ')?2:1));
        if ((buf = r_file_slurp_hexpairs (arg, &size))) {
            r_io_set_fd (core->io, core->file->fd);
            r_io_write_at (core->io, core->offset, buf, size);
            WSEEK (core, size);
            free (buf);
            r_core_block_read (core, 0);
        } else eprintf ("Cannot open file '%s'\n", arg);
        break;
    case 'w':
        str++;
        len = (len-1)<<1;
        if (len>0) tmp = malloc (len+1);
        else tmp = NULL;
        if (tmp) {
            for (i=0; i<len; i++) {
                if (i%2) tmp[i] = 0;
                else tmp[i] = str[i>>1];
            }
            str = tmp;
            r_io_set_fd (core->io, core->file->fd);
            r_io_write_at (core->io, core->offset, (const ut8*)str, len);
            WSEEK (core, len);
            r_core_block_read (core, 0);
            free (tmp);
        } else eprintf ("Cannot malloc %d\n", len);
        break;
    case 'x':
    {
        int b, len = strlen (input);
        ut8 *buf = malloc (len+1);
        len = r_hex_str2bin (input+1, buf);
        if (len != 0) {
            if (len<0) len = -len+1;
            b = core->block[len]&0xf;
            b |= (buf[len]&0xf0);
            buf[len] = b;
            r_core_write_at (core, core->offset, buf, len);
            WSEEK (core, len);
            r_core_block_read (core, 0);
        } else eprintf ("Error: invalid hexpair string\n");
        free (buf);
    }
    break;
    case 'a':
        switch (input[1]) {
        case 'o':
            if (input[2] == ' ')
                r_core_hack (core, input+3);
            else r_core_hack_help (core);
            break;
        case ' ':
        case '*':
        {   const char *file = input[1]=='*'? input+2: input+1;
            RAsmCode *acode;
            r_asm_set_pc (core->assembler, core->offset);
            acode = r_asm_massemble (core->assembler, file);
            if (acode) {
                if (input[1]=='*') {
                    r_cons_printf ("wx %s\n", acode->buf_hex);
                } else {
                    if (r_config_get_i (core->config, "scr.prompt"))
                        eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
                    r_core_write_at (core, core->offset, acode->buf, acode->len);
                    WSEEK (core, acode->len);
                    r_core_block_read (core, 0);
                }
                r_asm_code_free (acode);
            }
        }
        break;
        case 'f':
            if ((input[2]==' '||input[2]=='*')) {
                const char *file = input[2]=='*'? input+4: input+3;
                RAsmCode *acode;
                r_asm_set_pc (core->assembler, core->offset);
                acode = r_asm_assemble_file (core->assembler, file);
                if (acode) {
                    if (input[2]=='*') {
                        r_cons_printf ("wx %s\n", acode->buf_hex);
                    } else {
                        if (r_config_get_i (core->config, "scr.prompt"))
                            eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
                        r_core_write_at (core, core->offset, acode->buf, acode->len);
                        WSEEK (core, acode->len);
                        r_core_block_read (core, 0);
                    }
                    r_asm_code_free (acode);
                } else eprintf ("Cannot assemble file\n");
            } else eprintf ("Wrong argument\n");
            break;
        default:
            eprintf ("Usage: wa[of*] [arg]\n"
                     " wa nop           : write nopcode using asm.arch and asm.bits\n"
                     " wa* mov eax, 33  : show 'wx' op with hexpair bytes of sassembled opcode\n"
                     " \"wa nop;nop\"     : assemble more than one instruction (note the quotes)\n"
                     " waf foo.asm      : assemble file and write bytes\n"
                     " wao nop          : convert current opcode into nops\n"
                     " wao?             : show help for assembler operation on current opcode (hack)\n");
            break;
        }
        break;
    case 'b':
    {
        int len = strlen (input);
        ut8 *buf = malloc (len+1);
        if (buf) {
            len = r_hex_str2bin (input+1, buf);
            if (len > 0) {
                r_mem_copyloop (core->block, buf, core->blocksize, len);
                r_core_write_at (core, core->offset, core->block, core->blocksize);
                WSEEK (core, core->blocksize);
                r_core_block_read (core, 0);
            } else eprintf ("Wrong argument\n");
        } else eprintf ("Cannot malloc %d\n", len+1);
    }
    break;
    case 'm':
        size = r_hex_str2bin (input+1, (ut8*)str);
        switch (input[1]) {
        case '\0':
            eprintf ("Current write mask: TODO\n");
            // TODO
            break;
        case '?':
            break;
        case '-':
            r_io_set_write_mask(core->io, 0, 0);
            eprintf ("Write mask disabled\n");
            break;
        case ' ':
            if (size>0) {
                r_io_set_fd (core->io, core->file->fd);
                r_io_set_write_mask (core->io, (const ut8*)str, size);
                WSEEK (core, size);
                eprintf ("Write mask set to '");
                for (i=0; i<size; i++)
                    eprintf ("%02x", str[i]);
                eprintf ("'\n");
            } else eprintf ("Invalid string\n");
            break;
        }
        break;
    case 'v':
    {
        int type = 0;
        ut8 addr1;
        ut16 addr2;
        ut32 addr4, addr4_;
        ut64 addr8;

        switch (input[1]) {
        case '?':
            r_cons_printf ("Usage: wv[size] [value]    # write value of given size\n"
                           "  wv1 234      # write one byte with this value\n"
                           "  wv 0x834002  # write dword with this value\n"
                           "Supported sizes are: 1, 2, 4, 8\n");
            return 0;
        case '1':
            type = 1;
            break;
        case '2':
            type = 2;
            break;
        case '4':
            type = 4;
            break;
        case '8':
            type = 8;
            break;
        }
        off = r_num_math (core->num, input+2);
        r_io_set_fd (core->io, core->file->fd);
        r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
        if (type == 0)
            type = (off&UT64_32U)? 8: 4;
        switch (type) {
        case 1:
            addr1 = (ut8)off;
            r_io_write (core->io, (const ut8 *)&addr1, 1);
            WSEEK (core, 1);
            break;
        case 2:
            addr2 = (ut16)off;
            r_io_write (core->io, (const ut8 *)&addr2, 2);
            WSEEK (core, 2);
            break;
        case 4:
            addr4_ = (ut32)off;
            //drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
            //endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
            memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
            r_io_write (core->io, (const ut8 *)&addr4, 4);
            WSEEK (core, 4);
            break;
        case 8:
            /* 8 byte addr */
            memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
            //	endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
            r_io_write (core->io, (const ut8 *)&addr8, 8);
            WSEEK (core, 8);
            break;
        }
        r_core_block_read (core, 0);
    }
    break;
    case 'o':
        switch (input[1]) {
        case 'a':
        case 's':
        case 'A':
        case 'x':
        case 'r':
        case 'l':
        case 'm':
        case 'd':
        case 'o':
        case 'w':
            if (input[2]!=' ') {
                r_cons_printf ("Usage: 'wo%c 00 11 22'\n", input[1]);
                return 0;
            }
        case '2':
        case '4':
            r_core_write_op (core, input+3, input[1]);
            r_core_block_read (core, 0);
            break;
        case 'n':
            r_core_write_op (core, "ff", 'x');
            r_core_block_read (core, 0);
            break;
        case '\0':
        case '?':
        default:
            r_cons_printf (
                "Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]\n"
                "Example:\n"
                "  wox 0x90   ; xor cur block with 0x90\n"
                "  wox 90     ; xor cur block with 0x90\n"
                "  wox 0x0203 ; xor cur block with 0203\n"
                "  woa 02 03  ; add [0203][0203][...] to curblk\n"
                "Supported operations:\n"
                "  wow  ==  write looped value (alias for 'wb')\n"
                "  woa  +=  addition\n"
                "  wos  -=  substraction\n"
                "  wom  *=  multiply\n"
                "  wod  /=  divide\n"
                "  wox  ^=  xor\n"
                "  woo  |=  or\n"
                "  woA  &=  and\n"
                "  wor  >>= shift right\n"
                "  wol  <<= shift left\n"
                "  wo2  2=  2 byte endian swap\n"
                "  wo4  4=  4 byte endian swap\n"
            );
            break;
        }
        break;
    default:
    case '?':
        if (core->oobi) {
            eprintf ("Writing oobi buffer!\n");
            r_io_set_fd (core->io, core->file->fd);
            r_io_write (core->io, core->oobi, core->oobi_len);
            WSEEK (core, core->oobi_len);
            r_core_block_read (core, 0);
        } else r_cons_printf (
                "Usage: w[x] [str] [<file] [<<EOF] [@addr]\n"
                " w foobar     write string 'foobar'\n"
                " wr 10        write 10 random bytes\n"
                " ww foobar    write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n"
                " wa push ebp  write opcode, separated by ';' (use '\"' around the command)\n"
                " waf file     assemble file and write bytes\n"
                " wA r 0       alter/modify opcode at current seek (see wA?)\n"
                " wb 010203    fill current block with cyclic hexpairs\n"
                " wc[ir*?]     write cache commit/reset/list\n"
                " wx 9090      write two intel nops\n"
                " wv eip+34    write 32-64 bit value\n"
                " wo? hex      write in block with operation. 'wo?' fmi\n"
                " wm f0ff      set binary mask hexpair to be used as cyclic write mask\n"
                " wf file      write contents of file at current offset\n"
                " wF file      write contents of hexpairs file here\n"
                " wt file [sz] write to file (from current seek, blocksize or sz bytes)\n"
                " wp file      apply radare patch file. See wp? fmi\n");
        //TODO: add support for offset+seek
        // " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n"
        break;
    }
Exemple #6
0
static void printmetaitem(RAnal *a, RAnalMetaItem *d, int rad) {
	char *pstr, *str;
	//eprintf ("%d %d\n", d->space, a->meta_spaces.space_idx);
	if (a->meta_spaces.space_idx != -1) {
		if (a->meta_spaces.space_idx != d->space) {
			return;
		}
	}
	str = r_str_escape (d->str);
	if (str || d->type == 'd') {
		if (d->type=='s' && !*str) {
			free (str);
			return;
		}
		if (!str) {
			pstr = "";
		} else if (d->type != 'C') {
			r_name_filter (str, 0);
			pstr = str;
		} else pstr = d->str;
//		r_str_sanitize (str);
		switch (rad) {
		case 'j':
			a->cb_printf ("{\"offset\":%"PFMT64d", \"type\":\"%s\", \"name\":\"%s\"}",
				d->from, r_meta_type_to_string (d->type), str);
			break;
		case 0:
		case 1:
		case '*':
		default:
			switch (d->type) {
			case 'C':
				{
				const char *type = r_meta_type_to_string (d->type);
				char *s = sdb_encode ((const ut8*)pstr, -1);
				if (!s) s = strdup (pstr);
				if (rad) {
					if (!strcmp (type, "CCu")) {
						a->cb_printf ("%s base64:%s @ 0x%08"PFMT64x"\n",
							type, s, d->from);
					} else {
						a->cb_printf ("%s %s @ 0x%08"PFMT64x"\n",
							type, pstr, d->from);
					}
				} else {
					if (!strcmp (type, "CCu")) {
						char *mys = r_str_escape (pstr);
						a->cb_printf ("0x%08"PFMT64x" %s \"%s\"\n",
								d->from, type, mys);
						free (mys);
					} else {
						a->cb_printf ("0x%08"PFMT64x" %s \"%s\"\n",
								d->from, type, pstr);
					}
				}
				free (s);
				}
				break;
			case 'h': /* hidden */
			case 's': /* string */
				if (rad) {
					a->cb_printf ("%s %d @ 0x%08"PFMT64x" # %s\n",
							r_meta_type_to_string (d->type),
							(int)d->size, d->from, pstr);
				} else {
					// TODO: use b64 here
					a->cb_printf ("0x%08"PFMT64x" string[%d] \"%s\"\n",
							d->from, (int)d->size, pstr);
				}
				break;
			case 'd': /* data */
				if (rad) {
					a->cb_printf ("%s %d @ 0x%08"PFMT64x"\n",
							r_meta_type_to_string (d->type),
							(int)d->size, d->from);
				} else {
					a->cb_printf ("0x%08"PFMT64x" data %s %d\n",
						d->from, r_meta_type_to_string (d->type), (int)d->size);

				}
				break;
			case 'm': /* magic */
			case 'f': /* formatted */
				if (rad) {
					a->cb_printf ("%s %d %s @ 0x%08"PFMT64x"\n",
							r_meta_type_to_string (d->type),
							(int)d->size, pstr, d->from);
				} else {
					const char *dtype = d->type=='m'?"magic":"format";
					a->cb_printf ("0x%08"PFMT64x" %s %d %s\n",
							d->from, dtype, (int)d->size, pstr);
				}
				break;
			default:
				if (rad) {
					a->cb_printf ("%s %d 0x%08"PFMT64x" # %s\n",
						r_meta_type_to_string (d->type),
						(int)d->size, d->from, pstr);
				} else {
					// TODO: use b64 here
					a->cb_printf ("0x%08"PFMT64x" array[%d] %s %s\n",
						d->from, (int)d->size, 
						r_meta_type_to_string (d->type), pstr);
				}
				break;
			}
			break;
		}
		if (str)
			free (str);
	}
}
Exemple #7
0
R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr) {
	char buffer[1024], *outputptr = NULL;
	char *inputptr = (char *)input;
	int pid, bytes = 0, status;
	int sh_in[2], sh_out[2], sh_err[2];

	if (len) {
		*len = 0;
	}
	if (pipe (sh_in)) {
		return false;
	}
	if (output) {
		if (pipe (sh_out)) {
			close (sh_in[0]);
			close (sh_in[1]);
			close (sh_out[0]);
			close (sh_out[1]);
			return false;
		}
	}
	if (pipe (sh_err)) {
		close (sh_in[0]);
		close (sh_in[1]);
		return false;
	}

	switch ((pid = r_sys_fork ())) {
	case -1:
		return false;
	case 0:
		dup2 (sh_in[0], 0);
		close (sh_in[0]);
		close (sh_in[1]);
		if (output) {
			dup2 (sh_out[1], 1);
			close (sh_out[0]);
			close (sh_out[1]);
		}
		if (sterr) {
			dup2 (sh_err[1], 2); 
		} else {
			close (2);
		}
		close (sh_err[0]);
		close (sh_err[1]);
		exit (r_sandbox_system (cmd, 0));
	default:
		outputptr = strdup ("");
		if (!outputptr) {
			return false;
		}
		if (sterr) {
			*sterr = strdup ("");
			if (!*sterr) {
				free (outputptr);
				return false;
			}
		}
		if (output) {
			close (sh_out[1]);
		}
		close (sh_err[1]);
		close (sh_in[0]);
		if (!inputptr || !*inputptr) {
			close (sh_in[1]);
		}
		// we should handle broken pipes somehow better
		signal (SIGPIPE, SIG_IGN);
		for (;;) {
			fd_set rfds, wfds;
			int nfd;
			FD_ZERO (&rfds);
			FD_ZERO (&wfds);
			if (output) {
				FD_SET (sh_out[0], &rfds);
			}
			if (sterr) {
				FD_SET (sh_err[0], &rfds);
			}
			if (inputptr && *inputptr) {
				FD_SET (sh_in[1], &wfds);
			}
			memset (buffer, 0, sizeof (buffer));
			nfd = select (sh_err[0] + 1, &rfds, &wfds, NULL, NULL);
			if (nfd < 0) {
				break;
			}
			if (output && FD_ISSET (sh_out[0], &rfds)) {
				if (!(bytes = read (sh_out[0], buffer, sizeof (buffer)-1))) {
					break;
				}
				buffer[sizeof(buffer) - 1] = '\0';
				if (len) {
					*len += bytes;
				}
				outputptr = r_str_append (outputptr, buffer);
			} else if (FD_ISSET (sh_err[0], &rfds) && sterr) {
				if (!read (sh_err[0], buffer, sizeof (buffer)-1)) {
					break;
				}
				buffer[sizeof(buffer) - 1] = '\0';
				*sterr = r_str_append (*sterr, buffer);
			} else if (FD_ISSET (sh_in[1], &wfds) && inputptr && *inputptr) {
				int inputptr_len = strlen (inputptr);
				bytes = write (sh_in[1], inputptr, inputptr_len);
				if (bytes != inputptr_len) {
					break;
				}
				inputptr += bytes;
				if (!*inputptr) {
					close (sh_in[1]);
					/* If neither stdout nor stderr should be captured,
					 * abort now - nothing more to do for select(). */
					if (!output && !sterr) {
						break;
					}
				}
			}
		}
		if (output) {
			close (sh_out[0]);
		}
		close (sh_err[0]);
		close (sh_in[1]);
		waitpid (pid, &status, 0);
		bool ret = true;
		if (status) {
			char *escmd = r_str_escape (cmd);
			eprintf ("error code %d\n", WEXITSTATUS(status));
			//eprintf ("%s: failed command '%s'\n", __func__, escmd);
			free (escmd);
			ret = false;
		}

		if (output) {
			*output = outputptr;
		} else {
			free (outputptr);
		}
		return ret;
	}
	return false;
}