Esempio n. 1
0
static void parse_localvar (RParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign, char *ireg, bool att) {
	RStrBuf *sb = r_strbuf_new ("");
	if (att) {
		if (p->localvar_only) {
			if (ireg) {
				r_strbuf_setf (sb, "(%%%s)", ireg);
			}
			snprintf (newstr, newstr_len - 1, "%s%s", var, r_strbuf_get (sb));
		} else {
			if (ireg) {
				r_strbuf_setf (sb, ", %%%s", ireg);
			}
			snprintf (newstr, newstr_len - 1, "%s(%%%s%s)", var, reg, r_strbuf_get (sb));
		}
	} else {
		if (ireg) {
			r_strbuf_setf (sb, " + %s", ireg);
		}
		if (p->localvar_only) {
			snprintf (newstr, newstr_len - 1, "[%s%s]", var, r_strbuf_get (sb));
		} else {
			snprintf (newstr, newstr_len - 1, "[%s%s %c %s]", reg, r_strbuf_get (sb), sign, var);
		}
	}
	r_strbuf_free (sb);
}
Esempio n. 2
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	static struct disassemble_info disasm_obj;
	if (len < 2) {
		return -1;
	}
	buf_global = r_strbuf_get (&op->buf_asm);
	Offset = a->pc;
	if (len > sizeof (bytes)) {
		len = sizeof (bytes);
	}
	memcpy (bytes, buf, len); // TODO handle compact
	buf_len = len;
	/* prepare disassembler */
	memset (&disasm_obj,'\0', sizeof (struct disassemble_info));
	disasm_obj.buffer = bytes;
	disasm_obj.buffer_length = len;
	disasm_obj.read_memory_func = &arc_buffer_read_memory;
	disasm_obj.symbol_at_address_func = &symbol_at_address;
	disasm_obj.memory_error_func = &memory_error_func;
	disasm_obj.print_address_func = &print_address;
	disasm_obj.endian = !a->big_endian;
	disasm_obj.fprintf_func = &buf_fprintf;
	disasm_obj.stream = stdout;
	disasm_obj.mach = 0;
	r_strbuf_set (&op->buf_asm, "");
	if (a->bits == 16) {
		op->size = ARCompact_decodeInstr ((bfd_vma)Offset, &disasm_obj);
	} else {
		op->size = ARCTangent_decodeInstr ((bfd_vma)Offset, &disasm_obj);
	}
	if (op->size == -1) {
		r_strbuf_set (&op->buf_asm, "(data)");
	}
	return op->size;
}
Esempio n. 3
0
static int stack_clean (RCore *core, ut64 addr, RAnalFunction *fcn) {
	int offset, ret;
	char *tmp, *str, *sig;
	RAnalOp *op = r_core_anal_op (core, addr);
	if (!op) {
		return 0;
	}
	str = strdup (r_strbuf_get (&op->esil));
	if (!str) {
		return 0;
	}
	tmp = strchr (str, ',');
	if (!tmp) {
		free (str);
		return 0;
	}
	*tmp++ = 0;

	offset = r_num_math (core->num, str);
	const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
	sig = sdb_fmt (-1, "%s,+=", sp);
	ret = 0;
	if (!strncmp (tmp, sig, strlen (sig))) {
		const char *esil = sdb_fmt (-1, "%d,%s,-=", offset, sp);
		r_anal_esil_parse (core->anal->esil, esil);
		r_anal_esil_dumpstack (core->anal->esil);
		r_anal_esil_stack_free (core->anal->esil);
		r_core_esil_step (core, UT64_MAX, NULL);
		ret = op->size;
	}
	r_anal_op_free (op);
	free (str);
	return ret;
}
Esempio n. 4
0
R_API void r_anal_esil_trace (RAnalEsil *esil, RAnalOp *op) {
	const char *expr = r_strbuf_get (&op->esil);
	int esil_debug = esil->debug;
	if (ocbs_set) {
		eprintf ("cannot call recursively\n");
	}
	ocbs = esil->cb;
	ocbs_set = R_TRUE;
	if (!DB) DB = sdb_new0 ();

	sdb_num_set (DB, "idx", esil->trace_idx, 0);
	sdb_num_set (DB, KEY ("addr"), op->addr, 0);
//	sdb_set (DB, KEY ("opcode"), op->mnemonic, 0);
//	sdb_set (DB, KEY ("addr"), expr, 0);

	eprintf ("[ESIL] ADDR 0x%08"PFMT64x"\n", op->addr);
	//eprintf ("[ESIL] OPCODE %s\n", op->mnemonic);
	eprintf ("[ESIL] EXPR = %s\n", expr);
	/* set hooks */
	esil->debug = 0;
	esil->cb.hook_reg_read = trace_hook_reg_read;
	esil->cb.hook_reg_write = trace_hook_reg_write;
	esil->cb.hook_mem_read = trace_hook_mem_read;
	esil->cb.hook_mem_write = trace_hook_mem_write;
	/* evaluate esil expression */
	r_anal_esil_parse (esil, expr);
	/* restore hooks */
	esil->cb = ocbs;
	ocbs_set = R_FALSE;
	esil->debug = esil_debug;
	esil->trace_idx ++;
}
Esempio n. 5
0
static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf, int len) {
	static struct disassemble_info disasm_obj;
	if (len < 4) {
		return -1;
	}
	buf_global = r_strbuf_get (&op->buf_asm);
	Offset = a->pc;
	memcpy (bytes, buf, 4); // TODO handle thumb

	/* prepare disassembler */
	memset (&disasm_obj,'\0', sizeof (struct disassemble_info));
	mips_mode = a->bits;
	disasm_obj.arch = CPU_LOONGSON_2F;
	disasm_obj.buffer = bytes;
	disasm_obj.read_memory_func = &mips_buffer_read_memory;
	disasm_obj.symbol_at_address_func = &symbol_at_address;
	disasm_obj.memory_error_func = &memory_error_func;
	disasm_obj.print_address_func = &print_address;
	disasm_obj.buffer_vma = Offset;
	disasm_obj.buffer_length = 4;
	disasm_obj.endian = !a->big_endian;
	disasm_obj.fprintf_func = &buf_fprintf;
	disasm_obj.stream = stdout;

	op->size = (disasm_obj.endian == BFD_ENDIAN_LITTLE)
		? print_insn_little_mips ((bfd_vma)Offset, &disasm_obj)
		: print_insn_big_mips ((bfd_vma)Offset, &disasm_obj);
	if (op->size == -1) {
		r_strbuf_set (&op->buf_asm, "(data)");
	}
	return op->size;
}
Esempio n. 6
0
static int analyze(RAnal *anal, RAnalOp *op, ut64 offset, ut8* buf, int len) {
	char *bytes, *optype = NULL, *stackop = NULL;
	int ret;

	ret = r_anal_op (anal, op, offset, buf, len);
	if (ret) {
		stackop = stackop2str (op->stackop);
		optype = optype2str (op->type);
		bytes = r_hex_bin2strdup (buf, ret);
		printf ("bytes:    %s\n", bytes);
		printf ("type:     %s\n", optype);
		if (op->jump != -1LL)
			printf ("jump:     0x%08"PFMT64x"\n", op->jump);
		if (op->fail != -1LL)
			printf ("fail:     0x%08"PFMT64x"\n", op->fail);
		//if (op->ref != -1LL)
		//	printf ("ref:      0x%08"PFMT64x"\n", op->ref);
		if (op->val != -1LL)
			printf ("value:    0x%08"PFMT64x"\n", op->val);
		printf ("stackop:  %s\n", stackop);
		printf ("esil:     %s\n", r_strbuf_get (&op->esil));
		printf ("stackptr: %"PFMT64d"\n", op->stackptr);
		printf ("decode str: %s\n", r_anal_op_to_string (anal, op));
		printf ("--\n");
		free (optype);
		free (stackop);
		free (bytes);
	}
	return ret;
}
Esempio n. 7
0
R_API RAnalOp *r_anal_op_copy (RAnalOp *op) {
	RAnalOp *nop = R_NEW (RAnalOp);
	*nop = *op;
	nop->mnemonic = strdup (op->mnemonic);
	nop->src[0] = r_anal_value_copy (op->src[0]);
	nop->src[1] = r_anal_value_copy (op->src[1]);
	nop->src[2] = r_anal_value_copy (op->src[2]);
	nop->dst = r_anal_value_copy (op->dst);
	r_strbuf_init (&nop->esil);
	r_strbuf_set (&nop->esil, r_strbuf_get (&op->esil));
	return nop;
}
Esempio n. 8
0
static int assemble(RAsm *a, RAsmOp *op, const char *str) {
	ut8 *opbuf = (ut8*)r_strbuf_get (&op->buf);
	int ret = mips_assemble (str, a->pc, opbuf);
	if (a->big_endian) {
		ut8 tmp = opbuf[0];
		opbuf[0] = opbuf[3];
		opbuf[3] = tmp;
		tmp = opbuf[1];
		opbuf[1] = opbuf[2];
		opbuf[2] = tmp;
	}
	return ret;
}
Esempio n. 9
0
static inline void mk_reg_str(const char *regname, int delta, bool sign, bool att, char *ireg, char *dest, int len) {
	RStrBuf *sb = r_strbuf_new ("");
	if (att) {
		if (ireg) {
			r_strbuf_setf (sb, ", %%%s", ireg);
		}
		if (delta < 10) {
			snprintf (dest, len - 1, "%s%d(%%%s%s)", sign ? "" : "-", delta, regname, r_strbuf_get (sb));
		} else {
			snprintf (dest, len - 1, "%s0x%x(%%%s%s)", sign ? "" : "-", delta, regname, r_strbuf_get (sb));
		}
	} else {
		if (ireg) {
			r_strbuf_setf (sb, " + %s", ireg);
		}
		if (delta < 10) {
			snprintf (dest, len - 1, "[%s%s %c %d]", regname, r_strbuf_get (sb), sign ? '+':'-', delta);
		} else {
			snprintf (dest, len - 1, "[%s%s %c 0x%x]", regname, r_strbuf_get (sb), sign ? '+':'-', delta);
		}
	}
	r_strbuf_free (sb);
}
Esempio n. 10
0
static ut64 ws_find_label(int l, RIOBind iob) {
	RIO *io = iob.io;
	ut64 cur = 0, size = iob.desc_size (io->desc);
	ut8 buf[128];
	RAsmOp aop;
	iob.read_at (iob.io, cur, buf, 128);
	while (cur <= size && wsdis (&aop, buf, 128)) {
		const char *buf_asm = r_strbuf_get (&aop.buf_asm); // r_asm_op_get_asm (&aop);
		if (buf_asm && (strlen (buf_asm) > 4) && buf_asm[0] == 'm' && buf_asm[1] == 'a' && l == atoi (buf_asm + 5)) {
			return cur;
		}
		cur = cur + aop.size;
		iob.read_at (iob.io, cur, buf, 128);
	}
	return 0;
}
Esempio n. 11
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	RAsmLm32Instruction instr = {0};
	instr.value = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
	instr.addr = a->pc;
	if (r_asm_lm32_decode (&instr)) {
		r_strbuf_set (&op->buf_asm, "invalid");
		a->invhex = 1;
		return -1;
	}
	//op->buf_asm is 256 chars long, which is more than sufficient
	if (r_asm_lm32_stringify (&instr, r_strbuf_get (&op->buf_asm))) {
		r_strbuf_set (&op->buf_asm, "invalid");
		a->invhex = 1;
		return -1;
	}
	return 4;
}
Esempio n. 12
0
R_API RAnalOp *r_anal_op_copy (RAnalOp *op) {
	RAnalOp *nop = R_NEW0 (RAnalOp);
	if (!nop) return NULL;
	*nop = *op;
	if (op->mnemonic) {
		nop->mnemonic = strdup (op->mnemonic);
		if (!nop->mnemonic) {
			free (nop);
			return NULL;
		}
	} else {
		nop->mnemonic = NULL;
	}
	nop->src[0] = r_anal_value_copy (op->src[0]);
	nop->src[1] = r_anal_value_copy (op->src[1]);
	nop->src[2] = r_anal_value_copy (op->src[2]);
	nop->dst = r_anal_value_copy (op->dst);
	r_strbuf_init (&nop->esil);
	r_strbuf_set (&nop->esil, r_strbuf_get (&op->esil));
	return nop;
}
Esempio n. 13
0
R_API const char *r_anal_op_to_esil_string(RAnal *anal, RAnalOp *op) {
	return r_strbuf_get (&op->esil);
}
Esempio n. 14
0
static int do_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	int dlen = i8080_disasm (buf, r_strbuf_get (&op->buf_asm), len);
	return op->size = R_MAX (0, dlen);
}
Esempio n. 15
0
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
	int len = dcpu16_assemble ((ut8*)r_strbuf_get (&op->buf), buf);
	op->buf.len = len;
	return len;
}
Esempio n. 16
0
// TODO: add support for byte-per-byte opcode search
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp, int everyByte, int mode) {
	RCoreAsmHit *hit;
	RAsmOp op;
	RList *hits;
	ut64 at, toff = core->offset;
	ut8 *buf;
	int align = core->search->align;
	RRegex* rx = NULL;
	char *tok, *tokens[1024], *code = NULL, *ptr;
	int idx, tidx = 0, len = 0;
	int tokcount, matchcount, count = 0;
	int matches = 0;
	const int addrbytes = core->io->addrbytes;

	if (!input || !*input) {
		return NULL;
	}

	ut64 usrimm = r_num_math (core->num, input + 1);

	if (core->blocksize < 8) {
		eprintf ("error: block size too small\n");
		return NULL;
	}
	if (!(buf = (ut8 *)calloc (core->blocksize, 1))) {
		return NULL;
	}
	if (!(ptr = strdup (input))) {
		free (buf);
		return NULL;
	}
	if (!(hits = r_core_asm_hit_list_new ())) {
		free (buf);
		free (ptr);
		return NULL;
	}
	tokens[0] = NULL;
	for (tokcount = 0; tokcount < R_ARRAY_SIZE (tokens) - 1; tokcount++) {
		tok = strtok (tokcount? NULL: ptr, ";");
		if (!tok) {
			break;
		}
		tokens[tokcount] = r_str_trim_head_tail (tok);
	}
	tokens[tokcount] = NULL;
	r_cons_break_push (NULL, NULL);
	char *opst = NULL;
	for (at = from, matchcount = 0; at < to; at += core->blocksize) {
		if (r_cons_is_breaked ()) {
			break;
		}
		if (!r_io_is_valid_offset (core->io, at, 0)) {
			break;
		}
		(void)r_io_read_at (core->io, at, buf, core->blocksize);
		idx = 0, matchcount = 0;
		while (addrbytes * (idx + 1) <= core->blocksize) {
			ut64 addr = at + idx;
			if (addr >= to) {
				break;
			}
			r_asm_set_pc (core->assembler, addr);
			if (mode == 'i') {
				RAnalOp analop = {0};
				if (r_anal_op (core->anal, &analop, addr, buf + idx, 15, 0) < 1) {
					idx ++; // TODO: honor mininstrsz
					continue;
				}
				if (analop.val == usrimm) {
					if (!(hit = r_core_asm_hit_new ())) {
						r_list_purge (hits);
						R_FREE (hits);
						goto beach;
					}
					hit->addr = addr;
					hit->len = analop.size;  //  idx + len - tidx;
					if (hit->len == -1) {
						r_core_asm_hit_free (hit);
						goto beach;
					}
					r_asm_disassemble (core->assembler, &op, buf + addrbytes * idx,
					      core->blocksize - addrbytes * idx);
					hit->code = r_str_newf (r_strbuf_get (&op.buf_asm));
					idx = (matchcount)? tidx + 1: idx + 1;
					matchcount = 0;
					r_list_append (hits, hit);
					continue;
				}
				r_anal_op_fini (&analop);
				idx ++; // TODO: honor mininstrsz
				continue;
			} else if (mode == 'e') {
				RAnalOp analop = {0};
				if (r_anal_op (core->anal, &analop, addr, buf + idx, 15, R_ANAL_OP_MASK_ESIL) < 1) {
					idx ++; // TODO: honor mininstrsz
					continue;
				}
				//opsz = analop.size;
				opst = strdup (r_strbuf_get (&analop.esil));
				r_anal_op_fini (&analop);
			} else {
				if (!(len = r_asm_disassemble (
					      core->assembler, &op,
					      buf + addrbytes * idx,
					      core->blocksize - addrbytes * idx))) {
					idx = (matchcount)? tidx + 1: idx + 1;
					matchcount = 0;
					continue;
				}
				//opsz = op.size;
				opst = strdup (r_strbuf_get (&op.buf_asm));
			}
			if (opst) {
				matches = strcmp (opst, "invalid") && strcmp (opst, "unaligned");
			}
			if (matches && tokens[matchcount]) {
				if (!regexp) {
					matches = strstr (opst, tokens[matchcount]) != NULL;
				} else {
					rx = r_regex_new (tokens[matchcount], "");
					if (r_regex_comp (rx, tokens[matchcount], R_REGEX_EXTENDED|R_REGEX_NOSUB) == 0) {
						matches = r_regex_exec (rx, opst, 0, 0, 0) == 0;
					}
					r_regex_free (rx);
				}
			}
			if (align && align > 1) {
				if (addr % align) {
					matches = false;
				}
			}
			if (matches) {
				code = r_str_appendf (code, "%s; ", opst);
				if (matchcount == tokcount - 1) {
					if (tokcount == 1) {
						tidx = idx;
					}
					if (!(hit = r_core_asm_hit_new ())) {
						r_list_purge (hits);
						R_FREE (hits);
						goto beach;
					}
					hit->addr = addr;
					hit->len = idx + len - tidx;
					if (hit->len == -1) {
						r_core_asm_hit_free (hit);
						goto beach;
					}
					code[strlen (code) - 2] = 0;
					hit->code = strdup (code);
					r_list_append (hits, hit);
					R_FREE (code);
					matchcount = 0;
					idx = tidx + 1;
					if (maxhits) {
						count++;
						if (count >= maxhits) {
							//eprintf ("Error: search.maxhits reached\n");
							goto beach;
						}
					}
				} else if (!matchcount) {
					tidx = idx;
					matchcount++;
					idx += len;
				} else {
					matchcount++;
					idx += len;
				}
			} else {
				if (everyByte) {
					idx = matchcount? tidx + 1: idx + 1;
				} else {
					idx += R_MAX (1, len);
				}
				R_FREE (code);
				matchcount = 0;
			}
			R_FREE (opst);
		}
	}
	r_cons_break_pop ();
	r_asm_set_pc (core->assembler, toff);
beach:
	free (buf);
	free (ptr);
	free (code);
	R_FREE (opst);
	r_cons_break_pop ();
	return hits;
}
Esempio n. 17
0
static int disassemble(RAsm *a, struct r_asm_op_t *op, const ut8 *buf, int len) {
	char *buf_asm = r_strbuf_get (&op->buf_asm);
	arch_xap_disasm (buf_asm, buf, a->pc);
	return (op->size = 2);
}
Esempio n. 18
0
static RList *r_core_asm_back_disassemble (RCore *core, ut64 addr, int len, ut64 max_hit_count, ut8 disassmble_each_addr, ut32 extra_padding) {
	RList *hits;;
	RAsmOp op;
	ut8 *buf = NULL;
	ut8 max_invalid_b4_exit = 4,
		last_num_invalid = 0;
	int current_instr_len = 0;
	ut64 current_instr_addr = addr,
		current_buf_pos = 0,
		next_buf_pos = len;

	RCoreAsmHit dummy_value;
	ut32 hit_count = 0;

	if (disassmble_each_addr) {
		return r_core_asm_back_disassemble_all(core, addr, len, max_hit_count, extra_padding+1);
	}

	hits = r_core_asm_hit_list_new ();
	buf = malloc (len + extra_padding);
	if (!hits || !buf) {
		if (hits) {
			r_list_purge (hits);
			free (hits);
		}
		free (buf);
		return NULL;
	}

	if (!r_io_read_at (core->io, (addr + extra_padding) - len, buf, len + extra_padding)) {
		r_list_purge (hits);
		free (hits);
		free (buf);
		return NULL;
	}

	//
	// XXX - This is a heavy handed approach without a
	// 		an appropriate btree or hash table for storing
	//	 hits, because are using:
	//			1) Sorted RList with many inserts and searches
	//			2) Pruning hits to find the most optimal disassembly

	// greedy approach
	// 1) Consume previous bytes
	// 1a) Instruction is invalid (incr current_instr_addr)
	// 1b) Disasm is perfect
	// 1c) Disasm is underlap (disasm(current_instr_addr, next_instr_addr - current_instr_addr) short some bytes)
	// 1d) Disasm is overlap (disasm(current_instr_addr, next_instr_addr - current_instr_addr) over some bytes)

	memset (&dummy_value, 0, sizeof (RCoreAsmHit));
	// disassemble instructions previous to current address, extra_padding can move the location of addr
	// so we need to account for that with current_buf_pos
	current_buf_pos = len - extra_padding - 1;
	next_buf_pos = len + extra_padding - 1;
	current_instr_addr = addr - 1;
	do {
		if (r_cons_is_breaked ()) {
			break;
		}
		// reset assembler
		r_asm_set_pc (core->assembler, current_instr_addr);
		current_instr_len = next_buf_pos - current_buf_pos;
		current_instr_len = r_asm_disassemble (core->assembler, &op, buf+current_buf_pos, current_instr_len);
		IFDBG {
			ut32 byte_cnt =  current_instr_len ? current_instr_len : 1;
			eprintf("current_instr_addr: 0x%"PFMT64x", current_buf_pos: 0x%"PFMT64x", current_instr_len: %d \n", current_instr_addr, current_buf_pos, current_instr_len);

			ut8 *hex_str = (ut8*)r_hex_bin2strdup(buf+current_buf_pos, byte_cnt);
			eprintf ("==== current_instr_bytes: %s ",hex_str);

			if (current_instr_len > 0) {
				eprintf("op.buf_asm: %s\n", r_strbuf_get (&op.buf_asm));
			} else {
				eprintf("op.buf_asm: <invalid>\n");
			}
			free (hex_str);
		}
		// disassembly invalid
		if (current_instr_len == 0 || strstr (r_strbuf_get (&op.buf_asm), "invalid")) {
			if (current_instr_len == 0) {
				current_instr_len = 1;
			}
			add_hit_to_sorted_hits(hits, current_instr_addr, current_instr_len, /* is_valid */ false);
			hit_count ++;
			last_num_invalid ++;
		// disassembly perfect
		} else if (current_buf_pos + current_instr_len == next_buf_pos) {
			// i think this may be the only case where an invalid instruction will be
			// added because handle_forward_disassemble and handle_disassembly_overlap
			// are only called in cases where a valid instruction has been found.
			// and they are lazy, since they purge the hit list
			ut32 purge_results = 0;
			ut8 is_valid = true;
			IFDBG eprintf(" handling underlap case: current_instr_addr: 0x%"PFMT64x".\n", current_instr_addr);
			purge_results =  prune_hits_in_addr_range(hits, current_instr_addr, current_instr_len, /* is_valid */ true);
			if (purge_results) {
				handle_forward_disassemble(core, hits, buf, len, current_buf_pos+current_instr_len, current_instr_addr+current_instr_len, addr);
				hit_count = r_list_length(hits);
			}
			add_hit_to_sorted_hits(hits, current_instr_addr, current_instr_len, is_valid);
			//handle_forward_disassemble(core, hits, buf, len, current_buf_pos+current_instr_len, current_instr_addr+current_instr_len, addr/*end_addr*/);
			hit_count ++;
			next_buf_pos = current_buf_pos;
			last_num_invalid = 0;
		// disassembly underlap
		} else if (current_buf_pos + current_instr_len < next_buf_pos) {
			ut32 purge_results = 0;
			ut8 is_valid = true;
			purge_results =  prune_hits_in_addr_range(hits, current_instr_addr, current_instr_len, /* is_valid */ true);
			add_hit_to_sorted_hits(hits, current_instr_addr, current_instr_len, is_valid);

			if (hit_count < purge_results) {
				hit_count = 0; // WTF??
			} else {
				hit_count -= purge_results;
			}

			next_buf_pos = current_buf_pos;
			handle_forward_disassemble(core, hits, buf, len - extra_padding, current_buf_pos+current_instr_len, current_instr_addr+current_instr_len, addr);
			hit_count = r_list_length(hits);
			last_num_invalid = 0;
		// disassembly overlap
		} else if (current_buf_pos + current_instr_len > next_buf_pos) {
			//ut64 value = handle_disassembly_overlap(core, hits, buf, len, current_buf_pos, current_instr_addr);
			next_buf_pos = current_buf_pos;
			hit_count = r_list_length (hits);
			last_num_invalid = 0;
		}

		// walk backwards by one instruction
		IFDBG eprintf(" current_instr_addr: 0x%"PFMT64x" current_instr_len: %d next_instr_addr: 0x%04"PFMT64x"\n",
			current_instr_addr, current_instr_len, next_buf_pos);
		IFDBG eprintf(" hit count: %d \n", hit_count );
		current_instr_addr -= 1;
		current_buf_pos -= 1;

		if (hit_count >= max_hit_count &&
			(last_num_invalid >= max_invalid_b4_exit || last_num_invalid == 0)) {
			break;
		}
	} while (((int) current_buf_pos >= 0) && (int)(len - current_buf_pos) >= 0);

	r_asm_set_pc (core->assembler, addr);
	free (buf);
	return hits;
}
Esempio n. 19
0
File: op.c Progetto: aronsky/radare2
R_API char *r_asm_op_get_asm(RAsmOp *op) {
	return r_strbuf_get (&op->buf_asm);
}
Esempio n. 20
0
File: op.c Progetto: aronsky/radare2
R_API ut8 *r_asm_op_get_buf(RAsmOp *op) {
	r_return_val_if_fail (op, NULL);
	return (ut8*)r_strbuf_get (&op->buf);
}
Esempio n. 21
0
File: pj.c Progetto: f0829/radare2
R_API char *pj_fmt(PrintfCallback p, const char *fmt, ...) {
	va_list ap;
	va_start (ap, fmt);

	char ch[2] = { 0 };
	PJ *j = pj_new ();
	while (*fmt) {
		j->is_first = true;
		ch[0] = *fmt;
		switch (*fmt) {
		case '\\':
			fmt++;
			switch (*fmt) {
			// TODO: add \x, and \e
			case 'e':
				pj_raw (j, "\x1b");
				break;
			case 'r':
				pj_raw (j, "\r");
				break;
			case 'n':
				pj_raw (j, "\n");
				break;
			case 'b':
				pj_raw (j, "\b");
				break;
			}
			break;
		case '\'':
			pj_raw (j, "\"");
			break;
		case '%':
			fmt++;
			switch (*fmt) {
			case 'b':
				pj_b (j, va_arg (ap, int));
				break;
			case 's':
				pj_s (j, va_arg (ap, const char *));
				break;
			case 'S':
				{
					const char *s = va_arg (ap, const char *);
					char *es = r_base64_encode_dyn (s, -1);
					pj_s (j, es);
					free (es);
				}
				break;
			case 'n':
				pj_n (j, va_arg (ap, ut64));
				break;
			case 'd':
				pj_d (j, va_arg (ap, double));
				break;
			case 'i':
				pj_i (j, va_arg (ap, int));
				break;
			default:
				eprintf ("Invalid format\n");
				break;
			}
			break;
		default:
			ch[0] = *fmt;
			pj_raw (j, ch);
			break;
		}
		fmt++;
	}
	char *ret = NULL;
	if (p) {
		p ("%s", r_strbuf_get (j->sb));
		pj_free (j);
	} else {
		ret = pj_drain (j);
	}
	va_end (ap);
	return ret;
}
Esempio n. 22
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	static int omode = 0;
	int mode, ret;
	ut64 off = a->pc;

	mode =  (a->bits == 64)? CS_MODE_64: 
		(a->bits == 32)? CS_MODE_32:
		(a->bits == 16)? CS_MODE_16: 0;
	if (cd && mode != omode) {
		cs_close (&cd);
		cd = 0;
	}
	if (op) {
		op->size = 0;
	}
	omode = mode;
	if (cd == 0) {
		ret = cs_open (CS_ARCH_X86, mode, &cd);
		if (ret) {
			return 0;
		}
	}
	if (a->features && *a->features) {
		cs_option (cd, CS_OPT_DETAIL, CS_OPT_ON);
	} else {
		cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
	}
	// always unsigned immediates (kernel addresses)
	// maybe r2 should have an option for this too?
#if CS_API_MAJOR >= 4
	cs_option (cd, CS_OPT_UNSIGNED, CS_OPT_ON);
#endif
	if (a->syntax == R_ASM_SYNTAX_MASM) {
#if CS_API_MAJOR >= 4
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM);
#endif
	} else if (a->syntax == R_ASM_SYNTAX_ATT) {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
	} else {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
	}
	if (!op) {
		return true;
	}
	op->size = 1;
	cs_insn *insn = NULL;
#if USE_ITER_API
	{
		size_t size = len;
		if (!insn || cd < 1) {
			insn = cs_malloc (cd);
		}
		if (!insn) {
			cs_free (insn, n);
			return 0;
		}
		memset (insn, 0, insn->size);
		insn->size = 1;
		n = cs_disasm_iter (cd, (const uint8_t**)&buf, &size, (uint64_t*)&off, insn);
	}
#else
	n = cs_disasm (cd, (const ut8*)buf, len, off, 1, &insn);
#endif
	if (op) {
		op->size = 0;
	}
	if (a->features && *a->features) {
		if (!check_features (a, insn)) {
			op->size = insn->size;
			r_asm_op_set_asm (op, "illegal");
		}
	}
	if (op->size == 0 && n > 0 && insn->size > 0) {
		char *ptrstr;
		op->size = insn->size;
		char *buf_asm = sdb_fmt ("%s%s%s",
				insn->mnemonic, insn->op_str[0]?" ":"",
				insn->op_str);
		ptrstr = strstr (buf_asm, "ptr ");
		if (ptrstr) {
			memmove (ptrstr, ptrstr + 4, strlen (ptrstr + 4) + 1);
		}
		r_asm_op_set_asm (op, buf_asm);
	} else {
		decompile_vm (a, op, buf, len);
	}
	if (a->syntax == R_ASM_SYNTAX_JZ) {
		char *buf_asm = r_strbuf_get (&op->buf_asm);
		if (!strncmp (buf_asm, "je ", 3)) {
			memcpy (buf_asm, "jz", 2);
		} else if (!strncmp (buf_asm, "jne ", 4)) {
			memcpy (buf_asm, "jnz", 3);
		}
	}
#if 0
	// [eax + ebx*4]  =>  [eax + ebx * 4]
	char *ast = strchr (op->buf_asm, '*');
	if (ast && ast > op->buf_asm) {
		ast--;
		if (ast[0] != ' ') {
			char *tmp = strdup (ast + 1);
			if (tmp) {
				ast[0] = ' ';
				if (tmp[0] && tmp[1] && tmp[1] != ' ') {
					strcpy (ast, " * ");
					strcpy (ast + 3, tmp + 1);
				} else {
					strcpy (ast + 1, tmp);
				}
				free (tmp);
			}
		}
	}
#endif
#if USE_ITER_API
	/* do nothing because it should be allocated once and freed in the_end */
#else
	if (insn) {
		cs_free (insn, n);
	}
#endif
	return op->size;
}
Esempio n. 23
0
File: pj.c Progetto: f0829/radare2
R_API const char *pj_string(PJ *j) {
	return r_strbuf_get (j->sb);
}
Esempio n. 24
0
static int ws_anal(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
	memset (op, '\0', sizeof (RAnalOp));
	op->addr = addr;
	op->type = R_ANAL_OP_TYPE_UNK;
	RAsmOp *aop = R_NEW0 (RAsmOp);
	op->size = wsdis (aop, data, len);
	if (op->size) {
		const char *buf_asm = r_strbuf_get (&aop->buf_asm); // r_asm_op_get_asm (aop);
		switch (*buf_asm) {
		case 'n':
			op->type = R_ANAL_OP_TYPE_NOP;
			break;
		case 'e':
			op->type = R_ANAL_OP_TYPE_TRAP;
			break;
		case 'd':
			op->type = (buf_asm[1] == 'u')? R_ANAL_OP_TYPE_UPUSH: R_ANAL_OP_TYPE_DIV;
			break;
		case 'i':
			op->type = R_ANAL_OP_TYPE_ILL;
			break;
		case 'a':
			op->type = R_ANAL_OP_TYPE_ADD;
			break;
		case 'm':
			op->type = (buf_asm[1] == 'o') ? R_ANAL_OP_TYPE_MOD : R_ANAL_OP_TYPE_MUL;
			break;
		case 'r':
			op->type = R_ANAL_OP_TYPE_RET;
			break;
		case 'l':
			op->type = R_ANAL_OP_TYPE_LOAD;
			break;
		case 'c':
			if (buf_asm[1] == 'a') {
				op->type = R_ANAL_OP_TYPE_CALL;
				op->fail = addr + aop->size;
				op->jump = ws_find_label (atoi (buf_asm + 5), anal->iob);
			} else {
				op->type = R_ANAL_OP_TYPE_UPUSH;
			}
			break;
		case 'j':
			if (buf_asm[1] == 'm') {
				op->type = R_ANAL_OP_TYPE_JMP;
				op->jump = ws_find_label(atoi (buf_asm + 4), anal->iob);
			} else {
				op->type = R_ANAL_OP_TYPE_CJMP;
				op->jump = ws_find_label(atoi(buf_asm + 3), anal->iob);
			}
			op->fail = addr + aop->size;
			break;
		case 'g':
			op->type = R_ANAL_OP_TYPE_IO;
			break;
		case 'p':
			if (buf_asm[1] == 'o') {
				op->type = R_ANAL_OP_TYPE_POP;
			} else {
				if (buf_asm[2] == 's') {
					op->type = R_ANAL_OP_TYPE_PUSH;
					if (127 > atoi (buf_asm + 5) && atoi (buf_asm + 5) >= 33) {
						char c[4];
						c[3] = '\0';
						c[0] = c[2] = '\'';
						c[1] = (char) atoi (buf_asm + 5);
						r_meta_set_string (anal, R_META_TYPE_COMMENT, addr, c);
					}
				} else {
					op->type = R_ANAL_OP_TYPE_IO;
				}
			}
			break;
		case 's':
			switch (buf_asm[1]) {
			case 'u':
				op->type = R_ANAL_OP_TYPE_SUB;
				break;
			case 't':
				op->type = R_ANAL_OP_TYPE_STORE;
				break;
			case 'l':
				op->type = R_ANAL_OP_TYPE_LOAD;	// XXX
				break;
			case 'w':
				op->type = R_ANAL_OP_TYPE_ROR;
			}
			break;
		}
	}
	free (aop);
	return op->size;
}