mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-03 02:41:08 +00:00
Fixes for thumb/arm string references and endian refptr
This commit is contained in:
parent
3081b3b5d6
commit
b829244c19
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user