static int show_syscall(RDebug *dbg, const char *sysreg) { const char *sysname; char regname[8]; int reg, i, args; RSyscallItem *si; reg = (int)r_debug_reg_get (dbg, sysreg); si = r_syscall_get (dbg->anal->syscall, reg, -1); if (si) { sysname = si->name? si->name: "unknown"; args = si->args; } else { sysname = "unknown"; args = 3; } eprintf ("--> %s 0x%08"PFMT64x" syscall %d %s (", sysreg, r_debug_reg_get (dbg, "pc"), reg, sysname); for (i=0; i<args; i++) { ut64 val; snprintf (regname, sizeof (regname)-1, "a%d", i); val = r_debug_reg_get (dbg, regname); if (((st64)val<0) && ((st64)val>-0xffff)) { eprintf ("%"PFMT64d"%s", val, (i+1==args)?"":" "); } else { eprintf ("0x%"PFMT64x"%s", val, (i+1==args)?"":" "); } } eprintf (")\n"); r_syscall_item_free (si); return reg; }
// XXX: RVM must be inside RAnal ???? imho no. rsyscall must provide ret reg info //XXX: may overflow. this is vulnerable. needs fix R_API char *r_anal_cc_to_string (RAnal *anal, RAnalCC* cc) { RSyscallItem *si; RAnalFunction *fcn; char str[1024], buf[64]; int i, eax = 0; // eax = arg0 int str_len = 0; int buf_len = 0; str[0] = 0; switch (cc->type) { case R_ANAL_CC_TYPE_FASTCALL: // INT { RRegItem *item; const char *a0 = r_reg_get_name (anal->reg, R_REG_NAME_A0); // A0 or RET ?? item = r_reg_get (anal->reg, a0, R_REG_TYPE_GPR); if (!item) { //eprintf ("cannot get reg a0\n"); return R_FALSE; } eax = (int)r_reg_get_value (anal->reg, item); si = r_syscall_get (anal->syscall, eax, (int)cc->jump); if (si) { //DEBUG r_cons_printf (" ; sc[0x%x][%d]=%s(", (int)analop.value, eax, si->name); snprintf (str, sizeof (str), "%s (", si->name); for (i=0; i<si->args; i++) { const char *reg = r_syscall_reg (anal->syscall, i+1, si->args); if (!reg) break; // no registers? item = r_reg_get (anal->reg, reg, R_REG_TYPE_GPR); if (item) { snprintf (buf, sizeof (buf), "0x%"PFMT64x, r_reg_get_value (anal->reg, item)); strcat (str, buf); // XXX: do not use strcat } //else eprintf ("Unknown reg '%s'\n", reg); if (i<si->args-1) strcat (str, ","); // XXX: do not use strcat } strcat (str, ")"); } else { int n = (int)cc->jump; //if (n == 3) return NULL; // XXX: hack for x86 snprintf (str, sizeof (str), "syscall[0x%x][%d]=?", n, eax); } } break; case R_ANAL_CC_TYPE_STDCALL: // CALL fcn = r_anal_fcn_find (anal, cc->jump, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_IMP); if (fcn && fcn->name) snprintf (str, sizeof (str), "%s(", fcn->name); else if (cc->jump != -1LL) snprintf (str, sizeof (str), "0x%08"PFMT64x"(", cc->jump); else strncpy (str, "unk(", sizeof (str)-1); str_len = strlen (str); if (fcn) cc->nargs = (fcn->nargs>cc->nargs?fcn->nargs:cc->nargs); if (cc->nargs>8) { //eprintf ("too many arguments for stdcall. chop to 8\n"); cc->nargs = 8; } // TODO: optimize string concat for (i=0; i<cc->nargs; i++) { if (cc->args[cc->nargs-i] != -1LL) snprintf (buf, sizeof (buf), "0x%"PFMT64x, cc->args[cc->nargs-i]); else strncpy (buf, "unk", sizeof (buf)-1); buf_len = strlen (buf); if ((buf_len+str_len+5)>=sizeof (str)) { strcat (str, "..."); break; } strcat (str, buf); str_len += buf_len; if (i<cc->nargs-1) strcat (str, ", "); } strcat (str, ")"); break; } return strdup (str); }