Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
0
char *mreplace(char *string, char *se,char *rep) {
#ifdef _MSC_VER
#define nmatch 16
#else
	const size_t nmatch = 16;
#endif
	memChunk *search,*temp,*found,*ffound;
	unsigned long offset = 0;
	RRegexMatch pm[nmatch];
	char *res, field[16];
	char noMatch = 0;
	int status, i;
	RRegex *re;

	if (!string) return "";
	if (!strlen (se)) return string;
	if (!strcmp (se,rep)) return string;

	temp = memStringReserve (string,INPUTLINE_BUFFER_REPLACE_SIZE);
	search = memStringReserve (se,INPUTLINE_BUFFER_REPLACE_SIZE);

	sreplace (search->address, "\\d", "[0-9]", 1, INPUTLINE_BUFFER_REPLACE_SIZE);

#if MDEBUG2
	sData=strdup(string);
	DBG("mreplace(string,se,re)","string  : %s",sData);
	DBG("mreplace(string,se,re)","search  : %s",search->address);
	DBG("mreplace(string,se,re)","replace : %s",rep);
#endif
	re = r_regex_new ("", 0);

	if (r_regex_comp (re, search->address, R_REGEX_EXTENDED) != 0)
		if(r_regex_comp (re, search->address, R_REGEX_EXTENDED<<1))
			noMatch = 1;
	if ((status = r_regex_exec (re, string, nmatch, pm, 0)))
		noMatch = 1;
	if (noMatch) {
		memFree (temp);
		memFree (search);
		r_regex_free (re);
		return (char*)string;
	}

	found  = memReserve (INPUTLINE_BUFFER_REPLACE_SIZE);
	ffound = memReserve (INPUTLINE_BUFFER_REPLACE_SIZE);
	while (!status) {
		offset = strlen (temp->address) - strlen (string);
		snprintf (found->address, INPUTLINE_BUFFER_REPLACE_SIZE, "%.*s",
				(int)(size_t)(pm[0].rm_eo - pm[0].rm_so), &string[pm[0].rm_so]);//,&string[pm[0].rm_so]);
#if MDEBUG3
		printf("------->> found \"%s\" length => %d offset[%d]\n",
				found->address, strlen(temp->address), offset);
#endif
		sreplace (temp->address + offset,found->address, rep, 0, INPUTLINE_BUFFER_REPLACE_SIZE - offset);
		for(i = 1; i < nmatch; i++){
			snprintf (ffound->address,INPUTLINE_BUFFER_REPLACE_SIZE, "%.*s",
					(int)(size_t)(pm[i].rm_eo - pm[i].rm_so), &string[pm[i].rm_so]);//,&string[pm[i].rm_so]);
			snprintf (field, sizeof(field), "\\%d", i);
			if(strlen (ffound->address)) {
				sreplace (temp->address, field, ffound->address, 1, INPUTLINE_BUFFER_REPLACE_SIZE);
			}else{
				sreplace (temp->address, field, "", 1, INPUTLINE_BUFFER_REPLACE_SIZE);
				continue;
			}
#if MDEBUG3
			printf (">> subfound %2d  '%s' => '%s' length %d\n",
					i,
					ffound->address,
					temp->address,offset);
#endif
		}
		// it is unsigned!	if(offset<0) offset=-offset;
		if (*string && strlen (string + pm[0].rm_eo)) {
			string += pm[0].rm_eo;
			status = r_regex_exec (re, string, nmatch, pm, 0);
		}else{
			status=-1;
		}
	}
#if MDEBUG2
	DBG ("mreplace(string,se,re)", "result : %s",t emp->address);
#endif
	res=strdup (temp->address);
	memFree (temp);
	memFree (search);
	memFree (found);
	memFree (ffound);
	r_regex_free (re);
	return res;
#ifdef _MSC_VER
#undef nmatch
#endif
}
Beispiel #4
0
R_API void r_cons_less_str(const char *str) {
	int lines_count;
	RRegex *rx = NULL;
	int w, h, ch, to, ui = 1, from = 0, i;
	const char *sreg;

	if(str == NULL || str[0] == '\0') return;
	char *p = strdup (str);
	int *lines = splitlines (p, &lines_count);

	RRegexMatch **ms = malloc(lines_count * sizeof(void *));
	for(i = 0; i < lines_count; i++)
		ms[i] = calloc(NMATCHES, sizeof(RRegexMatch));

	r_cons_set_raw (R_TRUE);
	r_cons_show_cursor (R_FALSE);
	r_cons_reset ();
	w = h = 0;
	while (ui) {
		w = r_cons_get_size (&h);
		to = R_MIN (lines_count, from+h);
		if (from+3>lines_count)
			from = lines_count-3;
		if (from<0) from = 0;
		printpage (p, lines, ms, from, to, w);
		ch = r_cons_readchar ();
		ch = r_cons_arrow_to_hjkl (ch);
		switch (ch) {
		case ' ': from += h; break;
		case 'g': from = 0; break;
		case 'G': from = lines_count-1-h; break;
		case -1: // EOF
		case 'q': ui = 0; break;
		case '\r':
		case '\n':
		case 'j': from++; break;
		case 'J': from+=h; break;
		case 'k': if (from>0) from--; break;
		case 'K': from = (from>=h)? from-h: 0;
			break;
		case '/': 	/* search */
			r_cons_reset_colors();
			r_line_set_prompt("/");
			sreg = r_line_readline();
			from = R_MIN(lines_count - 1, from);
			/* repeat last search if empty string is provided */
			if(sreg[0]){ /* prepare for a new search */
				if(rx) r_regex_free(rx);
				rx = r_regex_new(sreg, "");
			} else { /* we got an empty string */
				from = next_match(from, ms, lines_count);
				break;
			}
			if(!rx) break;
			/* find all occurences */
			if(all_matches(p, rx, ms, lines, lines_count))
				from = next_match(from, ms, lines_count);
			break;
		case 'n': 	/* next match */
			/* search already performed */
			if(rx) from = next_match(from, ms, lines_count);
			break;
		case 'p': 	/* previous match */
			if(rx) from = prev_match(from, ms);
			break;
		}
	}
	for(i = 0; i < lines_count; i++) free(ms[i]);
	free(ms);
	if(rx) r_regex_free(rx);
	free (lines);
	free (p);
	r_cons_reset_colors();
	r_cons_set_raw (R_FALSE);
	r_cons_show_cursor (R_TRUE);
}
Beispiel #5
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;
	RRegex* rx = NULL;
	char *tok, *tokens[1024], *code = NULL, *ptr;
	int idx, tidx = 0, ret, len;
	int tokcount, matchcount, count = 0;
	int matches = 0;

	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<(sizeof (tokens) / sizeof (char*)) - 1; tokcount++) {
		tok = strtok (tokcount? NULL: ptr, ";");
		if (tok == NULL)
			break;
		tokens[tokcount] = r_str_trim_head_tail (tok);
	}
	tokens[tokcount] = NULL;
	r_cons_break (NULL, NULL);
	for (at = from, matchcount = 0; at < to; at += core->blocksize-OPSZ) {
		matches = 0;
		if (r_cons_singleton ()->breaked)
			break;
		ret = r_io_read_at (core->io, at, buf, core->blocksize);
		if (ret != core->blocksize)
			break;
		idx = 0, matchcount = 0;
		while (idx<core->blocksize) {
			r_asm_set_pc (core->assembler, at+idx);
			op.buf_asm[0] = 0;
			op.buf_hex[0] = 0;
			if (!(len = r_asm_disassemble (core->assembler, &op, buf+idx, core->blocksize-idx))) {
				idx = (matchcount)? tidx+1: idx+1;
				matchcount = 0;
				continue;
			}
			if (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 (matches) {
				code = r_str_concatf (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 = at+tidx;
					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 == 0) {
					tidx = idx;
					matchcount++;
					idx += len;
				} else {
					matchcount++;
					idx += len;
				}
			} else {
				idx = matchcount? tidx+1: idx+1;
				R_FREE (code);
				matchcount = 0;
			}
		}
	}
	r_asm_set_pc (core->assembler, toff);
beach:
	free (buf);
	free (ptr);
	free (code);
	return hits;
}