r_list_foreach (bpargs, iter, var) { char *tmpf = NULL; if (var->delta < 10) { tmpf = "%d(%s)"; } else if (var->delta > 0) { tmpf = "0x%x(%s)"; } else { tmpf = "-0x%x(%s)"; } oldstr = r_str_newf (tmpf, r_num_abs (var->delta), anal->reg->name[R_REG_NAME_BP]); if (ucase) { char *comma = strchr (oldstr, ','); if (comma) { *comma = 0; r_str_case (oldstr, true); *comma = ','; } } if (strstr (tstr, oldstr)) { char *newstr = (p->localvar_only) ? r_str_newf ("(%s)", var->name): r_str_newf ("%s%s(%s)", var->delta > 0 ? "" : "-", var->name, anal->reg->name[R_REG_NAME_SP]); tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); }
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) { bool has_dol_extension = false; DolHeader * dol; char *lowername, *ext; if (!arch || sz < sizeof (DolHeader)) { return NULL; } dol = R_NEW0 (DolHeader); if (!dol) return NULL; lowername = strdup (arch->file); if (!lowername) { free (dol); return NULL; } r_str_case (lowername, 0); ext = strstr (lowername, ".dol"); if (ext && ext[4] == 0) { has_dol_extension = true; } free (lowername); if (has_dol_extension) { r_buf_fread_at (arch->buf, 0, (void*)dol, "67I", 1); //r_buf_fread_at (arch->buf, 0, (void*)dol, "67i", 1); if (arch && arch->o && arch->o->bin_obj) { arch->o->bin_obj = dol; } return (void*)dol; } free (dol); return NULL; }
bool test_r_str_case(void) { char* str1_mixedcase = strdup ("mIxEdCaSe"); char* str2_mixedcase = strdup ("mIxEdCaSe"); r_str_case (str1_mixedcase, true /*upcase*/); r_str_case (str2_mixedcase, false /*downcase*/); mu_assert_streq (str1_mixedcase, "MIXEDCASE", "upcase"); mu_assert_streq (str2_mixedcase, "mixedcase", "downcase"); char* non_alphanum_1 = strdup ("c00lstring!"); char* non_alphanum_2 = strdup ("c00lstrinG!"); r_str_case (non_alphanum_1, true /*upcase*/); r_str_case (non_alphanum_2, false /*downcase*/); mu_assert_streq (non_alphanum_1, "C00LSTRING!", "upcase, nonalpanum"); mu_assert_streq (non_alphanum_2, "c00lstring!", "downcase, nonalpanum"); free (str1_mixedcase); free (str2_mixedcase); free (non_alphanum_1); free (non_alphanum_2); mu_end; }
/* iterate over base pointer args/vars */ r_list_foreach (bpargs, bpargiter, bparg) { char sign = '+'; if (bparg->delta < 0) { sign = '-'; bparg->delta = -bparg->delta; } mk_reg_str (p->anal->reg->name[R_REG_NAME_BP], bparg->delta, sign=='+', att, ireg, oldstr, sizeof (oldstr)); if (ucase) { r_str_case (oldstr, true); } parse_localvar (p, newstr, sizeof (newstr), bparg->name, p->anal->reg->name[R_REG_NAME_BP], sign, ireg, att); if (ucase) { char *plus = strchr (newstr, sign); if (plus) { *plus = 0; r_str_case (newstr, true); *plus = sign; } else { r_str_case (newstr, true); } } char *ptr = strstr (tstr, oldstr); if (ptr && (!att || *(ptr - 1) == ' ')) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, false); ptr = strstr(tstr, oldstr); if (ptr && (!att || *(ptr - 1) == ' ')) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } // Try with no spaces snprintf (oldstr, sizeof (oldstr)-1, "[%s%c0x%x]", p->anal->reg->name[R_REG_NAME_BP], sign, bparg->delta); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } }
R_API int r_debug_signal_resolve(RDebug *dbg, const char *signame) { int ret; char *name; if (strchr (signame, '.')) return 0; name = strdup (signame); r_str_case (name, R_TRUE); if (strncmp (name, "SIG", 3)) name = r_str_prefix (name, "SIG"); ret = (int)sdb_num_get (DB, name, 0); free (name); return ret; }
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { cs_insn* insn; int mode, n, ret = -1; mode = CS_MODE_BIG_ENDIAN; if (!op) { return 0; } // mode |= (a->bits == 64)? CS_MODE_64: CS_MODE_32; memset (op, 0, sizeof (RAsmOp)); op->size = 4; if (cd != 0) { cs_close (&cd); } ret = cs_open (CS_ARCH_TMS320C64X, mode, &cd); if (ret) { goto fin; } if (a->syntax == R_ASM_SYNTAX_REGNUM) { cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME); } else { cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT); } cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF); n = cs_disasm (cd, (ut8*)buf, len, a->pc, 1, &insn); if (n < 1) { strcpy (op->buf_asm, "invalid"); op->size = 4; goto beach; } else { ret = 4; } if (insn->size < 1) { goto beach; } op->size = insn->size; snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s", insn->mnemonic, insn->op_str[0]? " ": "", insn->op_str); // r_str_replace_in (op->buf_asm, sizeof (op->buf_asm), "*+", "", 1); // nasty, the disasm output comes with tabs and uppercase :( r_str_replace_char (op->buf_asm, '\t', 0); // r_str_replace_in (op->buf_asm, sizeof (op->buf_asm), "\t", "", 1); r_str_case (op->buf_asm, false); cs_free (insn, n); beach: // cs_close (&cd); fin: return op->size; }
static bool varsub(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RAnalVar *var; RListIter *iter; char *oldstr; char *tstr = strdup (data); RAnal *anal = p->analb.anal; if (!p->varlist) { free (tstr); return false; } RList *bpargs = p->varlist (anal, f, 'b'); RList *spargs = p->varlist (anal, f, 's'); const bool ucase = IS_UPPER (*tstr); r_list_foreach (spargs, iter, var) { char *tmpf; //TODO: honor asm pseudo if (var->delta < 10) { tmpf = "%d(%s)"; } else if (var->delta > 0) { tmpf = "0x%x(%s)"; } else { tmpf = "-0x%x(%s)"; } oldstr = r_str_newf (tmpf, r_num_abs(var->delta), anal->reg->name[R_REG_NAME_SP]); if (ucase) { char *comma = strchr (oldstr, ','); if (comma) { *comma = 0; r_str_case (oldstr, true); *comma = ','; } } if (strstr (tstr, oldstr)) { char *newstr = (p->localvar_only) ? r_str_newf ("(%s)", var->name): r_str_newf ("%s%s(%s)", var->delta > 0 ? "" : "-", var->name, anal->reg->name[R_REG_NAME_SP]); tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); }
static int tms320c64x_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { cs_insn* insn; int n = -1, ret = -1; int mode = 0; if (op) { memset (op, 0, sizeof (RAsmOp)); op->size = 4; } if (cd != 0) { cs_close (&cd); } ret = cs_open (CS_ARCH_TMS320C64X, mode, &cd); if (ret) { goto fin; } cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF); if (!op) { return 0; } n = cs_disasm (cd, buf, len, a->pc, 1, &insn); if (n < 1) { r_asm_op_set_asm (op, "invalid"); op->size = 4; ret = -1; goto beach; } else { ret = 4; } if (insn->size < 1) { goto beach; } op->size = insn->size; char *buf_asm = sdb_fmt ("%s%s%s", insn->mnemonic, insn->op_str[0]? " ": "", insn->op_str); r_str_replace_char (buf_asm, '%', 0); r_str_case (buf_asm, false); r_asm_op_set_asm (op, buf_asm); cs_free (insn, n); beach: // cs_close (&cd); fin: return ret; }
R_API int r_cons_grep_line(char *buf, int len) { RCons *cons = r_cons_singleton (); const char *delims = " |,;=\t"; char *in, *out, *tok = NULL; int hit = cons->grep.neg; int outlen = 0; bool use_tok = false; size_t i; in = calloc (1, len + 1); if (!in) { return 0; } out = calloc (1, len + 2); if (!out) { free (in); return 0; } memcpy (in, buf, len); if (cons->grep.nstrings > 0) { int ampfail = cons->grep.amp; if (cons->grep.icase) { r_str_case (in, false); } for (i = 0; i < cons->grep.nstrings; i++) { char *str = cons->grep.strings[i]; if (cons->grep.icase) { r_str_case (str, false); } char *p = strstr (in, cons->grep.strings[i]); if (!p) { ampfail = 0; continue; } if (cons->grep.begin) { hit = (p == in)? 1: 0; } else { hit = !cons->grep.neg; } // TODO: optimize without strlen without breaking t/feat_grep (grep end) if (cons->grep.end && (strlen (cons->grep.strings[i]) != strlen (p))) { hit = 0; } if (!cons->grep.amp) { break; } } if (cons->grep.amp) { hit = ampfail; } } else { hit = 1; } if (hit) { if (!cons->grep.range_line) { if (cons->grep.line == cons->lines) { use_tok = true; } } else if (cons->grep.range_line == 1) { if (cons->grep.f_line == cons->lines) { use_tok = true; } if (cons->grep.l_line == cons->lines) { use_tok = false; } } else { use_tok = true; } if (use_tok && cons->grep.tokens_used) { for (i = 0; i < R_CONS_GREP_TOKENS; i++) { tok = strtok (i? NULL: in, delims); if (tok) { if (cons->grep.tokens[i]) { int toklen = strlen (tok); memcpy (out + outlen, tok, toklen); memcpy (out + outlen + toklen, " ", 2); outlen += toklen + 1; if (!(*out)) { free (in); free (out); return -1; } } } else { if (!(*out)) { free (in); free (out); return 0; } else { break; } } } outlen = outlen > 0? outlen - 1: 0; if (outlen > len) { // should never happen eprintf ("r_cons_grep_line: wtf, how you reach this?\n"); free (in); free (out); return -1; } memcpy (buf, out, len); len = outlen; } } else { len = 0; } free (in); free (out); if (cons->grep.sort != -1) { char ch = buf[len]; buf[len] = 0; if (!sorted_lines) { sorted_lines = r_list_newf (free); } if (!unsorted_lines) { unsorted_lines = r_list_newf (free); } if (cons->lines > cons->grep.sort_row) { r_list_append (sorted_lines, strdup (buf)); } else { r_list_append (unsorted_lines, strdup (buf)); } buf[len] = ch; } return len; }
static bool varsub(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RList *spargs, *bpargs, *regargs; RAnalVar *var; RListIter *iter; char *oldstr, *newstr; char *tstr = strdup (data); if (!tstr) { return false; } if (!p->varlist) { free (tstr); return false; } if (p->relsub) { char *rip = (char *)r_str_casestr (tstr, "[pc, "); if (rip) { rip += 4; char *tstr_new, *ripend = strchr (rip, ']'); const char *neg = strchr (rip, '-'); ut64 off = (oplen == 2 || strstr (tstr, ".w")) ? 4 : 8; ut64 repl_num = (addr + off) & ~3; if (!ripend) { ripend = "]"; } if (neg) { repl_num -= r_num_get (NULL, neg + 1); } else { repl_num += r_num_get (NULL, rip); } rip -= 3; *rip = 0; tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend); free (tstr); tstr = tstr_new; } } regargs = p->varlist (p->anal, f, 'r'); bpargs = p->varlist (p->anal, f, 'b'); spargs = p->varlist (p->anal, f, 's'); bool ucase = IS_UPPER (*tstr); r_list_foreach (bpargs, iter, var) { if (var->delta > -10 && var->delta < 10) { oldstr = r_str_newf ("[%s, %d]", p->anal->reg->name[R_REG_NAME_BP], var->delta); } else if (var->delta > 0) { oldstr = r_str_newf ("[%s, 0x%x]", p->anal->reg->name[R_REG_NAME_BP], var->delta); } else { oldstr = r_str_newf ("[%s, -0x%x]", p->anal->reg->name[R_REG_NAME_BP], -var->delta); } if (ucase) { char *comma = strchr (oldstr, ','); if (comma) { *comma = 0; r_str_case (oldstr, true); *comma = ','; } } if (strstr (tstr, oldstr)) { newstr = r_str_newf ("[%s %c %s]", p->anal->reg->name[R_REG_NAME_BP], var->delta > 0 ? '+' : '-', var->name); if (ucase) { char *comma = strchr (newstr, ' '); if (comma) { *comma = 0; r_str_case (newstr, true); *comma = ' '; } } tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); } r_list_foreach (spargs, iter, var) { if (var->delta > -10 && var->delta < 10) { oldstr = r_str_newf ("[sp, %d]", var->delta); } else if (var->delta > 0) { oldstr = r_str_newf ("[sp, 0x%x]", var->delta); } else { oldstr = r_str_newf ("[sp, -0x%x]", -var->delta); } if (strstr (tstr, oldstr)) { newstr = r_str_newf ("[sp %c %s]", var->delta > 0 ? '+' : '-', var->name); tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); if (var->delta > -10 && var->delta < 10) { oldstr = r_str_newf ("[%s, %d]", p->anal->reg->name[R_REG_NAME_SP], var->delta); } else if (var->delta > 0) { oldstr = r_str_newf ("[%s, 0x%x]", p->anal->reg->name[R_REG_NAME_SP], var->delta); } else { oldstr = r_str_newf ("[%s, -0x%x]", p->anal->reg->name[R_REG_NAME_SP], -var->delta); } if (strstr (tstr, oldstr)) { newstr = r_str_newf ("[%s %c %s]", p->anal->reg->name[R_REG_NAME_BP], var->delta > 0 ? '+' : '-', var->name); tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); } r_list_foreach (regargs, iter, var) { RRegItem *r = r_reg_index_get (p->anal->reg, var->delta); if (r && r->name && strstr (tstr, r->name)) { tstr = r_str_replace (tstr, r->name, var->name, 1); } }
static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RList *bpargs, *spargs; RAnalVar *bparg, *sparg; RListIter *bpargiter, *spiter; char oldstr[64], newstr[64]; char *tstr = strdup (data); if (!tstr) { return false; } bool att = strchr (data, '%'); if (p->relsub) { if (att) { char *rip = (char *) r_str_casestr (tstr, "(%rip)"); if (rip) { *rip = 0; char *pre = tstr; char *pos = rip + 6; char *word = rip; while (word > tstr && *word != ' ') { word--; } if (word > tstr) { *word++ = 0; *rip = 0; st64 n = r_num_math (NULL, word); ut64 repl_num = oplen + addr + n; char *tstr_new = r_str_newf ("%s 0x%08"PFMT64x"%s", pre, repl_num, pos); *rip = '('; free (tstr); tstr = tstr_new; } } } else { char *rip = (char *) r_str_casestr (tstr, "[rip"); if (rip) { char *ripend = strchr (rip + 3, ']'); const char *plus = strchr (rip, '+'); const char *neg = strchr (rip, '-'); char *tstr_new; ut64 repl_num = oplen + addr; if (!ripend) { ripend = "]"; } if (plus) { repl_num += r_num_get (NULL, plus + 1); } if (neg) { repl_num -= r_num_get (NULL, neg + 1); } rip[1] = '\0'; tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend); free (tstr); tstr = tstr_new; } } } if (!p->varlist) { free (tstr); return false; } bpargs = p->varlist (p->anal, f, 'b'); spargs = p->varlist (p->anal, f, 's'); /*iterate over stack pointer arguments/variables*/ bool ucase = *tstr >= 'A' && *tstr <= 'Z'; if (ucase && tstr[1]) { ucase = tstr[1] >= 'A' && tstr[1] <= 'Z'; } char *ireg = NULL; if (p->get_op_ireg) { ireg = p->get_op_ireg(p->user, addr); } r_list_foreach (spargs, spiter, sparg) { // assuming delta always positive? mk_reg_str (p->anal->reg->name[R_REG_NAME_SP], sparg->delta, true, att, ireg, oldstr, sizeof (oldstr)); if (ucase) { r_str_case (oldstr, true); } parse_localvar (p, newstr, sizeof (newstr), sparg->name, p->anal->reg->name[R_REG_NAME_SP], '+', ireg, att); if (ucase) { char *plus = strchr (newstr, '+'); if (plus) { *plus = 0; r_str_case (newstr, true); *plus = '+'; } else { r_str_case (newstr, true); } } char *ptr = strstr(tstr, oldstr); if (ptr && (!att || *(ptr - 1) == ' ')) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, false); ptr = strstr(tstr, oldstr); if (ptr && (!att || *(ptr - 1) == ' ')) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } }
static bool varsub(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RAnalVar *var, *arg, *sparg; RListIter *variter, *argiter, *spiter; char oldstr[64], newstr[64]; char *tstr = strdup (data); RList *vars, *args, *spargs; if (!p->varlist) { free (tstr); return false; } vars = p->varlist (p->anal, f, 'v'); args = p->varlist (p->anal, f, 'a'); spargs = p->varlist (p->anal, f, 'e'); /*iterate over stack pointer arguments/variables*/ r_list_foreach (spargs, spiter,sparg) { if (sparg->delta < 10) { snprintf (oldstr, sizeof (oldstr)-1, "[%s + %d]", p->anal->reg->name[R_REG_NAME_SP], sparg->delta); } else { snprintf (oldstr, sizeof (oldstr)-1, "[%s + 0x%x]", p->anal->reg->name[R_REG_NAME_SP], sparg->delta); } snprintf (newstr, sizeof (newstr)-1, "[%s + %s]", p->anal->reg->name[R_REG_NAME_SP], sparg->name); if (strstr (tstr, oldstr)) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, false); if (strstr (tstr, oldstr)) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } } /* iterate over arguments */ r_list_foreach (args, argiter, arg) { if (arg->delta < 10) snprintf (oldstr, sizeof (oldstr)-1, "[%s + %d]", p->anal->reg->name[R_REG_NAME_BP], arg->delta); else snprintf (oldstr, sizeof (oldstr)-1, "[%s + 0x%x]", p->anal->reg->name[R_REG_NAME_BP], arg->delta); snprintf (newstr, sizeof (newstr)-1, "[%s + %s]", p->anal->reg->name[R_REG_NAME_BP], arg->name); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, false); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } // Try with no spaces snprintf (oldstr, sizeof (oldstr)-1, "[%s+0x%x]", p->anal->reg->name[R_REG_NAME_BP], arg->delta); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } char bp[32]; if (p->anal->reg->name[R_REG_NAME_BP]) { strncpy (bp, p->anal->reg->name[R_REG_NAME_BP], sizeof (bp) -1); if (isupper (*str)) { r_str_case (bp, true); } bp[sizeof(bp) - 1] = 0; } else { bp[0] = 0; } r_list_foreach (vars, variter, var) { if (var->delta < 10) snprintf (oldstr, sizeof (oldstr)-1, "[%s - %d]", bp, var->delta); else snprintf (oldstr, sizeof (oldstr)-1, "[%s - 0x%x]", bp, var->delta); snprintf (newstr, sizeof (newstr)-1, "[%s - %s]", bp, var->name); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, true); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } // Try with no spaces snprintf (oldstr, sizeof (oldstr)-1, "[%s - 0x%x]", p->anal->reg->name[R_REG_NAME_BP], var->delta); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } bool ret = true; if (len > strlen (tstr)) { strncpy (str, tstr, strlen (tstr)); str[strlen (tstr)] = 0; } else { // TOO BIG STRING CANNOT REPLACE HERE ret = false; } free (tstr); r_list_free (vars); r_list_free (args); return ret; }
static bool varsub(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RList *spargs = NULL; RList *bpargs = NULL; RAnalVar *var; RListIter *iter; char *oldstr, *newstr; char *tstr = strdup (data); if (!tstr) { return false; } if (!p->varlist) { free (tstr); return false; } if (p->relsub) { char *rip = (char *)r_str_casestr (tstr, "[pc, "); if (!rip) { rip = (char *)r_str_casestr (tstr, "[PC, "); } if (rip && !strchr (rip + 4, ',')) { rip += 4; char *tstr_new, *ripend = strchr (rip, ']'); const char *neg = strchr (rip, '-'); ut64 off = (oplen == 2 || strstr (tstr, ".w") || strstr(tstr, ".W")) ? 4 : 8; ut64 repl_num = (addr + off) & ~3; if (!ripend) { ripend = "]"; } if (neg) { repl_num -= r_num_get (NULL, neg + 1); } else { repl_num += r_num_get (NULL, rip); } rip -= 3; *rip = 0; tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend); free (tstr); tstr = tstr_new; } } bpargs = p->varlist (p->anal, f, 'b'); spargs = p->varlist (p->anal, f, 's'); bool ucase = IS_UPPER (*tstr); r_list_foreach (bpargs, iter, var) { char *reg = p->anal->reg->name[R_REG_NAME_BP]; char *tmplt = NULL; if (var->delta > -10 && var->delta < 10) { if (p->pseudo) { char sign = '+'; int delta = var->delta; if (var->delta < 0) { sign = '-'; delta = -delta; } oldstr = r_str_newf ("[%s %c %d]", reg, sign, delta); } else { oldstr = r_str_newf ("[%s, %d]", reg, var->delta); } } else if (var->delta > 0) { tmplt = p->pseudo ? "[%s + 0x%x]" : (ucase ? "[%s, 0x%X]" : "[%s, 0x%x]"); oldstr = r_str_newf (tmplt, reg, var->delta); } else { tmplt = p->pseudo ? "[%s - 0x%x]" : (ucase ? "[%s, -0x%X]" : "[%s, -0x%x]"); oldstr = r_str_newf (tmplt, reg, -var->delta); } if (ucase) { char *comma = strchr (oldstr, ','); if (comma) { *comma = 0; r_str_case (oldstr, true); *comma = ','; } } if (strstr (tstr, oldstr)) { if (p->localvar_only) { newstr = r_str_newf ("[%s]", var->name); } else { newstr = r_str_newf ("[%s %c %s]", reg, var->delta > 0 ? '+' : '-', var->name); } if (ucase) { char *comma = strchr (newstr, ' '); if (comma) { *comma = 0; r_str_case (newstr, true); *comma = ' '; } } tstr = r_str_replace (tstr, oldstr, newstr, 1); free (newstr); free (oldstr); break; } free (oldstr); }
static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { RAnalVar *reg, *bparg, *sparg; RListIter *regiter, *bpargiter, *spiter; char oldstr[64], newstr[64]; char *tstr = strdup (data); if (!tstr) return false; RList *regs, *bpargs, *spargs; if (p->relsub) { char *rip = strstr (tstr, "[rip"); if (rip) { char *ripend = strchr (rip + 3, ']'); const char *plus = strchr (rip, '+'); const char *neg = strchr (rip, '-'); char *tstr_new; ut64 repl_num = oplen + addr; if (!ripend) ripend = "]"; if (plus) repl_num += r_num_get (NULL, plus + 1); if (neg) repl_num -= r_num_get (NULL, neg + 1); rip[1] = '\0'; tstr_new = r_str_newf ("%s0x%08"PFMT64x"%s", tstr, repl_num, ripend); free (tstr); tstr = tstr_new; if (!strncmp (tstr, "lea", 3)) { r_str_replace_char (tstr, '[', 0); r_str_replace_char (tstr, ']', 0); } } } if (!p->varlist) { free (tstr); return false; } regs = p->varlist (p->anal, f, 'v'); bpargs = p->varlist (p->anal, f, 'a'); spargs = p->varlist (p->anal, f, 'e'); /*iterate over stack pointer arguments/variables*/ r_list_foreach (spargs, spiter,sparg) { if (sparg->delta < 10) { snprintf (oldstr, sizeof (oldstr)-1, "[%s + %d]", p->anal->reg->name[R_REG_NAME_SP], sparg->delta); } else { snprintf (oldstr, sizeof (oldstr)-1, "[%s + 0x%x]", p->anal->reg->name[R_REG_NAME_SP], sparg->delta); } snprintf (newstr, sizeof (newstr)-1, "[%s + %s]", p->anal->reg->name[R_REG_NAME_SP], sparg->name); if (strstr (tstr, oldstr)) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, false); if (strstr (tstr, oldstr)) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } } /* iterate over base pointer args/vars */ r_list_foreach (bpargs, bpargiter, bparg) { char sign = '+'; if (bparg->delta < 0) { sign = '-'; bparg->delta = -bparg->delta; } if (bparg->delta < 10) snprintf (oldstr, sizeof (oldstr)-1, "[%s %c %d]", p->anal->reg->name[R_REG_NAME_BP], sign, bparg->delta); else snprintf (oldstr, sizeof (oldstr)-1, "[%s %c 0x%x]", p->anal->reg->name[R_REG_NAME_BP], sign, bparg->delta); snprintf (newstr, sizeof (newstr)-1, "[%s %c %s]", p->anal->reg->name[R_REG_NAME_BP], sign, bparg->name); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } else { r_str_case (oldstr, false); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } } // Try with no spaces snprintf (oldstr, sizeof (oldstr)-1, "[%s%c0x%x]", p->anal->reg->name[R_REG_NAME_BP], sign, bparg->delta); if (strstr (tstr, oldstr) != NULL) { tstr = r_str_replace (tstr, oldstr, newstr, 1); break; } }