Beispiel #1
0
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
	const bool is_thumb = (a->bits == 16);
	int opsize;
	ut32 opcode;
	if (a->bits == 64) {
		if (!arm64ass (buf, a->pc, &opcode)) {
			return -1;
		}
	} else {
		opcode = armass_assemble (buf, a->pc, is_thumb);
		if (a->bits != 32 && a->bits != 16) {
			eprintf ("Error: ARM assembler only supports 16 or 32 bits\n");
			return -1;
		}
	}
	if (opcode == UT32_MAX) {
		return -1;
	}
	if (is_thumb) {
		const int o = opcode >> 16;
		opsize = o > 0? 4: 2; //(o&0x80 && ((o&0xe0)==0xe0))? 4: 2;
		if (opsize == 4) {
			if (a->big_endian) {
				r_write_le32 (op->buf, opcode);
			} else {
				r_write_be32 (op->buf, opcode);
			}
		} else if (opsize == 2) {
			r_write_be16 (op->buf, opcode & UT16_MAX);
		}
	} else {
Beispiel #2
0
static void __patch_reloc(RBuffer *buf, ut32 addr_to_patch, ut32 data_offset) {
	ut8 val[4] = {
		0
	};
	r_write_le32 (val, data_offset);
	r_buf_write_at (buf, addr_to_patch, (void *) val, sizeof (val));
}
Beispiel #3
0
// TODO: SEE: R_API ut64 r_reg_get_value(RReg *reg, RRegItem *item) { .. dupped code?
R_API int r_mem_set_num(ut8 *dest, int dest_size, ut64 num) {
	// LITTLE ENDIAN is the default for streams
	switch (dest_size) {
	case 1:
		r_write_le8 (dest, (ut8) (num & UT8_MAX));
		break;
	case 2:
		r_write_le16 (dest, (ut16) (num & UT16_MAX));
		break;
	case 4:
		r_write_le32 (dest, (ut32) (num & UT32_MAX));
		break;
	case 8:
		r_write_le64 (dest, num);
		break;
	default:
		return false;
	}
	return true;
}
Beispiel #4
0
R_API int r_core_write_op(RCore *core, const char *arg, char op) {
	int i, j, len, ret = false;
	char *str = NULL;
	ut8 *buf;

	// XXX we can work with config.block instead of dupping it
	buf = (ut8 *)malloc (core->blocksize);
	if (!buf) {
		goto beach;
	}
	memcpy (buf, core->block, core->blocksize);

	if (op!='e') {
		// fill key buffer either from arg or from clipboard
		if (arg) {  // parse arg for key
			// r_hex_str2bin() is guaranteed to output maximum half the
			// input size, or 1 byte if there is just a single nibble.
			str = (char *)malloc (strlen (arg) / 2 + 1);
			if (!str) {
				goto beach;
			}
			len = r_hex_str2bin (arg, (ut8 *)str);
			// Output is invalid if there was just a single nibble,
			// but in that case, len is negative (-1).
			if (len <= 0) {
				eprintf ("Invalid hexpair string\n");
				goto beach;
			}
		} else {  // use clipboard as key
			len = core->yank_buf->length;
			if (len <= 0) {
				eprintf ("Clipboard is empty and no value argument(s) given\n");
				goto beach;
			}
			str = r_mem_dup (core->yank_buf->buf, len);
			if (!str) {
				goto beach;
			}
		}
	} else {
		len = 0;
	}

	// execute the operand
	if (op=='e') {
		int wordsize = 1;
		char *os, *p, *s = strdup (arg);
		int n = 0, from = 0, to = UT8_MAX, dif = 0, step = 1;
		os = s;
		p = strchr (s, ' ');
		if (p) {
			*p = 0;
			from = r_num_math (core->num, s);
			s = p + 1;
		}
		p = strchr (s, ' ');
		if (p) {
			*p = 0;
			to = r_num_math (core->num, s);
			s = p + 1;
		}
		p = strchr (s, ' ');
		if (p) {
			*p = 0;
			step = r_num_math (core->num, s);
			s = p + 1;
			wordsize = r_num_math (core->num, s);
		} else {
			step = r_num_math (core->num, s);
		}
		free (os);
		eprintf ("from %d to %d step %d size %d\n", from, to, step, wordsize);
		dif = (to <= from)? UT8_MAX: to - from + 1;
		if (wordsize == 1) {
			from %= (UT8_MAX + 1);
		}
		if (dif < 1) {
			dif = UT8_MAX + 1;
		}
		if (step < 1) {
			step = 1;
		}
		if (wordsize < 1) {
			wordsize = 1;
		}
		if (wordsize == 1) {
			for (i = n = 0; i < core->blocksize; i++, n += step) {
				buf[i] = (ut8)(n % dif) + from;
			}
		} else if (wordsize == 2) {
			ut16 num16 = from;
			for (i = 0; i < core->blocksize; i += wordsize, num16 += step) {
				r_write_le16 (buf + i, num16);
			}
		} else if (wordsize == 4) {
			ut32 num32 = from;
			for (i = 0; i < core->blocksize; i += wordsize, num32 += step) {
				r_write_le32 (buf + i, num32);
			}
		} else if (wordsize == 8) {
			ut64 num64 = from;
			for (i = 0; i < core->blocksize; i += wordsize, num64 += step) {
				r_write_le64 (buf + i, num64);
			}
		} else {
			eprintf ("Invalid word size. Use 1, 2, 4 or 8\n");
		}
	} else if (op=='2' || op=='4') {
		op -= '0';
		// if i < core->blocksize would pass the test but buf[i+3] goes beyond the buffer
		if (core->blocksize > 3) {
			for (i=0; i<core->blocksize-3; i+=op) {
				/* endian swap */
				ut8 tmp = buf[i];
				buf[i] = buf[i+3];
				buf[i+3] = tmp;
				if (op == 4) {
					tmp = buf[i + 1];
					buf[i + 1] = buf[i + 2];
					buf[i + 2] = tmp;
				}
			}
		}
	} else {
		for (i=j=0; i<core->blocksize; i++) {
			switch (op) {
			case 'x': buf[i] ^= str[j]; break;
			case 'a': buf[i] += str[j]; break;
			case 's': buf[i] -= str[j]; break;
			case 'm': buf[i] *= str[j]; break;
			case 'w': buf[i] = str[j]; break;
			case 'd': buf[i] = (str[j])? buf[i] / str[j]: 0; break;
			case 'r': buf[i] >>= str[j]; break;
			case 'l': buf[i] <<= str[j]; break;
			case 'o': buf[i] |= str[j]; break;
			case 'A': buf[i] &= str[j]; break;
			}
			j++;
			if (j >= len) {
				j = 0; /* cyclic key */
			}
		}
	}

	ret = r_core_write_at (core, core->offset, buf, core->blocksize);
beach:
	free (buf);
	free (str);
	return ret;
}
Beispiel #5
0
R_API bool r_reg_set_value(RReg *reg, RRegItem *item, ut64 value) {
	int fits_in_arena;
	ut8 bytes[12];
	ut8 *src = bytes;

	if (!item) {
		eprintf ("r_reg_set_value: item is NULL\n");
		return false;
	}
	switch (item->size) {
	case 80:
	case 96: // long floating value
		r_reg_set_longdouble (reg, item, (long double)value);
		break;
	case 64:
		if (reg->big_endian) {
			r_write_be64 (src, value);
		} else {
			r_write_le64 (src, value);
		}
		break;
	case 32:
		if (reg->big_endian) {
			r_write_be32 (src, value);
		} else {
			r_write_le32 (src, value);
		}
		break;
	case 16:
		if (reg->big_endian) {
			r_write_be16 (src, value);
		} else {
			r_write_le16 (src, value);
		}
		break;
	case 8:
		r_write_ble8 (src, (ut8)(value & UT8_MAX));
		break;
	case 1:
		if (value) {
			ut8 *buf = reg->regset[item->arena].arena->bytes + (item->offset / 8);
			int bit = (item->offset % 8);
			ut8 mask = (1 << bit);
			buf[0] = (buf[0] & (0xff ^ mask)) | mask;
		} else {
			int idx = item->offset / 8;
			RRegArena *arena = reg->regset[item->arena].arena;
			if (idx + item->size > arena->size) {
				eprintf ("RRegSetOverflow %d vs %d\n", idx + item->size, arena->size);
				return false;
			}
			ut8 *buf = arena->bytes + idx;
			int bit = item->offset % 8;
			ut8 mask = 0xff ^ (1 << bit);
			buf[0] = (buf[0] & mask) | 0;
		}
		return true;
	default:
		eprintf ("r_reg_set_value: Bit size %d not supported\n", item->size);
		return false;
	}
	fits_in_arena = (reg->regset[item->arena].arena->size - BITS2BYTES (item->offset) - BITS2BYTES (item->size)) >= 0;
	if (src && fits_in_arena) {
		r_mem_copybits (reg->regset[item->arena].arena->bytes +
					BITS2BYTES (item->offset),
				src, item->size);
		return true;
	}
	eprintf ("r_reg_set_value: Cannot set %s to 0x%" PFMT64x "\n", item->name, value);
	return false;
}