コード例 #1
0
ファイル: asm.c プロジェクト: DePierre/radare2
// 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) {
	RCoreAsmHit *hit;
	RAsmOp op;
	RList *hits;
	ut64 at, toff = core->offset;
	ut8 *buf;
	char *tok, *tokens[1024], *code = NULL, *ptr;
	int idx, tidx = 0, ret, len;
	int tokcount, matchcount;

	if (!*input)
		return NULL;
	if (core->blocksize<=OPSZ) {
		eprintf ("error: block size too small\n");
		return NULL;
	}
	if (!(buf = (ut8 *)malloc (core->blocksize)))
		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) {
		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] && strstr (op.buf_asm, tokens[matchcount])) {
				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;
					}
					hit->code = strdup (code);
					r_list_append (hits, hit);
					R_FREE (code);
					matchcount = 0;
					idx = tidx+1;
				} 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;
}
コード例 #2
0
ファイル: asm.c プロジェクト: ghostbar/radare2.deb
// 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, 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)
			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) {
			ut64 addr = at + idx;
			r_asm_set_pc (core->assembler, addr);
			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;
			}
			matches = true;
			if (!strcmp (op.buf_asm, "unaligned"))
				matches = false;
			if (!strcmp (op.buf_asm, "invalid"))
				matches = false;
			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_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 = 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 == 0) {
					tidx = idx;
					matchcount++;
					idx += len;
				} else {
					matchcount++;
					idx += len;
				}
			} else {
				idx = matchcount? tidx+1: idx+1;
				R_FREE (code);
				matchcount = 0;
			}
		}

		at += OPSZ;
	}
	r_asm_set_pc (core->assembler, toff);
beach:
	free (buf);
	free (ptr);
	free (code);
	return hits;
}
コード例 #3
0
ファイル: casm.c プロジェクト: rlaemmert/radare2
// 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;
}