From b829244c19b577a00c68ef866a0fb319de3f4fd4 Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 10 Jun 2016 19:09:13 +0200 Subject: [PATCH] Fixes for thumb/arm string references and endian refptr --- libr/anal/p/anal_arm_cs.c | 92 +++++++++++++++++---------------------- libr/core/bin.c | 3 +- libr/core/disasm.c | 71 ++++++++++++++++++++++-------- libr/core/visual.c | 3 +- 4 files changed, 96 insertions(+), 73 deletions(-) diff --git a/libr/anal/p/anal_arm_cs.c b/libr/anal/p/anal_arm_cs.c index b1bbdcc461..00a7857582 100644 --- a/libr/anal/p/anal_arm_cs.c +++ b/libr/anal/p/anal_arm_cs.c @@ -498,11 +498,12 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l return 0; } -static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) { +static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn, bool thumb) { bool hascond = false; int i; char str[32][32]; int msr_flags; + int pcdelta = (thumb ? 4 : 8 ) - op->size; r_strbuf_init (&op->esil); r_strbuf_set (&op->esil, ""); switch (insn->detail->arm.cc) { @@ -678,22 +679,18 @@ r4,r5,r6,3,sp,[*],12,sp,+= case ARM_INS_SADD16: case ARM_INS_SADD8: case ARM_INS_ADD: - if (strcmp (ARG(2), "")) { + if (!strcmp (ARG(2), "")) { if (!strcmp (ARG(1), "pc")) { - // that 2>>2<< is for & 0xfffffffc - // (the address of the current instruction + 4) AND &FFFFFFFC. - // to clear 2 lower bits - int delta = 4; - if (a->bits == 32) { - delta = 8; + int delta = thumb ? 4 : 8; + if (thumb) { + delta -= op->size; + if (!(addr & 2)) + delta += 2; } r_strbuf_appendf (&op->esil, - "%d,%"PFMT64d",+,%s,+=", delta, op->addr, ARG(0)); - //"2,2,4,%s,+,>>,<<,%s,+=", ARG(1), ARG(0)); - //"2,2,4,%"PFMT64d",+,>>,<<,%s,+=", op->addr, ARG(0)); - //"4,%s,+,0xfffffffc,&,%s,+=", ARG(1), ARG(0)); + "%d,2,2,%s,>>,<<,+,%s,+=", + delta, ARG(1), ARG(0)); } else { - // THUMB if (!strcmp (ARG(0), ARG(1))) { r_strbuf_appendf (&op->esil, "2,%s,*=", ARG(0)); } else { @@ -701,12 +698,17 @@ r4,r5,r6,3,sp,[*],12,sp,+= } } } else { - if (!strcmp (ARG(0),ARG(1))) { - r_strbuf_appendf (&op->esil, "%s,%s,+=", ARG(2), ARG(0)); - } else if (!strcmp (ARG(2),"0")) { - r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), ARG(0)); + if (!strcmp (ARG(1), "pc")) { + int delta = 4; //thumb ? 4 : 8; + r_strbuf_appendf (&op->esil, "%d,%s,+,%s,+,%s,=", delta, ARG(2), ARG(1), ARG(0)); } else { - r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=", ARG(2), ARG(1), ARG(0)); + if (!strcmp (ARG(0), ARG(1))) { + r_strbuf_appendf (&op->esil, "%s,%s,+=", ARG(2), ARG(0)); + } else if (!strcmp (ARG(2),"0")) { + r_strbuf_appendf (&op->esil, "%s,%s,=", ARG(1), ARG(0)); + } else { + r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=", ARG(2), ARG(1), ARG(0)); + } } } break; @@ -743,46 +745,31 @@ r4,r5,r6,3,sp,[*],12,sp,+= case ARM_INS_LDREXH: case ARM_INS_LDR: addr &= ~3LL; - if (MEMDISP(1)<0) { + if (MEMDISP(1) < 0) { if (REGBASE(1) == ARM_REG_PC) { op->refptr = 4; - op->ptr = addr + op->size - MEMDISP(1); + op->ptr = addr + pcdelta - MEMDISP(1); r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=", - MEMBASE(1), MEMDISP(1), REG(0)); + "$$", MEMDISP(1), REG(0)); } else { r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=", - MEMBASE(1), +MEMDISP(1), REG(0)); + MEMBASE(1), MEMDISP(1), REG(0)); } } else { if (REGBASE(1) == ARM_REG_PC) { - int pcdelta = 8; - switch (a->bits) { - case 16: - pcdelta = 4; // op->size * 2; - op->refptr = 4; - op->ptr = addr + pcdelta + MEMDISP(1); - pcdelta = 0; // not needed for esil - break; - case 32: - pcdelta = 4; - if (ISREG(1)) { - // cant resolve register values magically - } else { - op->ptr = addr + 8 + MEMDISP(1); - op->refptr = 4; - } - break; - } + const char *pc = "$$"; //MEMBASE(1); + op->refptr = 4; + op->ptr = addr + pcdelta + MEMDISP(1); if (ISMEM(1) && LSHIFT2(1)) { - r_strbuf_appendf (&op->esil, "%d,%s,+,%d,%s,<<,+,[4],%s,=", - pcdelta, MEMBASE(1), LSHIFT2(1), MEMINDEX(1), REG(0)); + r_strbuf_appendf (&op->esil, "2,2,%d,%s,+,>>,<<,%d,%s,<<,+,[4],%s,=", + pcdelta, pc, LSHIFT2(1), MEMINDEX(1), REG(0)); } else { if (ISREG(1)) { - r_strbuf_appendf (&op->esil, "%d,%s,+,%s,+,[4],%s,=", - pcdelta, MEMBASE(1), MEMINDEX(1), REG(0)); + r_strbuf_appendf (&op->esil, "2,2,%d,%s,+,>>,<<,%s,+,[4],%s,=", + pcdelta, pc, MEMINDEX(1), REG(0)); } else { - r_strbuf_appendf (&op->esil, "%d,%s,+,%d,+,[4],%s,=", - pcdelta, MEMBASE(1), MEMDISP(1), REG(0)); + r_strbuf_appendf (&op->esil, "2,2,%d,%s,+,>>,<<,%d,+,[4],%s,=", + pcdelta, pc, MEMDISP(1), REG(0)); } } } else { @@ -799,7 +786,6 @@ r4,r5,r6,3,sp,[*],12,sp,+= } } } - op->refptr = 4; } break; case ARM_INS_MSR: @@ -1034,7 +1020,7 @@ static int cond_cs2r2(int cc) { return cc; } -static void anop32 (RAnalOp *op, cs_insn *insn) { +static void anop32 (RAnalOp *op, cs_insn *insn, bool thumb) { const ut64 addr = op->addr; int i; op->cond = cond_cs2r2 (insn->detail->arm.cc); @@ -1098,8 +1084,9 @@ jmp $$ + 4 + ( [delta] * 2 ) case ARM_INS_ADD: op->type = R_ANAL_OP_TYPE_ADD; if (REGID(1) == ARM_REG_PC) { - op->ptr = addr + 8 + IMM(2); - op->refptr = 0; + op->ptr = (addr & ~3) + (thumb ? 4 : 8) + IMM(2); +//if (addr & 2) { op->ptr += 2; } + op->refptr = 4; } break; case ARM_INS_VMOV: @@ -1298,6 +1285,7 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { if (n<1) { op->type = R_ANAL_OP_TYPE_ILL; } else { + bool thumb = cs_insn_group (handle, insn, ARM_GRP_THUMB); op->size = insn->size; if (a->bits == 64) { anop64 (op, insn); @@ -1305,9 +1293,9 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { analop64_esil (a, op, addr, buf, len, &handle, insn); } } else { - anop32 (op, insn); + anop32 (op, insn, thumb); if (a->decode) { - analop_esil (a, op, addr, buf, len, &handle, insn); + analop_esil (a, op, addr, buf, len, &handle, insn, thumb); } } cs_free (insn, n); diff --git a/libr/core/bin.c b/libr/core/bin.c index ed2590864c..0420364182 100644 --- a/libr/core/bin.c +++ b/libr/core/bin.c @@ -314,8 +314,9 @@ static int bin_strings(RCore *r, int mode, int va) { r_list_foreach (list, iter, string) { const char *section_name, *type_string; ut64 paddr, vaddr, addr; - if (!string_filter (r, string->string)) + if (!string_filter (r, string->string)) { continue; + } paddr = string->paddr; vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr); addr = va ? vaddr : paddr; diff --git a/libr/core/disasm.c b/libr/core/disasm.c index 04f69eedec..20d50b9f58 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -640,8 +640,9 @@ static void ds_build_op_str(RDisasmState *ds) { ds->opstr = strdup (ds->str); core->parser->flagspace = ofs; // ??? } else { - if (!ds->opstr) - ds->opstr = strdup (asm_str?asm_str:""); + if (!ds->opstr) { + ds->opstr = strdup (asm_str? asm_str: ""); + } } } if (ds->use_esil) { @@ -649,11 +650,13 @@ static void ds_build_op_str(RDisasmState *ds) { free (ds->opstr); ds->opstr = strdup (R_STRBUF_SAFEGET (&ds->analop.esil)); } else { - char *p = malloc (strlen (ds->opstr)+6); /* What's up '\0' ? */ - strcpy (p, "TODO,"); - strcpy (p+5, ds->opstr); - free (ds->opstr); - ds->opstr = p; + char *p = malloc (strlen (ds->opstr) + 6); /* What's up '\0' ? */ + if (p) { + strcpy (p, "TODO,"); + strcpy (p + 5, ds->opstr); + free (ds->opstr); + ds->opstr = p; + } } } free (asm_str); @@ -2241,15 +2244,20 @@ static void ds_print_ptr(RDisasmState *ds, int len, int idx) { } if (p == UT64_MAX) { /* do nothing */ - } else if (((st64)p)>0) { + } else if (((st64)p) > 0) { const char *kind; - char *msg = calloc(sizeof(char), len); + char *msg = calloc (sizeof (char), len); RFlagItem *f, *f2; - r_io_read_at (core->io, p, (ut8*)msg, len-1); + r_io_read_at (core->io, p, (ut8*)msg, len - 1); if (ds->analop.refptr) { - ut64 num = r_read_le64 (msg); + ut64 num; + if (core->print->big_endian) { + num = r_read_le64 (msg); + } else { + num = r_read_be64 (msg); + } // TODO: make this more complete switch (ds->analop.refptr) { case 1: num &= UT8_MAX; break; @@ -2270,7 +2278,7 @@ static void ds_print_ptr(RDisasmState *ds, int len, int idx) { r_cons_printf (" ; 0x%"PFMT64x"%s%s", p, *flag?" ; ":"", flag); } else { f = NULL; - if (n==UT32_MAX || n==UT64_MAX) { + if (n == UT32_MAX || n == UT64_MAX) { r_cons_printf (" ; [0x%"PFMT64x":%d]=-1", p, ds->analop.refptr); } else if (n == n32 && (n32>-512 && n32 <512)) { r_cons_printf (" ; [0x%"PFMT64x":%d]=%"PFMT64d, p, ds->analop.refptr, n); @@ -2319,19 +2327,19 @@ static void ds_print_ptr(RDisasmState *ds, int len, int idx) { DOALIGN(); if (*msg) { - r_cons_printf (" ; \"%s\" @ 0x%"PFMT64x, msg, p); + r_cons_printf (" ; \"%s\"", msg); // @ 0x%"PFMT64x, msg, p); } else { r_cons_printf (" ; %s", f->name); } } else { - if (p==UT64_MAX || p==UT32_MAX) { + if (p == UT64_MAX || p == UT32_MAX) { DOALIGN(); r_cons_printf (" ; -1", p); } else if (((char)p>0) && p>='!' && p<='~') { char ch = p; DOALIGN(); r_cons_printf (" ; '%c'", ch); - } else if (p>10) { + } else if (p > 10) { if ((st64)p<0) { // resolve local var if possible RAnalVar *v = r_anal_var_get (core->anal, ds->at, 'v', 1, (int)p); @@ -2353,13 +2361,14 @@ static void ds_print_ptr(RDisasmState *ds, int len, int idx) { } } } - kind = r_anal_data_kind (core->anal, p, (const ut8*)msg, len-1); + kind = r_anal_data_kind (core->anal, p, (const ut8*)msg, len - 1); if (kind) { if (!strcmp (kind, "text")) { r_str_filter (msg, 0); if (*msg) { DOALIGN(); - r_cons_printf (" ; \"%s\" @ 0x%"PFMT64x, msg, p); + //r_cons_printf (" ; \"%s\" @ 0x%"PFMT64x, msg, p); + r_cons_printf (" ; \"%s\"", msg); // @ 0x%"PFMT64x, msg, p); } } else if (!strcmp (kind, "invalid")){ int *n = (int*)&p; @@ -2432,9 +2441,9 @@ static int myregwrite(RAnalEsil *esil, const char *name, ut64 val) { } } - memset (str, 0, sizeof (str)); if (val != 0LL) { +#if 0 RFlagItem *fi = r_flag_get_i (esil->anal->flb.f, val); if (fi) { strncpy (str, fi->name, sizeof (str)-1); @@ -2460,6 +2469,29 @@ static int myregwrite(RAnalEsil *esil, const char *name, ut64 val) { } else { msg = r_str_newf ("%s", str); } + +#endif + (void)r_io_read_at (esil->anal->iob.io, val, (ut8*)str, sizeof (str)-1); + str[sizeof (str)-1] = 0; + if (*str && r_str_is_printable (str)) { + // do nothing + msg = r_str_newf ("\"%s\"", str); + } else { + str[0] = 0; + if (*n32 == 0) { + // msg = strdup ("NULL"); + } else if (*n32 == UT32_MAX) { + /* nothing */ + } else { + if (ds && !ds->show_emu_str) { + msg = r_str_newf ("-> 0x%x", *n32); + } + } + } + RFlagItem *fi = r_flag_get_i (esil->anal->flb.f, val); + if (fi) { + msg = r_str_concatf (msg, " %s", fi->name); + } } if (ds && ds->show_emu_str) { if (msg && *msg) r_cons_printf ("; %s", msg); @@ -2498,7 +2530,6 @@ static void ds_print_esil_anal_init(RDisasmState *ds) { static void ds_print_esil_anal_fini(RDisasmState *ds) { if (ds->show_emu && ds->esil_regstate) { RCore* core = ds->core; - const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); r_reg_arena_poke (core->anal->reg, ds->esil_regstate); r_reg_setv (core->anal->reg, pc, ds->esil_old_pc); @@ -2542,6 +2573,7 @@ static void ds_print_esil_anal(RDisasmState *ds) { esil = core->anal->esil; pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); r_reg_setv (core->anal->reg, pc, ds->at + ds->analop.size); + //r_reg_setv (core->anal->reg, pc, ds->at); esil->cb.hook_reg_write = myregwrite; if (ds->show_emu_write) { esil->cb.hook_mem_write = mymemwrite0; @@ -2551,6 +2583,7 @@ static void ds_print_esil_anal(RDisasmState *ds) { ds->esil_likely = 0; r_anal_esil_parse (esil, R_STRBUF_SAFEGET (&ds->analop.esil)); r_anal_esil_stack_free (esil); + switch (ds->analop.type) { case R_ANAL_OP_TYPE_SWI: { char *s = cmd_syscall_dostr (core, -1); diff --git a/libr/core/visual.c b/libr/core/visual.c index 8c88052fac..15c761d995 100644 --- a/libr/core/visual.c +++ b/libr/core/visual.c @@ -26,8 +26,9 @@ static int visual_repeat_thread(RThread *th) { RCore *core = th->user; int i = 0; for (;;) { - if (core->cons->breaked) + if (core->cons->breaked) { break; + } visual_refresh (core); r_cons_flush (); r_cons_gotoxy (0, 0);