Exemple #1
0
R_API ut64 r_io_size(RIO *io) {
	ut64 size, here;
	if (r_io_is_listener (io))
		return UT64_MAX;
// XXX. problematic when io.va = 1
int iova = io->va;
io->va = 0;
	//r_io_set_fdn (io, fd);
	here = r_io_seek (io, 0, R_IO_SEEK_CUR);
	size = r_io_seek (io, 0, R_IO_SEEK_END);
io->va = iova;
	r_io_seek (io, here, R_IO_SEEK_SET);
	return size;
}
Exemple #2
0
R_API ut64 r_io_size(RIO *io) {
	int iova;
	ut64 size, here;
	if (!io) return 0LL;
	if (r_io_is_listener (io))
		return UT64_MAX;
	iova = io->va;
	io->va = 0;
	here = r_io_seek (io, 0, R_IO_SEEK_CUR);
	size = r_io_seek (io, 0, R_IO_SEEK_END);
	io->va = iova;
	r_io_seek (io, here, R_IO_SEEK_SET);
	return size;
}
Exemple #3
0
R_API int r_io_write(struct r_io_t *io, const ut8 *buf, int len) {
	int i, ret = -1;
	ut8 *data = NULL;

	/* check section permissions */
	if (io->enforce_rwx && !(r_io_section_get_rwx (io, io->off) & R_IO_WRITE))
		return -1;

	if (io->cached) {
		ret = r_io_cache_write (io, io->off, buf, len);
		if (ret == len)
			return len;
		if (ret > 0) {
			len -= ret;
			buf += ret;
		}
	}

	/* TODO: implement IO cache here. to avoid dupping work on vm for example */

	/* apply write binary mask */
	if (io->write_mask_fd != -1) {
		data = malloc (len);
		r_io_seek (io, io->off, R_IO_SEEK_SET);
		r_io_read (io, data, len);
		r_io_seek (io, io->off, R_IO_SEEK_SET);
		for (i=0; i<len; i++)
			data[i] = buf[i] & \
				io->write_mask_buf[i%io->write_mask_len];
		buf = data;
	}
	

	r_io_map_select(io,io->off);

	if (io->plugin) {
		if (io->plugin->write)
			ret = io->plugin->write (io, io->fd, buf, len);
		else eprintf ("r_io_write: io handler with no write callback\n");
	} else ret = write (io->fd->fd, buf, len);

	if (ret == -1)
		eprintf ("r_io_write: cannot write on fd %d\n", io->fd->fd);

	if (data)
		free (data);
	return ret;
}
Exemple #4
0
R_API bool r_core_seek(RCore *core, ut64 addr, bool rb) {
	core->offset = r_io_seek (core->io, addr, R_IO_SEEK_SET);
	if (rb) {
		r_core_block_read (core);
	}
	return core->offset == addr;
}
Exemple #5
0
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
#if 0
	int ret;
	if (r_io_seek (io, addr, R_IO_SEEK_SET)==UT64_MAX) {
		memset (buf, 0xff, len);
		return -1;
	}
	ret = r_io_read_internal (io, buf, len);
	if (ret<1)
		memset (buf, 0xff, len);
	return ret;
#else
	int ret, l, olen = len;
	int w = 0;
#if 1
	// HACK?: if io->va == 0 -> call seek+read without checking sections ?
	if (!io->va) {
		r_io_seek (io, addr, R_IO_SEEK_SET);
		return r_io_read_internal (io, buf, len);
	}
#endif
	while (len>0) {
		ut64 last = r_io_section_next (io, addr);
		l = (len > (last-addr))? (last-addr): len;
		if (l<1) l = len;
		// ignore seek errors
//		eprintf ("0x%llx %llx\n", addr+w, 
		r_io_seek (io, addr+w, R_IO_SEEK_SET);
		ret = r_io_read_internal (io, buf+w, l);
		if (ret <1) {
			memset (buf+w, 0xff, l); // reading out of file
			ret = 1;
		} else
		if (ret<l) {
		//	eprintf ("FOUND EOF AT %llx\n", addr+ret);
			l = ret;
		}
		w += l;
		len -= l;
	}
	return olen;
#endif
}
Exemple #6
0
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
	RIOSection *newsection;
	ut64 old = core->offset;
	ut64 ret;

	/* XXX unnecesary call */
	//r_io_set_fd (core->io, core->file->fd);
	core->io->section = core->section; // HACK
	ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
	newsection = core->io->section;

	if (ret == UT64_MAX) {
		//eprintf ("RET =%d %llx\n", ret, addr);
		/*
		   XXX handle read errors correctly
		   if (core->ffio) {
		   core->offset = addr;
		   } else return R_FALSE;
		 */
		//core->offset = addr;
		if (!core->io->va)
			return R_FALSE;
		memset (core->block, 0xff, core->blocksize);
	} else core->offset = addr;
	if (rb) {
		ret = r_core_block_read (core, 0);
		if (core->ffio) {
			if (ret<1 || ret > core->blocksize)
				memset (core->block, 0xff, core->blocksize);
			else memset (core->block+ret, 0xff, core->blocksize-ret);
			ret = core->blocksize;
			core->offset = addr;
		} else {
			if (ret<1) {
				core->offset = old;
				//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
			}
		}
	}
	if (core->section != newsection) {//&& core->io->section->arch) {
		int bits = 0;// = core->io->section->bits;
		const char *arch = r_io_section_get_archbits (core->io, core->offset, &bits);
		if (arch && bits) {
			r_config_set (core->config, "asm.arch", arch);
			r_config_set_i (core->config, "asm.bits", bits);
		}
		core->section = core->io->section;
	}
	return (ret==-1)? R_FALSE: R_TRUE;
}
Exemple #7
0
R_API int r_core_block_read(RCore *core, int next) {
	ut64 off;
	if (core->file == NULL) {
		memset (core->block, 0xff, core->blocksize);
		return -1;
	}
	r_io_set_fd (core->io, core->file->fd);
	off = r_io_seek (core->io, core->offset+((next)?core->blocksize:0), R_IO_SEEK_SET);
	if (off == UT64_MAX) {
		memset (core->block, 0xff, core->blocksize);
		return -1;
	}
	return (int)r_io_read (core->io, core->block, core->blocksize);
}
Exemple #8
0
R_API int r_io_buffer_load(RIO* io, ut64 addr, int len) {
	ut64 at;
	int i, r;
	ut8 buf[512];
	if (len<1) return R_FALSE;
	io->buffer_enabled = 0;
	for (i=0; i<len; i+=sizeof (buf)) {
		at = addr+i;
		r_io_seek (io, at, R_IO_SEEK_SET);
		memset (buf, 0xff, sizeof (buf));
		r = r_io_read (io, buf, sizeof (buf));
		if (r<1) break;
		r_cache_set (io->buffer, at, buf, sizeof (buf));
	}
	io->buffer_enabled = 1;
	return R_TRUE;
}
Exemple #9
0
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
	int ret;
	if (!core->io || !core->file || size<1)
		return R_FALSE;
#if 0
	r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
	ret = r_io_read_at (core->io, addr, buf, size);
	if (addr>=core->offset && addr<=core->offset+core->blocksize)
		r_core_block_read (core, 0);
#else
	r_io_set_fd (core->io, core->file->fd); // XXX ignore ret? -- ultra slow method.. inverse resolution of io plugin brbrb
	//ret = r_io_read_at (core->io, addr, buf, size);
	r_io_seek (core->io, addr, R_IO_SEEK_SET);
	ret = r_io_read (core->io, buf, size);
	if (ret != size) {
		if (ret>=size || ret<0) ret = 0;
		memset (buf+ret, 0xff, size-ret);
	}
	if (addr>=core->offset && addr<=core->offset+core->blocksize)
		r_core_block_read (core, 0);
#endif
	return (ret==size); //UT64_MAX);
}
Exemple #10
0
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) {
	ut64 old = core->offset;
	ut64 ret;

	/* XXX unnecesary call */
	//r_io_set_fd (core->io, core->file->fd);
	ret = r_io_seek (core->io, addr, R_IO_SEEK_SET);
	if (ret == UT64_MAX) {
//eprintf ("RET =%d %llx\n", ret, addr);
/*
	XXX handle read errors correctly
		if (core->ffio) {
			core->offset = addr;
		} else return R_FALSE;
*/
		//core->offset = addr;
		if (!core->io->va)
			return R_FALSE;
		memset (core->block, 0xff, core->blocksize);
	} else core->offset = addr;
	if (rb) {
		ret = r_core_block_read (core, 0);
		if (core->ffio) {
			if (ret<1 || ret > core->blocksize)
				memset (core->block, 0xff, core->blocksize);
			else memset (core->block+ret, 0xff, core->blocksize-ret);
			ret = core->blocksize;
			core->offset = addr;
		} else {
			if (ret<1) {
				core->offset = old;
				//eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr);
			}
		}
	}
	return (ret==-1)?R_FALSE:R_TRUE;
}
Exemple #11
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 #12
0
static int perform_mapped_file_yank(RCore *core, ut64 offset, ut64 len, const char *filename) {
	// grab the current file descriptor, so we can reset core and io state
	// after our io op is done
	RIODesc *yankdesc = NULL;
	ut64 fd = core->file? core->file->fd: -1, yank_file_sz = 0,
	     loadaddr = 0, addr = offset;
	int res = false;

	if (filename && *filename) {
		ut64 load_align = r_config_get_i (core->config, "file.loadalign");
		RIOMap *map = NULL;
		yankdesc = r_io_open_nomap (core->io, filename, R_PERM_R, 0644);
		// map the file in for IO operations.
		if (yankdesc && load_align) {
			yank_file_sz = r_io_size (core->io);
			map = r_io_map_add_next_available (core->io, yankdesc->fd, R_PERM_R, 0, 0, yank_file_sz, load_align);
			loadaddr = map? map->itv.addr: -1;
			if (yankdesc && map && loadaddr != -1) {
				// ***NOTE*** this is important, we need to
				// address the file at its physical address!
				addr += loadaddr;
			} else if (yankdesc) {
				eprintf ("Unable to map the opened file: %s", filename);
				r_io_desc_close (yankdesc);
				yankdesc = NULL;
			} else {
				eprintf ("Unable to open the file: %s", filename);
			}
		}
	}

	// if len is -1 then we yank in everything
	if (len == -1) {
		len = yank_file_sz;
	}

	// this wont happen if the file failed to open or the file failed to
	// map into the IO layer
	if (yankdesc) {
		ut64 res = r_io_seek (core->io, addr, R_IO_SEEK_SET);
		ut64 actual_len = len <= yank_file_sz? len: 0;
		ut8 *buf = NULL;
		if (actual_len > 0 && res == addr) {
			buf = malloc (actual_len);
			if (!r_io_read_at (core->io, addr, buf, actual_len)) {
				actual_len = 0;
			}
			r_core_yank_set (core, R_CORE_FOREIGN_ADDR, buf, len);
			res = true;
		} else if (res != addr) {
			eprintf (
				"ERROR: Unable to yank data from file: (loadaddr (0x%"
				PFMT64x ") (addr (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", res, addr,
				yank_file_sz );
		} else if (actual_len == 0) {
			eprintf (
				"ERROR: Unable to yank from file: addr+len (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", addr + len,
				yank_file_sz );
		}
		r_io_desc_close (yankdesc);
		free (buf);
	}
	if (fd != -1) {
		r_io_use_fd (core->io, fd);
		core->switch_file_view = 1;
		r_core_block_read (core);
	}
	return res;
}
Exemple #13
0
static void cmd_write_value (RCore *core, const char *input) {
	int type = 0;
	ut8 addr1;
	ut16 addr2;
	ut32 addr4, addr4_;
	ut64 addr8, off = 0LL;
	int wseek = r_config_get_i (core->config, "cfg.wseek");

	if (!input)
		return;

	if (input[0])
	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;
	case '1': type = 1; break;
	case '2': type = 2; break;
	case '4': type = 4; break;
	case '8': type = 8; break;
	}
	if (input && input[0] && input[1] && input[2]) {
		off = r_num_math (core->num, input+2);
	}
	if (core->file) {
		r_io_use_desc (core->io, core->file->desc);
	}
	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);
}
Exemple #14
0
R_API int r_core_shift_block(RCore *core, ut64 addr, ut64 b_size, st64 dist) {
	// bstart - block start, fstart file start
	ut64 fend = 0, fstart = 0, bstart = 0, file_sz = 0;
	ut8 * shift_buf = NULL;
	int res = false;

	if (!core->io || !core->file) {
		return false;
	}

	if (b_size == 0 || b_size == (ut64) -1) {
		r_io_use_fd (core->io, core->file->fd);
		file_sz = r_io_size (core->io);
		if (file_sz == UT64_MAX) {
			file_sz = 0;
		}
#if 0
		bstart = r_io_seek (core->io, addr, R_IO_SEEK_SET);
		fend = r_io_seek (core->io, 0, R_IO_SEEK_END);
		if (fend < 1) {
			fend = 0;
		}
#else
		bstart = 0;
		fend = file_sz;
#endif
		fstart = file_sz - fend;
		b_size = fend > bstart ? fend - bstart: 0;
	}

	if ((st64)b_size < 1) {
		return false;
	}
	shift_buf = calloc (b_size, 1);
	if (!shift_buf) {
		eprintf ("Cannot allocated %d byte(s)\n", (int)b_size);
		return false;
	}

	// cases
	// addr + b_size + dist > file_end
	//if ( (addr+b_size) + dist > file_end ) {
	//	res = false;
	//}
	// addr + b_size + dist < file_start (should work since dist is signed)
	//else if ( (addr+b_size) + dist < 0 ) {
	//	res = false;
	//}
	// addr + dist < file_start
	if (addr + dist < fstart) {
		res = false;
	// addr + dist > file_end
	} else if ( (addr) + dist > fend) {
		res = false;
	} else {
		r_io_use_fd (core->io, core->file->fd);
		r_io_read_at (core->io, addr, shift_buf, b_size);
		r_io_write_at (core->io, addr + dist, shift_buf, b_size);
		res = true;
	}
	r_core_seek (core, addr, 1);
	free (shift_buf);
	return res;
}
Exemple #15
0
R_API int r_io_write_at(RIO *io, ut64 addr, const ut8 *buf, int len) {
	if (r_io_seek (io, addr, R_IO_SEEK_SET)<0)
		return -1;
	return r_io_write (io, buf, len);
}
Exemple #16
0
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
	ut64 paddr, last, last2;
	int ms, ret, l, olen = len, w = 0;

	io->off = addr;
	memset (buf, 0xff, len); // probably unnecessary

	if (io->buffer_enabled)
		return r_io_buffer_read (io, addr, buf, len);
	while (len>0) {
		last = r_io_section_next (io, addr+w);
		last2 = r_io_map_next (io, addr+w); // XXX: must use physical address
		if (last == (addr+w)) last = last2;
		//else if (last2<last) last = last2;
		l = (len > (last-addr+w))? (last-addr+w): len;
		if (l<1) l = len;
		{
			paddr = w? r_io_section_vaddr_to_offset (io, addr+w): addr;
			if (len>0 && l>len) l = len;
			addr = paddr-w;
			if (r_io_seek (io, paddr, R_IO_SEEK_SET)==UT64_MAX) {
				memset (buf+w, 0xff, l);
			}
		}
#if 0
		if (io->zeromap)
			if (!r_io_map_get (io, addr+w)) {
				if (addr==0||r_io_section_getv (io, addr+w)) {
					memset (buf+w, 0xff, l);
eprintf ("RETRERET\n");
					return -1;
				}
			}
#endif
		// XXX is this necessary?
		ms = r_io_map_select (io, addr+w);
		ret = r_io_read_internal (io, buf+w, l);
//eprintf ("READ %d = %02x %02x %02x\n", ret, buf[w], buf[w+1], buf[w+2]);
		if (ret<1) {
			memset (buf+w, 0xff, l); // reading out of file
			ret = 1;
		} else if (ret<l) {
			l = ret;
		}
#if USE_CACHE
		if (io->cached) {
			r_io_cache_read (io, addr+w, buf+w, len-w);
		} else if (r_list_length (io->maps) >1) {
			if (!io->debug && ms>0) {
				//eprintf ("FAIL MS=%d l=%d d=%d\n", ms, l, d);
				/* check if address is vaddred in sections */
				ut64 o = r_io_section_offset_to_vaddr (io, addr+w);
				if (o == UT64_MAX) {
					ut64 o = r_io_section_vaddr_to_offset (io, addr+w);
					if (o == UT64_MAX)
						memset (buf+w, 0xff, l);
				}
				break;
			}
		}
#endif
		w += l;
		len -= l;
	}
	return olen;
}
Exemple #17
0
static void cmd_write_value (RCore *core, const char *input) {
	int type = 0;
	ut64 off = 0LL;
	ut8 buf[sizeof(ut64)];
	int wseek = r_config_get_i (core->config, "cfg.wseek");
	bool be = r_config_get_i (core->config, "cfg.bigendian");

	if (!input)
		return;

	if (input[0])
	switch (input[1]) {
	case '?':
	{
		const char* help_msg[] = {
			"Usage:", "wv[size] [value]", "write value of given size",
			"wv1", " 234", "write one byte with this value",
			"wv", " 0x834002", "write dword with this value",
			"Supported sizes are:", "1, 2, 4, 8", "",
			NULL};
		r_core_cmd_help (core, help_msg);
		return;
	}
	case '1': type = 1; break;
	case '2': type = 2; break;
	case '4': type = 4; break;
	case '8': type = 8; break;
	}
	if (input && input[0] && input[1] && input[2]) {
		off = r_num_math (core->num, input+2);
	}
	if (core->file) {
		r_io_use_desc (core->io, core->file->desc);
	}
	ut64 res = r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
	if (res == UT64_MAX) return;
	if (type == 0)
		type = (off&UT64_32U)? 8: 4;
	switch (type) {
	case 1:
		r_write_ble8 (buf, (ut8)(off & UT8_MAX));
		r_io_write (core->io, buf, 1);
		WSEEK (core, 1);
		break;
	case 2:
		r_write_ble16 (buf, (ut16)(off & UT16_MAX), be);
		r_io_write (core->io, buf, 2);
		WSEEK (core, 2);
		break;
	case 4:
		r_write_ble32 (buf, (ut32)(off & UT32_MAX), be);
		r_io_write (core->io, buf, 4);
		WSEEK (core, 4);
		break;
	case 8:
		r_write_ble64 (buf, off, be);
		r_io_write (core->io, buf, 8);
		WSEEK (core, 8);
		break;
	}
	r_core_block_read (core);
}
Exemple #18
0
static void cmd_write_value (RCore *core, const char *input) {
	int type = 0;
	ut64 off = 0LL;
	ut8 buf[sizeof(ut64)];
	int wseek = r_config_get_i (core->config, "cfg.wseek");
	bool be = r_config_get_i (core->config, "cfg.bigendian");

	if (!input)
		return;

	if (input[0])
	switch (input[1]) {
	case '?':
		r_core_cmd_help (core, help_msg_wv);
		return;
	case '1': type = 1; break;
	case '2': type = 2; break;
	case '4': type = 4; break;
	case '8': type = 8; break;
	}
	if (input && input[0] && input[1] && input[2]) {
		off = r_num_math (core->num, input+2);
	}
	if (core->file) {
		r_io_use_fd (core->io, core->file->fd);
	}
	ut64 res = r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
	if (res == UT64_MAX) return;
	if (type == 0)
		type = (off&UT64_32U)? 8: 4;
	switch (type) {
	case 1:
		r_write_ble8 (buf, (ut8)(off & UT8_MAX));
		if (!r_io_write (core->io, buf, 1)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 1);
		}
		break;
	case 2:
		r_write_ble16 (buf, (ut16)(off & UT16_MAX), be);
		if (!r_io_write (core->io, buf, 2)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 2);
		}
		break;
	case 4:
		r_write_ble32 (buf, (ut32)(off & UT32_MAX), be);
		if (!r_io_write (core->io, buf, 4)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 4);
		}
		break;
	case 8:
		r_write_ble64 (buf, off, be);
		if (!r_io_write (core->io, buf, 8)) {
			cmd_write_fail ();
		} else {
			WSEEK (core, 8);
		}
		break;
	}
	r_core_block_read (core);
}
Exemple #19
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 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_printf ("%s\n", p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = R_FALSE;
		char *input_shadow = NULL, *p = NULL;

		switch (input[1]) {
			case 'n':
				if (input[2] == ' ') {
					len = *input ? r_num_math (core->num, input+3) : 0;
					if (len > 0){
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, core->offset, len);
						core->offset = cur_off;
						r_core_block_read (core, 0);
					}
				}
				break;
			case 'N':
				if (input[2] == ' ') {
					input += 3;
					while (*input && *input == ' ') input++;
					addr = r_num_math (core->num, input);
					while (*input && *input != ' ') input++;
					input++;
					len = *input ? r_num_math (core->num, input) : 0;
					if (len > 0){
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, addr, len);
						cmd_suc = r_core_seek (core, cur_off, 1);
						core->offset = addr;
						r_core_block_read (core, 0);
					}
				}
				break;
			case 'x':
				if (input[2] == ' ') {
					input+=2;
					len = *input ? strlen (input) : 0;
					bytes = len > 1? malloc (len+1) : NULL;
					len = bytes ? r_hex_str2bin (input, bytes) : 0;
					if (len > 0) {
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, cur_off, len);
						if (cmd_suc) {
							r_core_write_at (core, cur_off, bytes, len);
						}
						core->offset = cur_off;
						r_core_block_read (core, 0);
					}
					free (bytes);
				}
				break;
			case 'X':
				if (input[2] == ' ') {
					addr = r_num_math (core->num, input+3);
					input += 3;
					while (*input && *input != ' ') input++;
					input++;
					len = *input ? strlen (input) : 0;
					bytes = len > 1? malloc (len+1) : NULL;
					len = bytes ? r_hex_str2bin (input, bytes) : 0;
					if (len > 0) {
						//ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, addr, len);
						if (cmd_suc) {
							r_core_write_at (core, addr, bytes, len);
						}
						core->offset = addr;
						r_core_block_read (core, 0);
					}
					free (bytes);
				}
				break;
			case 's':
				input +=  3;
				while (*input && *input == ' ') input++;
				len = strlen (input);
				input_shadow = len > 0? malloc (len+1): 0;

				// since the distance can be negative,
				// the r_num_math will perform an unwanted operation
				// the solution is to tokenize the string :/
				if (input_shadow) {
					strncpy (input_shadow, input, len+1);
					p = strtok (input_shadow, " ");
					addr = p && *p ? r_num_math (core->num, p) : 0;

					p = strtok (NULL, " ");
					dist = p && *p ? r_num_math (core->num, p) : 0;

					p = strtok (NULL, " ");
					b_size = p && *p ? r_num_math (core->num, p) : 0;
					if (dist != 0){
						r_core_shift_block (core, addr, b_size, dist);
						r_core_seek (core, addr, 1);
						cmd_suc = R_TRUE;
					}
				}
				free (input_shadow);
				break;
			case '?':
			default:
				cmd_suc = R_FALSE;
		}


		if (cmd_suc == R_FALSE) {
			r_cons_printf ("|Usage: write extend\n"
			"wen <num>               insert num null bytes at current offset\n"
			"wex <hex_bytes>         insert bytes at current offset\n"
			"weN <addr> <len>        insert bytes at address\n"
			"weX <addr> <hex_bytes>  insert bytes at address\n"
			"wes <addr>  <dist> <block_size>   shift a blocksize left or write in the editor\n"
			);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' '&&input[2]=='-')) {
			const char *tmpfile = ".tmp";
			char *out = r_core_editor (core, NULL);
			if (out) {
				// XXX hacky .. patch should support str, not only file
				r_file_dump (tmpfile, (ut8*)out, strlen (out));
				r_core_patch (core, tmpfile);
				r_file_rm (tmpfile);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				r_core_patch (core, input+2);
			} else {
				eprintf ("Usage: wp [-|r2patch-file]\n"
			         "TODO: rapatch format documentation here\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\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':
			if (!r_config_get_i (core->config, "io.cache"))
				eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, R_FALSE);
			break;
		}
		break;
	case ' ':
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		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 (!strcmp (arg, "-")) {
			char *out = r_core_editor (core, NULL);
			if (out) {
				r_io_write_at (core->io, core->offset,
					(ut8*)out, strlen (out));
				free (out);
			}
		} else
		if ((buf = (ut8*) r_file_slurp (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			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 (!strcmp (arg, "-")) {
			int len;
			ut8 *out;
			char *in = r_core_editor (core, NULL);
			if (in) {
				out = (ut8 *)strdup (in);
				if (out) {
					len = r_hex_str2bin (in, out);
					if (len>0)
						r_io_write_at (core->io, core->offset, out, len);
					free (out);
				}
				free (in);
			}
		} else
		if ((buf = r_file_slurp_hexpairs (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			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_use_desc (core->io, core->file->desc);
			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;
			if (len<core->blocksize) {
				b = core->block[len]&0xf;
				b |= (buf[len]&0xf0);
			} else b = buf[len];
			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+2, 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:
			r_cons_printf ("|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");
			free (buf);
		} 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_use_desc (core->io, core->file->desc);
				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_use_desc (core->io, core->file->desc);
			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 'e':
			case 'A':
			case 'x':
			case 'r':
			case 'l':
			case 'm':
			case 'd':
			case 'o':
			case 'w':
				if (input[2]!=' ') {
					if (input[1]=='e') r_cons_printf (
						"Usage: 'woe from-to step'\n");
					else r_cons_printf (
						"Usage: 'wo%c 00 11 22'\n", input[1]);
					free (ostr);
					return 0;
				}
			case '2':
			case '4':
				r_core_write_op (core, input+3, input[1]);
				r_core_block_read (core, 0);
				break;
			case 'R':
				r_core_cmd0 (core, "wr $b");
				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"
					"|  woe 02 03  \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  random bytes (alias for 'wr $b'\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;
	case 'd':
		if (input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		{
			ut8 ulen;
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core, 0);
			}
		}
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			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"
			"| wh r2        whereis/which shell command\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 undo/commit/reset/list (io.cache)\n"
			"| wd [off] [n] duplicate N bytes from offset at current seek (memcpy) (see y?)\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"
			"| ws pstring   write 1 byte for length and then the string\n"
			"| wf -|file    write contents of file at current offset\n"
			"| wF -|file    write contents of hexpairs file here\n"
			"| wp -|file    apply radare patch file. See wp? fmi\n"
			"| wt file [sz] write to file (from current seek, blocksize or sz bytes)\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 #20
0
static int perform_mapped_file_yank (RCore *core, ut64 offset, ut64 len, const char *filename) {
	// grab the current file descriptor, so we can reset core and io state
	// after our io op is done
	RIODesc *yankfd = NULL;
	ut64 fd = core->file ? core->file->desc->fd : -1, yank_file_sz = 0,
		 loadaddr = 0, addr = offset;
	int res = R_FALSE;

	if (filename && *filename) {
		ut64 load_align = r_config_get_i (core->config,
			"file.loadalign");
		RIOMap * map = NULL;
		yankfd = r_io_open (core->io, filename, R_IO_READ, 0644);
		// map the file in for IO operations.
		if (yankfd && load_align) {
			yank_file_sz = r_io_size (core->io);
			map = r_io_map_add_next_available (core->io,
				yankfd->fd,
				R_IO_READ, 0, 0,
				yank_file_sz,
				load_align);
			loadaddr = map ? map->from : -1;
			if (yankfd && map && loadaddr != -1) {
				// ***NOTE*** this is important, we need to
				// address the file at its physical address!
				addr += loadaddr;
			} else if (yankfd) {
				eprintf ("Unable to map the opened file: %s", filename);
				r_io_close (core->io, yankfd);
				yankfd = NULL;
			} else {
				eprintf ("Unable to open the file: %s", filename);
			}
		}
	}

	// if len is -1 then we yank in everything
	if (len == -1) len = yank_file_sz;

	IFDBG eprintf ("yankfd: %p, yank->fd = %d, fd=%d\n", yankfd,
		       (int)(yankfd ? yankfd->fd : -1), (int)fd);
	// this wont happen if the file failed to open or the file failed to
	// map into the IO layer
	if (yankfd) {
		ut64 res = r_io_seek (core->io, addr, R_IO_SEEK_SET),
		     actual_len = len <= yank_file_sz ? len : 0;
		ut8 *buf = NULL;
		IFDBG eprintf (
			"Addr (%"PFMT64d
			") file_sz (%"PFMT64d
			") actual_len (%"PFMT64d
			") len (%"PFMT64d
			") bytes from file: %s\n", addr, yank_file_sz,
			actual_len, len, filename);
		if (actual_len > 0 && res == addr) {
			IFDBG eprintf (
				"Creating buffer and reading %"PFMT64d
				" bytes from file: %s\n", actual_len, filename);
			buf = malloc (actual_len);
			actual_len = r_io_read_at (core->io, addr, buf,
				actual_len);
			IFDBG eprintf (
				"Reading %"PFMT64d " bytes from file: %s\n",
				actual_len, filename);
			/*IFDBG {
				int i = 0;
				eprintf ("Read these bytes from file: \n");
				for (i = 0; i < actual_len; i++)
					eprintf ("%02x", buf[i]);
				eprintf ("\n");
			}*/
			r_core_yank_set (core, R_CORE_FOREIGN_ADDR, buf, len);
			res = R_TRUE;
		} else if (res != addr) {
			eprintf (
				"ERROR: Unable to yank data from file: (loadaddr (0x%"
				PFMT64x ") (addr (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", res, addr,
				yank_file_sz );
		} else if (actual_len == 0) {
			eprintf (
				"ERROR: Unable to yank from file: addr+len (0x%"
				PFMT64x ") > file_sz (0x%"PFMT64x ")\n", addr+len,
				yank_file_sz );
		}
		r_io_close (core->io, yankfd);
		free (buf);
	}
	if (fd != -1) {
		r_io_raise (core->io, fd);
		core->switch_file_view = 1;
		r_core_block_read (core, 0);
	}
	return res;
}
Exemple #21
0
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
	int ret, l, olen = len;
	int w = 0;

#if 0
	// HACK?: if io->va == 0 -> call seek+read without checking sections ?
	if (!io->va) {
	//	r_io_seek (io, addr, R_IO_SEEK_SET);
		r_io_map_select (io, addr);
		ret = r_io_read_internal (io, buf, len);
		if (io->cached) {
			r_io_cache_read (io, addr, buf, len);
		}
		return ret;
	}
#endif
// XXX: this is buggy!
	while (len>0) {
		int ms;
		ut64 last = r_io_section_next (io, addr);
		l = (len > (last-addr))? (last-addr): len;
		if (l<1) l = len;
		// ignore seek errors
//		eprintf ("0x%llx %llx\n", addr+w, 
		//r_io_seek (io, addr+w, R_IO_SEEK_SET);
		if (r_io_seek (io, addr+w, R_IO_SEEK_SET)==UT64_MAX) {
			memset (buf+w, 0xff, l);
			return -1;
		}
		ms = r_io_map_select (io, addr+w);
		ret = r_io_read_internal (io, buf+w, l);
		if (ret<1) {
			memset (buf+w, 0xff, l); // reading out of file
			ret = 1;
		} else if (ret<l) {
		//	eprintf ("FOUND EOF AT %llx\n", addr+ret);
			l = ret;
		}
		if (io->cached) {
			r_io_cache_read (io, addr+w, buf+w, l);
			/*
			 * XXX: The 'else' below is fixing the io.cache
			 * with resized files. That may be wrong
			 */
		} else
		// hide non-mapped files here
		// do not allow reading on real addresses if mapped != 0
		if (!io->debug && ms>0) {
			//eprintf ("FAIL MS=%d l=%d d=%d\n", ms, l, d);
			/* check if address is vaddred in sections */
			ut64 o = r_io_section_offset_to_vaddr (io, addr);
			if (o == UT64_MAX) {
				ut64 o = r_io_section_vaddr_to_offset (io, addr);
				if (o == UT64_MAX)
					memset (buf+w, 0xff, l);
			}
			break;
		}
		w += l;
		len -= l;
	}
	return olen;
}