R_API void r_vlog(const char *funcname, const char *filename, ut32 lineno, RLogLevel level, const char *tag, const char *fmtstr, va_list args) { va_list args_copy; va_copy (args_copy, args); if (level < cfg_loglvl && level < cfg_logtraplvl) { // Don't print if output level is lower than current level // Don't ignore fatal/trap errors va_end (args_copy); return; } // TODO: Colors // Build output string with src info, and formatted output char output_buf[LOG_OUTPUTBUF_SIZE] = ""; // Big buffer for building the output string if (!tag) { tag = R_BETWEEN (0, level, R_ARRAY_SIZE (level_tags) - 1)? level_tags[level]: ""; } int offset = snprintf (output_buf, LOG_OUTPUTBUF_SIZE, "%s: ", tag); if (cfg_logsrcinfo) { offset += snprintf (output_buf + offset, LOG_OUTPUTBUF_SIZE - offset, "%s in %s:%i: ", funcname, filename, lineno); } vsnprintf (output_buf + offset, LOG_OUTPUTBUF_SIZE - offset, fmtstr, args); // Actually print out the string with our callbacks if (log_cbs && r_list_length (log_cbs) > 0) { RListIter *it; RLogCallback cb; r_list_foreach (log_cbs, it, cb) { cb (output_buf, funcname, filename, lineno, level, NULL, fmtstr, args_copy); }
bool test_r_list_sort4(void) { RList* list = r_list_new (); char* test1 = "AAAA"; char* test2 = "BBBB"; char* test3 = "CCCC"; char* test4 = "DDDD"; char* test5 = "EEEE"; char* test6_later = "FFFF"; char* test7 = "GGGG"; char* test8 = "HHHH"; char* test9 = "IIII"; char* test10 = "JJJJ"; char* ins_tests_odd[] = {test10, test1, test3, test7, test5, test9, test2, test4, test8}; char* exp_tests_odd[] = {test1, test2, test3, test4, test5, test7, test8, test9, test10}; int i; // Put in not sorted order. for (i = 0; i < R_ARRAY_SIZE (ins_tests_odd); ++i) { r_list_append (list, (void*)ins_tests_odd[i]); } // Sort. r_list_merge_sort (list, (RListComparator)strcmp); // Check that the list (odd-length) is actually sorted. RListIter *next = list->head; for (i = 0; i < R_ARRAY_SIZE (exp_tests_odd); ++i) { char buf[BUF_LENGTH]; snprintf(buf, BUF_LENGTH, "%d-th value in sorted list", i); mu_assert_streq ((char*)next->data, exp_tests_odd[i], buf); next = next->n; } #if 0 // Debug Print char *data; printf("after sorted 1 \n"); r_list_foreach (list, next, data) { printf("l -> %s\n", data); }
// Returns the permissions as in integer given an input in the form of rwx, rx, // etc. R_API int r_str_rwx(const char *str) { int ret = atoi (str); if (!ret) { ret |= strchr (str, 'm') ? 16 : 0; ret |= strchr (str, 'r') ? 4 : 0; ret |= strchr (str, 'w') ? 2 : 0; ret |= strchr (str, 'x') ? 1 : 0; } else if (ret < 0 || ret >= R_ARRAY_SIZE (rwxstr)) { ret = 0; } return ret; }
static char *getrandomline(RCore *core) { int i, lines = 0; const char *types = (char *)r_config_get (core->config, "cfg.fortunes.type"); char *line = NULL, *templine; for (i = 0; i < R_ARRAY_SIZE (fortunes); i++) { if (strstr (types, fortunes[i])) { char *file = getFortuneFile(core, fortunes[i]); templine = r_file_slurp_random_line_count (file, &lines); if (templine && *templine) { free (line); line = templine; } free (file); } } return line; }
R_API void r_core_fortune_list(RCore *core) { // TODO: use file.fortunes // can be dangerous in sandbox mode const char *types = (char *)r_config_get (core->config, "cfg.fortunes.type"); int i, j; for (i = 0; i < R_ARRAY_SIZE (fortunes); i++) { if (strstr (types, fortunes[i])) { char *file = getFortuneFile(core, fortunes[i]); char *str = r_file_slurp (file, NULL); for (j = 0; str[j]; j++) { if (str[j] == '\n') { if (i < j) { str[j] = '\0'; r_cons_printf ("%s\n", str + i); } i = j + 1; } } free (str); free (file); } } }
// 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; }
R_API void r_core_fortune_list_types(void) { int i; for (i = 0; i < R_ARRAY_SIZE (fortunes); i++) { r_cons_printf ("%s\n", fortunes[i]); } }
// Returns the string representation of the permission of the inputted integer. R_API const char *r_str_rwx_i(int rwx) { if (rwx < 0 || rwx >= R_ARRAY_SIZE (rwxstr)) { rwx = 0; } return rwxstr[rwx % 24]; // 15 for srwx }
// 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; }