Пример #1
0
R_API int r_core_lines_initcache(RCore *core, ut64 start_addr, ut64 end_addr) {
	int i, line_count;
	int bsz = core->blocksize;
	char *buf;
	ut64 off = start_addr;
	ut64 baddr;
	if (start_addr == UT64_MAX || end_addr == UT64_MAX) {
		return -1;
	}

	free (core->print->lines_cache);
	core->print->lines_cache = R_NEWS0 (ut64, bsz);
	if (!core->print->lines_cache) {
		return -1;
	}

	{
		RIOSection *s = r_io_section_mget_in (core->io, core->offset);
		baddr = s? s->paddr: r_config_get_i (core->config, "bin.baddr");
	}

	line_count = start_addr? 0: 1;
	core->print->lines_cache[0] = start_addr? 0: baddr;
	buf = malloc (bsz);
	if (!buf) {
		return -1;
	}
	r_cons_break_push (NULL, NULL);
	while (off < end_addr) {
		if (r_cons_is_breaked ()) {
			break;
		}
		r_io_read_at (core->io, off, (ut8 *) buf, bsz);
		for (i = 0; i < bsz; i++) {
			if (buf[i] == '\n') {
				core->print->lines_cache[line_count] = start_addr? off + i + 1: off + i + 1 + baddr;
				line_count++;
				if (line_count % bsz == 0) {
					ut64 *tmp = realloc (core->print->lines_cache,
						(line_count + bsz) * sizeof (ut64));
					if (tmp) {
						core->print->lines_cache = tmp;
					} else {
						R_FREE (core->print->lines_cache);
						goto beach;
					}
				}
			}
		}
		off += bsz;
	}
	free (buf);
	r_cons_break_pop ();
	return line_count;
beach:
	free (buf);
	r_cons_break_pop ();
	return -1;
}
Пример #2
0
static int r_debug_bochs_wait(RDebug *dbg, int pid) {
	char strIP[19];
	int i = 0;
	const char *x;
	char *ini = 0, *fin = 0;

	//eprintf ("bochs_wait:\n");

	if (bStep) {
		bStep = false;
	} else {
		r_cons_break_push (bochs_debug_break, dbg);
		i = 500;
		do {
			bochs_wait (desc);
			if (bBreak) {
				if (desc->data[0]) {
					eprintf ("ctrl+c %s\n", desc->data);
					bBreak = false;
					break;
				}
				i--;
				if (!i) {
					bBreak = false;
					eprintf ("empty ctrl+c.\n");
					break;
				}
			} else if (desc->data[0]) {
				//eprintf("stop on breakpoint%s\n",desc->data);
				break;
			}
		} while(1);
		r_cons_break_pop ();
	}
	//eprintf ("bochs_wait: loop done\n");
	i = 0;
	// Next at t=394241428
	// (0) [0x000000337635] 0020:0000000000337635 (unk. ctxt): add eax, esi              ; 03c6
	ripStop = 0;
	if ((x = strstr (desc->data, "Next at"))) {
		if ((ini = strstr (x, "[0x"))) {
			if ((fin = strstr (ini,"]"))) {
				int len = fin - ini - 1;
				strncpy (strIP, ini+1, len);
				strIP[len] = 0;
				//eprintf(" parada EIP = %s\n",strIP);
				ripStop = r_num_get (NULL, strIP);
			}
		}
	}
	desc->data[0] = 0;

	return true;
}
Пример #3
0
R_API bool r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size, int append) {
	ut64 i;
	ut8 *buf;
	int bs = core->blocksize;
	FILE *fd;
	if (append) {
		fd = r_sandbox_fopen (file, "ab");
	} else {
		r_sys_truncate (file, 0);
		fd = r_sandbox_fopen (file, "wb");
	}
	if (!fd) {
		eprintf ("Cannot open '%s' for writing\n", file);
		return false;
	}
	/* some io backends seems to be buggy in those cases */
	if (bs > 4096) {
		bs = 4096;
	}
	buf = malloc (bs);
	if (!buf) {
		eprintf ("Cannot alloc %d byte(s)\n", bs);
		fclose (fd);
		return false;
	}
	r_cons_break_push (NULL, NULL);
	for (i = 0; i < size; i += bs) {
		if (r_cons_is_breaked ()) {
			break;
		}
		if ((i + bs) > size) {
			bs = size - i;
		}
		r_io_read_at (core->io, addr + i, buf, bs);
		if (fwrite (buf, bs, 1, fd) < 1) {
			eprintf ("write error\n");
			break;
		}
	}
	r_cons_break_pop ();
	fclose (fd);
	free (buf);
	return true;
}
Пример #4
0
static void rtti_msvc_print_all(RVTableContext *context, int mode) {
	r_cons_break_push (NULL, NULL);
	RList *vtables = r_anal_vtable_search (context);
	RListIter *vtableIter;
	RVTableInfo *table;

	if (vtables) {
		r_list_foreach (vtables, vtableIter, table) {
			if (r_cons_is_breaked ()) {
				break;
			}
			r_anal_rtti_msvc_print_at_vtable (context, table->saddr, mode);
			r_cons_print ("\n");
		}
	}
	r_list_free (vtables);

	r_cons_break_pop ();
}
Пример #5
0
static void draw_vertical_line (RConsCanvas *c, int x, int y, int height) {
	int i;
	/* do not render offscreen vertical lines */
	if (x + c->sx < 0) {
		return;
	}
	if (x + c->sx > c->w) {
		return;
	}
	const char *vline = useUtf8? RUNECODESTR_LINE_VERT : "|";
	r_cons_break_push (NULL, NULL);
	for (i = y; i < y + height; i++) {
		if (r_cons_is_breaked ()) {
			break;
		}
		if (G (x, i)) {
			W (vline);
		}
	}
	r_cons_break_pop ();
}
Пример #6
0
R_API ut64 r_debug_esil_step(RDebug *dbg, ut32 count) {
	count++;
	has_match = 0;
	r_cons_break_push (NULL, NULL);
	do {
		if (r_cons_is_breaked ()) {
			break;
		}
		if (has_match) {
			eprintf ("EsilBreak match at 0x%08"PFMT64x"\n", opc);
			break;
		}
		if (count > 0) {
			count--;
			if (!count) {
				//eprintf ("Limit reached\n");
				break;
			}
		}
	} while (r_debug_esil_stepi (dbg));
	r_cons_break_pop ();
	return opc;
}
Пример #7
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) {
	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;
	int tokcount, matchcount, count = 0;
	int matches = 0, addrbytes = core->assembler->addrbytes;

	if (!*input) {
		return NULL;
	}
	if (core->blocksize <= OPSZ) {
		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);
	for (at = from, matchcount = 0; at < to; at += core->blocksize) {
		matches = 0;
		if (r_cons_is_breaked ()) {
			break;
		}
		if (!r_io_read_at (core->io, at, buf, core->blocksize)) {
			break;
		}
		idx = 0, matchcount = 0;
		while (addrbytes * (idx + 1) <= core->blocksize) {
			ut64 addr = at + idx;
			r_asm_set_pc (core->assembler, addr);
			if (!(len = r_asm_disassemble (
				      core->assembler, &op,
				      buf + addrbytes * idx,
				      core->blocksize - addrbytes * idx))) {
				idx = (matchcount)? tidx + 1: idx + 1;
				matchcount = 0;
				continue;
			}
			matches = strcmp (op.buf_asm, "invalid") && strcmp (op.buf_asm, "unaligned");
			if (matches && tokens[matchcount]) {
				if (!regexp) {
					matches = strstr(op.buf_asm, tokens[matchcount]) != NULL;
				} else {
					rx = r_regex_new (tokens[matchcount], "");
					matches = r_regex_exec (rx, op.buf_asm, 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; ", op.buf_asm);
				if (matchcount == tokcount - 1) {
					if (tokcount == 1) {
						tidx = idx;
					}
					if (!(hit = r_core_asm_hit_new ())) {
						r_list_purge (hits);
						free (hits);
						hits = NULL;
						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 {
				idx = matchcount? tidx + 1: idx + 1;
				R_FREE (code);
				matchcount = 0;
			}
		}
	}
	r_cons_break_pop ();
	r_asm_set_pc (core->assembler, toff);
beach:
	free (buf);
	free (ptr);
	free (code);
	r_cons_break_pop ();
	return hits;
}
Пример #8
0
static void draw_horizontal_line (RConsCanvas *c, int x, int y, int width, int style) {
	const char *l_corner = "?", *r_corner = "?";
	int i;

	if (width < 1) {
		return;
	}
	/* do not render offscreen horizontal lines */
	if (y + c->sy < 0) {
		return;
	}
	if (y + c->sy > c->h) {
		return;
	}

	switch (style) {
	case APEX_DOT:
		if (useUtf8) {
			if (useUtf8Curvy) {
				l_corner = RUNECODESTR_CURVE_CORNER_BL;
				r_corner = RUNECODESTR_CURVE_CORNER_TR;
			} else {
				l_corner = RUNECODESTR_CORNER_BL;
				r_corner = RUNECODESTR_CORNER_TR;
			}
		} else {
			l_corner = "'";
			r_corner = ".";
		}
		break;
	case DOT_APEX:
		if (useUtf8) {
			if (useUtf8Curvy) {
				l_corner = RUNECODESTR_CURVE_CORNER_TL;
				r_corner = RUNECODESTR_CURVE_CORNER_BR;
			} else {
				l_corner = RUNECODESTR_CORNER_TL;
				r_corner = RUNECODESTR_CORNER_BR;
			}
		} else {
			l_corner = ".";
			r_corner = "'";
		}
		break;
	case REV_APEX_APEX:
		if (useUtf8) {
			if (useUtf8Curvy) {
				l_corner = RUNECODESTR_CURVE_CORNER_BL;
				r_corner = RUNECODESTR_CURVE_CORNER_BR;
			} else {
				l_corner = RUNECODESTR_CORNER_BL;
				r_corner = RUNECODESTR_CORNER_BR;
			}
		} else {
			l_corner = "`";
			r_corner = "'";
		}
		break;
	case DOT_DOT:
		if (useUtf8) {
			if (useUtf8Curvy) {
				l_corner = RUNECODESTR_CURVE_CORNER_TL;
				r_corner = RUNECODESTR_CURVE_CORNER_TR;
			} else {
				l_corner = RUNECODESTR_CORNER_TL;
				r_corner = RUNECODESTR_CORNER_TR;
			}
		} else {
			l_corner = r_corner = ".";
		}
		break;
	case NRM_DOT:
		if (useUtf8) {
			l_corner = RUNECODESTR_LINE_HORIZ;
			if (useUtf8Curvy) {
				r_corner = RUNECODESTR_CURVE_CORNER_TR;
			} else {
				r_corner = RUNECODESTR_CORNER_TR;
			}
		} else {
			l_corner = "-";
			r_corner = ".";
		}
		break;
	case NRM_APEX:
		if (useUtf8) {
			l_corner = RUNECODESTR_LINE_HORIZ;
			if (useUtf8Curvy) {
				r_corner = RUNECODESTR_CURVE_CORNER_BR;
			} else {
				r_corner = RUNECODESTR_CORNER_BR;
			}
		} else {
			l_corner = "-";
			r_corner = "'";
		}
		break;
	case DOT_NRM:
		if (useUtf8) {
			if (useUtf8Curvy) {
				l_corner = RUNECODESTR_CURVE_CORNER_TL;
			} else {
				l_corner = RUNECODESTR_CORNER_TL;
			}
			r_corner = RUNECODESTR_LINE_HORIZ;
		} else {
			l_corner = ".";
			r_corner = "-";
		}
		break;
	case REV_APEX_NRM:
		if (useUtf8) {
			if (useUtf8Curvy) {
				l_corner = RUNECODESTR_CURVE_CORNER_BL;
			} else {
				l_corner = RUNECODESTR_CORNER_BL;
			}
			r_corner = RUNECODESTR_LINE_HORIZ;
		} else {
			l_corner = "`";
			r_corner = "-";
		}
		break;
	case NRM_NRM:
	default:
		if (useUtf8) {
			l_corner = r_corner = RUNECODESTR_LINE_HORIZ;
		} else {
			l_corner = r_corner = "-";
		}
		break;
	}

	if (G (x, y)) {
		W (l_corner);
	}

	const char *hline = useUtf8? RUNECODESTR_LINE_HORIZ : "-";
	r_cons_break_push (NULL, NULL);
	for (i = x + 1; i < x + width - 1; i++) {
		if (r_cons_is_breaked ()) {
			break;
		}
		if (G (i, y)) {
			W (hline);
		}
	}
	r_cons_break_pop ();

	if (G (x + width - 1, y)) {
		W (r_corner);
	}
}
Пример #9
0
R_API void r_cons_flush() {
	const char *tee = I.teefile;
	if (I.noflush) {
		return;
	}
	if (I.null) {
		r_cons_reset ();
		return;
	}
	r_cons_filter ();
	if (I.is_interactive && I.fdout == 1) {
		/* Use a pager if the output doesn't fit on the terminal window. */
		if (I.pager && *I.pager && I.buffer_len > 0
				&& r_str_char_count (I.buffer, '\n') >= I.rows) {
			I.buffer[I.buffer_len-1] = 0;
			r_sys_cmd_str_full (I.pager, I.buffer, NULL, NULL, NULL);
			r_cons_reset ();

		} else if (I.buffer_len > CONS_MAX_USER) {
#if COUNT_LINES
			int i, lines = 0;
			for (i = 0; I.buffer[i]; i++) {
				if (I.buffer[i] == '\n') {
					lines ++;
				}
			}
			if (lines > 0 && !r_cons_yesno ('n',"Do you want to print %d lines? (y/N)", lines)) {
				r_cons_reset ();
				return;
			}
#else
			char buf[64];
			char *buflen = r_num_units (buf, I.buffer_len);
			if (buflen && !r_cons_yesno ('n',"Do you want to print %s chars? (y/N)", buflen)) {
				r_cons_reset ();
				return;
			}
#endif
			// fix | more | less problem
			r_cons_set_raw (1);
		}
	}
	if (tee && *tee) {
		FILE *d = r_sandbox_fopen (tee, "a+");
		if (d) {
			if (I.buffer_len != fwrite (I.buffer, 1, I.buffer_len, d)) {
				eprintf ("r_cons_flush: fwrite: error (%s)\n", tee);
			}
			fclose (d);
		} else {
			eprintf ("Cannot write on '%s'\n", tee);
		}
	}
	r_cons_highlight (I.highlight);
	// is_html must be a filter, not a write endpoint
	if (I.is_html) {
		r_cons_html_print (I.buffer);
	} else {
		if (I.is_interactive && !r_sandbox_enable (false)) {
			if (I.linesleep > 0 && I.linesleep < 1000) {
				int i = 0;
				int pagesize = R_MAX (1, I.pagesize);
				char *ptr = I.buffer;
				char *nl = strchr (ptr, '\n');
				int len = I.buffer_len;
				I.buffer[I.buffer_len] = 0;
				r_cons_break_push (NULL, NULL);
				while (nl && !r_cons_is_breaked ()) {
					r_cons_write (ptr, nl - ptr + 1);
					if (!(i % pagesize)) {
						r_sys_usleep (I.linesleep * 1000);
					}
					ptr = nl + 1;
					nl = strchr (ptr, '\n');
					i++;
				}
				r_cons_write (ptr, I.buffer + len - ptr);
				r_cons_break_pop ();
			} else {
				r_cons_write (I.buffer, I.buffer_len);
			}
		} else {
			r_cons_write (I.buffer, I.buffer_len);
		}
	}

	r_cons_reset ();
	if (I.newline) {
		eprintf ("\n");
		I.newline = false;
	}
}
Пример #10
0
/* Callback to trigger SIGINT signal */
static void r_debug_native_stop(RDebug *dbg) {
	r_debug_kill (dbg, dbg->pid, dbg->tid, SIGINT);
	r_cons_break_pop ();
}
Пример #11
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;
}