mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-04 19:47:31 +00:00
Enhace ARM disassembly and code analysis
This commit is contained in:
parent
7c1e0c85d9
commit
21c4d1c5f5
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2007-2011 */
|
||||
/* radare - LGPL - Copyright 2007-2012 */
|
||||
/* pancake<nopcode.org> */
|
||||
|
||||
#include <string.h>
|
||||
@ -102,6 +102,7 @@ static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = addr+4+(delta<<1);
|
||||
op->fail = addr+4;
|
||||
op->eob = 1;
|
||||
} else if ( (ins & _(B1111,B1111,0,0)) == _(B0100,B0111,0,0) ) {
|
||||
// BLX
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
@ -121,6 +122,7 @@ static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
|
||||
}
|
||||
|
||||
static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
|
||||
unsigned char ndata[4];
|
||||
struct arm_insn *arminsn;
|
||||
ut32 branch_dst_addr, i = 0;
|
||||
ut32* code = (ut32 *)data;
|
||||
@ -130,11 +132,19 @@ static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
return 0;
|
||||
memset (op, '\0', sizeof (RAnalOp));
|
||||
arminsn = arm_new();
|
||||
arm_set_thumb(arminsn, R_FALSE);
|
||||
arm_set_input_buffer(arminsn, data);
|
||||
arm_set_pc(arminsn, addr);
|
||||
arm_set_thumb (arminsn, R_FALSE);
|
||||
arm_set_input_buffer (arminsn, data);
|
||||
arm_set_pc (arminsn, addr);
|
||||
op->addr = addr;
|
||||
op->type = R_ANAL_OP_TYPE_UNK;
|
||||
|
||||
if (anal->big_endian) {
|
||||
b = data = ndata;
|
||||
ndata[0]=data[3];
|
||||
ndata[1]=data[2];
|
||||
ndata[2]=data[1];
|
||||
ndata[3]=data[0];
|
||||
}
|
||||
#if 0
|
||||
op->jump = op->fail = -1;
|
||||
op->ref = op->value = -1;
|
||||
@ -147,19 +157,29 @@ static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
codeA[0], codeA[1], codeA[2], codeA[3]);
|
||||
#endif
|
||||
// 0x000037b8 00:0000 0 800000ef svc 0x00000080
|
||||
if (b[2] ==0xa0 && b[3]==0xe1) {
|
||||
int n = (b[0]<<16) + b[1];
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
switch (n) {
|
||||
case 0:
|
||||
case 0x0110: case 0x0220: case 0x0330: case 0x0440:
|
||||
case 0x0550: case 0x0660: case 0x0770: case 0x0880:
|
||||
case 0x0990: case 0x0aa0: case 0x0bb0: case 0x0cc0:
|
||||
op->type = R_ANAL_OP_TYPE_NOP;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if (b[3]==0xef) {
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
op->value = (b[0] | (b[1]<<8) | (b[2]<<2));
|
||||
} else
|
||||
if (b[3]==0xe5) {
|
||||
if (b[2]==0x9f) {
|
||||
/* STORE */
|
||||
/* LDR/STR */
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
op->stackop = R_ANAL_STACK_SET;
|
||||
|
||||
//printf ("FUCKING PT Rpc AT 0x%08llx + %d\n", addr, b[0]);
|
||||
//op->ref = 4+addr+b[0]+(b[1]&4<<8);
|
||||
op->ref = 8+addr+b[0]+((b[1]&0xf)<<8);
|
||||
op->ref = 12+addr+b[0]+((b[1]&0xf)<<8);
|
||||
op->refptr = R_TRUE;
|
||||
} else
|
||||
if ((b[1]&0xf0) == 0xf0) {
|
||||
@ -223,7 +243,8 @@ static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
}
|
||||
|
||||
if (IS_EXITPOINT (code[i])) {
|
||||
branch_dst_addr = disarm_branch_offset (addr, code[i]&0x00FFFFFF);
|
||||
b=data;
|
||||
branch_dst_addr = disarm_branch_offset (addr, b[0] | (b[1]<<8) | (b[2]<<16)); //code[i]&0x00FFFFFF);
|
||||
op->ref = 0;
|
||||
if (IS_BRANCHL (code[i])) {
|
||||
if (IS_BRANCH (code[i])) {
|
||||
@ -238,7 +259,9 @@ static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
} else if (IS_BRANCH (code[i])) {
|
||||
if (IS_CONDAL (code[i])) {
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
//op->type = R_ANAL_OP_TYPE_NOP;
|
||||
op->jump = branch_dst_addr;
|
||||
op->fail = UT64_MAX;
|
||||
op->eob = 1;
|
||||
} else {
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
@ -252,8 +275,8 @@ static int arm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
op->eob = 1;
|
||||
}
|
||||
}
|
||||
op->jump = arminsn->jmp;
|
||||
op->fail = arminsn->fail;
|
||||
//op->jump = arminsn->jmp;
|
||||
//op->fail = arminsn->fail;
|
||||
arm_free(arminsn);
|
||||
return op->length;
|
||||
}
|
||||
@ -263,6 +286,7 @@ static int set_reg_profile(RAnal *anal) {
|
||||
return r_reg_set_profile_string (anal->reg,
|
||||
"=pc r15\n"
|
||||
"=sp r14\n" // XXX
|
||||
"=bp r14\n" // XXX
|
||||
"=a0 r0\n"
|
||||
"=a1 r1\n"
|
||||
"=a2 r2\n"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,7 @@ static int config_bigendian_callback(void *user, void *data) {
|
||||
RCore *core = (RCore *) user;
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
core->assembler->big_endian = node->i_value;
|
||||
core->anal->big_endian = node->i_value;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -343,11 +343,15 @@ toro:
|
||||
char *sign = r_anal_fcn_to_string (core->anal, f);
|
||||
if (f->type == R_ANAL_FCN_TYPE_LOC) {
|
||||
r_cons_printf ("|- %s (%d)\n| ", f->name, f->size);
|
||||
} else
|
||||
r_cons_printf ("/ %s: %s (%d)\n| ",
|
||||
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"function":
|
||||
(f->type==R_ANAL_FCN_TYPE_IMP)?"import":"loc",
|
||||
f->name, f->size);
|
||||
} else {
|
||||
const char *fmt = show_color?
|
||||
"/ "Color_MAGENTA"%s: "Color_YELLOW"%s"Color_RESET" (%d)\n| ":
|
||||
"/ %s: %s (%d)\n| ";
|
||||
r_cons_printf (fmt,
|
||||
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"function":
|
||||
(f->type==R_ANAL_FCN_TYPE_IMP)?"import":"loc",
|
||||
f->name, f->size);
|
||||
}
|
||||
if (sign) r_cons_printf ("// %s\n", sign);
|
||||
free (sign);
|
||||
pre = "| ";
|
||||
@ -367,7 +371,9 @@ toro:
|
||||
if (show_lines && refline)
|
||||
r_cons_strcat (refline);
|
||||
if (show_offset)
|
||||
printoffset (at, show_color, (at==dest), show_offseg);
|
||||
// printoffset (at, show_color, (at==dest), show_offseg);
|
||||
//r_cons_printf ("__________ ");
|
||||
r_cons_printf ("; -------- ");
|
||||
if (show_functions)
|
||||
r_cons_printf ("%s:\n%s", flag->name, f?"| ":" ");
|
||||
else r_cons_printf ("%s:\n", flag->name);
|
||||
@ -402,7 +408,10 @@ toro:
|
||||
// TODO: filter string (r_str_unscape)
|
||||
{
|
||||
char *out = r_str_unscape (mi->str);
|
||||
r_cons_printf ("string (%"PFMT64d"): \"%s\"\n", mi->size, out);
|
||||
if (show_color)
|
||||
r_cons_printf (" .string "Color_YELLOW"\"%s\""Color_RESET" ; len=%"PFMT64d"\n", out, mi->size);
|
||||
else
|
||||
r_cons_printf (" .string \"%s\" ; len=%"PFMT64d"\n", out, mi->size);
|
||||
free (out);
|
||||
}
|
||||
ret = (int)mi->size;
|
||||
@ -642,17 +651,19 @@ toro:
|
||||
R_META_TYPE_ANY, R_META_WHERE_HERE);
|
||||
if (mi2) {
|
||||
char *str = r_str_unscape (mi2->str);
|
||||
r_cons_printf (" (at=0x%08"PFMT64x") (len=%"PFMT64d") \"%s\" ", analop.ref, mi2->size, str);
|
||||
r_cons_printf (" \"%s\" @ 0x%08"PFMT64x":%"PFMT64d,
|
||||
str, analop.ref, mi2->size);
|
||||
free (str);
|
||||
} else r_cons_printf ("; => 0x%08x ", word);
|
||||
} else {
|
||||
if (mi2->type == R_META_TYPE_STRING) {
|
||||
char *str = r_str_unscape (mi2->str);
|
||||
r_cons_printf (" (at=0x%08x) (len=%"PFMT64d") \"%s\" ", word, mi2->size, str);
|
||||
r_cons_printf (" (at=0x%08x) (len=%"PFMT64d
|
||||
") \"%s\" ", word, mi2->size, str);
|
||||
free (str);
|
||||
} else r_cons_printf ("unknown type '%c'\n", mi2->type);
|
||||
}
|
||||
}
|
||||
} else r_cons_printf (" ; => 0x%08"PFMT64x"\n", analop.ref); //addr+idx+analop.ref);
|
||||
}
|
||||
if (show_comments && show_comment_right && comment) {
|
||||
int c = r_cons_get_column ();
|
||||
|
Loading…
Reference in New Issue
Block a user