static char *r_socket_http_answer (RSocket *s, int *code, int *rlen) { const char *p; int ret, olen, len = 0, bufsz = 32768, delta = 0; char *dn, *res, *buf = malloc (bufsz + 32); // XXX: use r_buffer here if (!buf) return NULL; r_socket_block_time (s, 1, 5); res = NULL; olen = r_socket_read_block (s, (unsigned char*) buf, bufsz); if (olen < 1) goto fail; buf[olen] = 0; if ((dn = (char*)r_str_casestr (buf, "\n\n"))) { delta += 2; } else if ((dn = (char*)r_str_casestr (buf, "\r\n\r\n"))) { delta += 4; } else goto fail; olen -= delta; *dn = 0; // chop headers /* Parse Len */ p = r_str_casestr (buf, "Content-Length: "); if (p) len = atoi (p+16); else len = olen - (dn - buf); if (len >0) { if (len > olen) { res = malloc (len+2); memcpy (res, dn+delta, olen); do { ret = r_socket_read_block (s, (ut8*) res+olen, len-olen); if (ret < 1) break; olen += ret; } while (olen<len); res[len] = 0; } else { res = malloc (len+1); if (res) { memcpy (res, dn+delta, len); res[len] = 0; } } } else res = NULL; fail: free (buf); // is 's' free'd? isnt this going to cause a double free? r_socket_close (s); if (rlen) *rlen = len; return res; }
static char *strmatch (char *pos, char *buf) { char *p, *os = buf; for (p = buf; *p; p++) { if (*p==' ') { *p = 0; if (!r_str_casestr (pos, os)) { //r_cons_printf ("FAIL ((%s), %s)\n", pos, os); *p = ' '; return NULL; } //r_cons_printf ("CHK (%s)\n", os); *p = ' '; os = p+1; } } return (char *)r_str_casestr (pos, os); }
/* Match a filter on a line. A filter can contain multiple words separated by spaces, which are all matched *in any order* over the target entry. If all words are present, the function returns true. The mask is a character buffer wich is filled by 'x' to mark those characters that match the filter */ static bool strmatch(char *entry, char *filter, char* mask, const int mask_size) { char *p, *current_token = filter; const char *filter_end = filter + strlen (filter); // first we separate the filter in words (include the terminator char // to avoid special handling of the last token) for (p = filter; p <= filter_end; p++) { if (*p == ' ' || *p == '\0') { const char *next_match, *entry_ptr = entry; char old_char = *p; int token_len; // Ignoring consecutive spaces if (p == current_token) { current_token++; continue; } *p = 0; token_len = strlen (current_token); // look for all matches of the current_token in this entry while ((next_match = r_str_casestr (entry_ptr, current_token))) { int i; for (i = next_match - entry; (i < next_match - entry + token_len) && i < mask_size; i++) { mask[i] = 'x'; } entry_ptr += token_len; } *p = old_char; if (entry_ptr == entry) { // the word is not present in the target return false; } current_token = p + 1; } } return true; }
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) { 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); }