R_API int r_name_filter(char *name, int maxlen) { int i; char *oname; name = oname = r_str_trim_head_tail (name); for (i=0; *name!='\0'; name++, i++) { if (maxlen && i>maxlen) { *name = '\0'; break; } if (!r_name_validate_char (*name)) { *name = '_'; //r_str_ccpy (name, name+1, 0); //name--; } } return r_name_check (oname); }
static int exprmatchreg (RDebug *dbg, const char *regname, const char *expr) { int ret = 0; char *p; char *s = strdup (expr); if (!s) { return 0; } if (!strcmp (regname, s)) { ret = 1; } else { #define CURVAL 0){}r_str_trim_head_tail (s);if (!strcmp(regname,s) && regval ut64 regval = r_debug_reg_get_err (dbg, regname, NULL, NULL); if (exprtoken (dbg, s, ">=", &p)) { if (CURVAL >= r_num_math (dbg->num, p)) ret = 1; } else if (exprtoken (dbg, s, "<=", &p)) { if (CURVAL <= r_num_math (dbg->num, p)) ret = 1; } else if (exprtoken (dbg, s, "==", &p)) { if (CURVAL <= r_num_math (dbg->num, p)) ret = 1; } else if (exprtoken (dbg, s, "<", &p)) { if (CURVAL < r_num_math (dbg->num, p)) ret = 1; } else if (exprtoken (dbg, s, ">", &p)) { if (CURVAL > r_num_math (dbg->num, p)) ret = 1; } else if (exprtoken (dbg, s, " ", &p)) { r_str_trim_head_tail (s); if (!strcmp (regname, s)) { ut64 num = r_num_math (dbg->num, p); ret = exprmatch (dbg, num, s); } } else { if (!strcmp (regname, s)) { ret = 1; } } } free (s); return ret; }
R_API char *r_cons_pal_parse(const char *str) { int i; ut8 r, g, b; char out[128]; char *s = r_str_trim_head_tail (strdup (str)); r_str_split (s, ' '); int length = strlen (s); out[0] = 0; if (!strcmp (str, "random")) { free (s); return r_cons_color_random (0); } if (!strncmp (s, "rgb:", 4)) { int correct = 0; if (length == 7) { r = rgbnum (s[4],s[4]); g = rgbnum (s[5],s[5]); b = rgbnum (s[6],s[6]); correct = 1; } else if (length == 10) { r = rgbnum(s[4],s[5]); g = rgbnum(s[6],s[7]); b = rgbnum(s[8],s[9]); correct = 1; } if (correct) { r_cons_rgb_str (out, r, g, b, 0); } else { eprintf ("Invalid rgb string (%s)\n", str); } } for (i=0; colors[i].name; i++) { if (!strcmp (s, colors[i].name)) strcat (out, colors[i].code); } free (s); return *out? strdup (out): NULL; }
// 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; }
// 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; }
// 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; }