diff --git a/libr/anal/p/anal_arm_cs.c b/libr/anal/p/anal_arm_cs.c index e2c5dd9bbe..c8f90c200d 100644 --- a/libr/anal/p/anal_arm_cs.c +++ b/libr/anal/p/anal_arm_cs.c @@ -181,6 +181,7 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len op->refptr = 4; } break; + case ARM_INS_LDRD: case ARM_INS_LDRB: r_strbuf_appendf (&op->esil, "%s,%d,+,[1],%s,=", MEMBASE(1), MEMDISP(1), REG(0)); @@ -366,6 +367,7 @@ static void anop32 (RAnalOp *op, cs_insn *insn) { } break; case ARM_INS_LDR: + case ARM_INS_LDRD: case ARM_INS_LDRB: // 0x000082a8 28301be5 ldr r3, [fp, -0x28] if (insn->detail->arm.operands[0].reg == ARM_REG_PC) { @@ -447,7 +449,7 @@ static int set_reg_profile(RAnal *anal) { char *p = (anal->bits != 64) ? "=pc r15\n" "=sp r14\n" // XXX - "=bp r14\n" // XXX + "=bp fp\n" // XXX "=a0 r0\n" "=a1 r1\n" "=a2 r2\n" diff --git a/libr/core/graph.c b/libr/core/graph.c index 9e605009ed..cee919d6f1 100644 --- a/libr/core/graph.c +++ b/libr/core/graph.c @@ -79,6 +79,7 @@ static void Node_print(RConsCanvas *can, Node *n, int cur) { n->w += 4; n->h += 3; n->w = R_MAX (18, n->w); +#if SHOW_OUT_OF_SCREEN_NODES { int x = n->x + can->sx; int y = n->y + n->h + can->sy; @@ -87,6 +88,7 @@ static void Node_print(RConsCanvas *can, Node *n, int cur) { if (y<0 || y> can->h) return; } +#endif if (cur) { //F (n->x,n->y, n->w, n->h, '.'); snprintf (title, sizeof (title)-1, @@ -97,11 +99,12 @@ static void Node_print(RConsCanvas *can, Node *n, int cur) { } if (G (n->x+1, n->y+1)) W (title); - if (G (n->x+2, n->y+2)) { + G (n->x+2, n->y+2); + //if ( // TODO: temporary crop depending on out of screen offsets -//n->text = r_str_crop (n->text, 1,1,4,4); + //n->text = r_str_crop (n->text, 1,1,4,4); W (n->text); - } + //} if (G (n->x+1, n->y+1)) W (title); B (n->x, n->y, n->w, n->h); diff --git a/libr/include/r_parse.h b/libr/include/r_parse.h index 0e345aa872..dd8e1f58ee 100644 --- a/libr/include/r_parse.h +++ b/libr/include/r_parse.h @@ -60,6 +60,7 @@ R_API int r_parse_is_c_file (const char *file); extern struct r_parse_plugin_t r_parse_plugin_dummy; extern struct r_parse_plugin_t r_parse_plugin_att2intel; extern struct r_parse_plugin_t r_parse_plugin_x86_pseudo; +extern struct r_parse_plugin_t r_parse_plugin_arm_pseudo; extern struct r_parse_plugin_t r_parse_plugin_mips_pseudo; extern struct r_parse_plugin_t r_parse_plugin_dalvik_pseudo; extern struct r_parse_plugin_t r_parse_plugin_mreplace; diff --git a/libr/parse/p/Makefile b/libr/parse/p/Makefile index 6a18c6487d..2f5ddce608 100644 --- a/libr/parse/p/Makefile +++ b/libr/parse/p/Makefile @@ -9,7 +9,7 @@ CFLAGS+=-DCORELIB foo: all ALL_TARGETS= -ARCHS=att2intel.mk x86_pseudo.mk mreplace.mk +ARCHS=att2intel.mk x86_pseudo.mk mreplace.mk arm_pseudo.mk include $(ARCHS) all: ${ALL_TARGETS} diff --git a/libr/parse/p/arm_pseudo.mk b/libr/parse/p/arm_pseudo.mk new file mode 100644 index 0000000000..a2f40536a7 --- /dev/null +++ b/libr/parse/p/arm_pseudo.mk @@ -0,0 +1,10 @@ +OBJ_ARMPSEUDO+=parse_arm_pseudo.o + +TARGET_ARMPSEUDO=parse_arm_pseudo.${EXT_SO} +ALL_TARGETS+=${TARGET_ARMPSEUDO} +STATIC_OBJ+=${OBJ_ARMPSEUDO} +LIBDEPS=-L../../util -lr_util +LIBDEPS+=-L../../flags -lr_flags + +${TARGET_ARMPSEUDO}: ${OBJ_ARMPSEUDO} + ${CC} $(call libname,parse_arm_pseudo) ${LIBDEPS} -shared ${CFLAGS} -o ${TARGET_ARMPSEUDO} ${OBJ_ARMPSEUDO} diff --git a/libr/parse/p/parse_arm_pseudo.c b/libr/parse/p/parse_arm_pseudo.c new file mode 100644 index 0000000000..e66585a25a --- /dev/null +++ b/libr/parse/p/parse_arm_pseudo.c @@ -0,0 +1,230 @@ +/* radare - LGPL - Copyright 2015 - pancake */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +static int replace(int argc, const char *argv[], char *newstr) { + int i,j,k; + struct { + char *op; + char *str; + } ops[] = { + { "cmp", "cmp 1 2"}, + { "ldr", "1 = 2 + 3"}, + { "mov", "1 = 2"}, + { "ldrb", "1 = 2"}, + { "str", "2 + 3 = 1"}, + { "add", "1 = 2 + 3"}, + { "sub", "1 = 2 - 3"}, + { "bxeq", "je 1"}, + { "beq", "je 1"}, + { "bx lr", "ret"}, + { "beq lr", "ifeq ret"}, + { "bl", "call 1"}, + { "blx", "call 1"}, + { "blx", "call 1"}, + { "b", "jmp 1"}, + { "lsl", "1 = 2 << 3"}, + { "lsr", "1 = 2 >> 3"}, + /* 64bit */ + { "movz", "1 = 2"}, + { "b.gt", "jmp ifgt 1"}, + { "b.le", "jmp ifle 1"}, + { "adrp", "1 = 2"}, + { "ldrsw", "1 = 2 + 3"}, + { "eor", "1 = 2 ^ 3"}, + { NULL } + }; + + for (i=0; ops[i].op != NULL; i++) { + if (!strcmp (ops[i].op, argv[0])) { + if (newstr != NULL) { + for (j=k=0; ops[i].str[j]!='\0'; j++, k++) { + if (ops[i].str[j]>='0' && ops[i].str[j]<='9') { + const char *w = argv[ ops[i].str[j]-'0' ]; + if (w != NULL) { + strcpy(newstr+k, w); + k += strlen(w)-1; + } + } else newstr[k] = ops[i].str[j]; + } + newstr[k]='\0'; + } + return R_TRUE; + } + } + + /* TODO: this is slow */ + if (newstr != NULL) { + newstr[0] = '\0'; + for (i=0; i=sizeof (w0)) + return R_FALSE; + // malloc can be slow here :? + if ((buf = malloc (len+1)) == NULL) + return R_FALSE; + memcpy (buf, data, len+1); + + if (*buf) { + *w0 = *w1 = *w2 = *w3 = '\0'; + ptr = strchr (buf, ' '); + if (ptr == NULL) + ptr = strchr (buf, '\t'); + if (ptr) { + *ptr = '\0'; + for (++ptr; *ptr==' '; ptr++); + strncpy (w0, buf, sizeof (w0) - 1); + strncpy (w1, ptr, sizeof (w1) - 1); + + optr = ptr; + ptr = strchr (ptr, ','); + if (ptr) { + *ptr = '\0'; + for (++ptr; *ptr==' '; ptr++); + strncpy (w1, optr, sizeof (w1) - 1); + strncpy (w2, ptr, sizeof (w2) - 1); + optr = ptr; + ptr = strchr (ptr, ','); + if (ptr) { + *ptr = '\0'; + for (++ptr; *ptr==' '; ptr++); + strncpy (w2, optr, sizeof (w2) - 1); + strncpy (w3, ptr, sizeof (w3) - 1); + } + } + } + { + const char *wa[] = { w0, w1, w2, w3 }; + int nw = 0; + for (i=0; i<4; i++) { + if (wa[i][0] != '\0') + nw++; + } + replace (nw, wa, str); + } + } + free (buf); + return R_TRUE; +} + +static int varsub(RParse *p, RAnalFunction *f, char *data, char *str, int len) { + RAnalVar *var; + RListIter *iter; + char oldstr[64], newstr[64]; + char *tstr = strdup (data); + RList *vars, *args; + + if (!p->varlist) { + free(tstr); + return R_FALSE; + } + + vars = p->varlist (p->anal, f, 'v'); + args = p->varlist (p->anal, f, 'a'); + r_list_join (vars, args); + switch (p->anal->bits) { + case 64: + r_list_foreach (vars, iter, var) { + if (var->delta < 10) snprintf (oldstr, sizeof (oldstr)-1, + "[%s, %d]", + p->anal->reg->name[R_REG_NAME_BP], + var->delta); + else snprintf (oldstr, sizeof (oldstr)-1, + "[%s, 0x%x]", + p->anal->reg->name[R_REG_NAME_BP], + var->delta); + snprintf (newstr, sizeof (newstr)-1, "[%s+%s]", + p->anal->reg->name[R_REG_NAME_BP], + var->name); + 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; + } + } + break; + case 32: + r_list_foreach (vars, iter, var) { + if (var->delta < 10) snprintf (oldstr, sizeof (oldstr)-1, + "[%s, -%d]", + p->anal->reg->name[R_REG_NAME_BP], + var->delta); + else snprintf (oldstr, sizeof (oldstr)-1, + "[%s, -0x%x]", + p->anal->reg->name[R_REG_NAME_BP], + var->delta); + snprintf (newstr, sizeof (newstr)-1, "[%s-%s]", + p->anal->reg->name[R_REG_NAME_BP], + var->name); + 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; + } + } + break; + case 16: + // + break; + } + if (len > strlen (tstr)) { + strncpy (str, tstr, strlen (tstr)); + str[strlen (tstr)] = 0; + } else { + // TOO BIG STRING CANNOT REPLACE HERE + return R_FALSE; + } + free (tstr); + return R_TRUE; +} + +struct r_parse_plugin_t r_parse_plugin_arm_pseudo = { + .name = "arm.pseudo", + .desc = "ARM/ARM64 pseudo syntax", + .init = NULL, + .fini = NULL, + .parse = parse, + .assemble = NULL, + .filter = NULL, + .varsub = &varsub, +}; + +#ifndef CORELIB +struct r_lib_struct_t radare_plugin = { + .type = R_LIB_TYPE_PARSE, + .data = &r_parse_plugin_arm_pseudo +}; +#endif diff --git a/plugins.def.cfg b/plugins.def.cfg index 5d2c92283d..cef69fc391 100644 --- a/plugins.def.cfg +++ b/plugins.def.cfg @@ -168,7 +168,8 @@ parse.mreplace parse.att2intel parse.mips_pseudo parse.dalvik_pseudo -parse.x86_pseudo" +parse.x86_pseudo +parse.arm_pseudo" SHARED=" asm.snes asm.6502