Add dexdump.sh to import DEX info into r2, VF now fits in screen

And 'C' toggles color! a use-after-free has been fixed too
And more instructions are now recognized by the analysis
This commit is contained in:
pancake 2015-03-24 03:23:56 +01:00
parent 908d5bf9a4
commit f4e3f593d4
8 changed files with 81 additions and 12 deletions

47
doc/dexdump.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/sh
# Import DEX/Dalvik information from `dexdump`
# Usage:
# r2 -c '.!doc/dexdump.sh $FILE' classes.dex
if [ -z "${DEXDUMP}" ]; then
DEXDUMP="${HOME}/Downloads/android-sdk/sdk/build-tools/android-4.4.2/dexdump";
if [ ! -x "${DEXDUMP}" ]; then
DEXDUMP="dexdump"
fi
fi
if [ -z "$1" ] ;then
echo "Usage: dexdump.sh [dexfile] > dex.r2"
exit 1
fi
echo "e asm.arch=dalvik"
echo "e asm.bits=32"
echo "fs symbols"
#${DEXDUMP} -d $1 ; exit 0
# Symbols
${DEXDUMP} -d $1 | perl -ne '
s/://g;
if (/invoke-/) {
s/\s+/ /g;
local @str = split (/ /);
/\sL(.*)/;
local $msg = $1;
$msg=~tr/,()[]{}|\/\;$<> @#-+*/_____________________/;
#$msg=~s//;
print "fs callrefs\nCC call.L".$msg." @ 0x".$str[0]."\n";
} elsif (/\|\[/) {
tr/()[]\/\;$<>/_________/;
/^(.*) (.*) (.*)$/;
print "fs symbols\nf sym.$3 = 0x$1\n";
} elsif (/const-string/) {
s/\s+/ /g;
local @str = split (/ /);
/"(.*)"/;
local $msg = $1;
$msg=~tr/,()[]{}|\/\;$<> @#-+*/_____________________/;
#$msg=~s//;
print "fs strings\nCC str.".$msg." @ 0x".$str[0]."\n";
}
'
echo "fs *"

View File

@ -24,6 +24,14 @@ R_API RList *r_anal_op_list_new() {
} }
R_API void r_anal_op_fini(RAnalOp *op) { R_API void r_anal_op_fini(RAnalOp *op) {
if (!op) // || !op->mnemonic)
return;
if (((ut64)(size_t)op) == UT64_MAX) {
return;
}
if (((ut64)(size_t)op->mnemonic) == UT64_MAX) {
return;
}
r_anal_value_free (op->src[0]); r_anal_value_free (op->src[0]);
r_anal_value_free (op->src[1]); r_anal_value_free (op->src[1]);
r_anal_value_free (op->src[2]); r_anal_value_free (op->src[2]);

View File

@ -44,6 +44,7 @@ static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int l
case 0x42: // const case 0x42: // const
case 0x18: // const-wide case 0x18: // const-wide
case 0x19: // const-wide case 0x19: // const-wide
case 0x1a: // const-string
case 0x0c: // move-result-object // TODO: add MOVRET OP TYPE ?? case 0x0c: // move-result-object // TODO: add MOVRET OP TYPE ??
case 0x0b: // move-result-wide case 0x0b: // move-result-wide
case 0x1c: // const-class case 0x1c: // const-class
@ -59,11 +60,12 @@ static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int l
case 0x88: // float-to-long case 0x88: // float-to-long
op->family = R_ANAL_OP_FAMILY_FPU; op->family = R_ANAL_OP_FAMILY_FPU;
/* pass thru */ /* pass thru */
case 0x8f: // int-to-short
case 0x81: // int-to-long case 0x81: // int-to-long
case 0x82: // case 0x82: //
case 0x83: // case 0x83: //
case 0x84: // case 0x84: //
case 0x8d: // int-to-byte
case 0x8f: // int-to-short
case 0x20: // instance-of case 0x20: // instance-of
op->type = R_ANAL_OP_TYPE_CAST; op->type = R_ANAL_OP_TYPE_CAST;
break; break;
@ -247,7 +249,7 @@ static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int l
case 0x3c: // if-gtz case 0x3c: // if-gtz
case 0x3d: // if-lez case 0x3d: // if-lez
op->type = R_ANAL_OP_TYPE_CJMP; op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = addr + (short)(data[2]|data[3]<<8)*2; op->jump = addr + sz + (short)(data[2]|data[3]<<8)*2;
op->fail = addr + sz; op->fail = addr + sz;
op->eob = 1; op->eob = 1;
break; break;

View File

@ -21,7 +21,7 @@ R_API RAnalSwitchOp * r_anal_switch_op_new(ut64 addr, ut64 min_val, ut64 def_val
} }
R_API void r_anal_switch_op_free(RAnalSwitchOp * swop) { R_API void r_anal_switch_op_free(RAnalSwitchOp * swop) {
if (swop == NULL) return; if ((((ut64)(size_t)swop)==UT64_MAX) || swop == NULL) return;
if (swop->cases) if (swop->cases)
r_list_free(swop->cases); r_list_free(swop->cases);
free(swop); free(swop);

View File

@ -20,8 +20,11 @@ R_API RAnalValue *r_anal_value_copy (RAnalValue *ov) {
// TODO: move into .h as #define free // TODO: move into .h as #define free
R_API void r_anal_value_free(RAnalValue *value) { R_API void r_anal_value_free(RAnalValue *value) {
/* TODO: free RRegItem objects? */ ut64 pval = (ut64)(size_t)value;
free (value); if (pval && pval != UT64_MAX) {
/* TODO: free RRegItem objects? */
free (value);
}
} }
// mul*value+regbase+regidx+delta // mul*value+regbase+regidx+delta

View File

@ -675,7 +675,7 @@ static RList* sections(RBinFile *arch) {
} }
if ((ptr = R_NEW0 (RBinSection))) { if ((ptr = R_NEW0 (RBinSection))) {
strcpy (ptr->name, "code"); strcpy (ptr->name, "code");
ptr->paddr = bin->code_from; //ptr->vaddr = fsym; ptr->vaddr = ptr->paddr = bin->code_from; //ptr->vaddr = fsym;
ptr->size = bin->code_to - ptr->paddr; ptr->size = bin->code_to - ptr->paddr;
ptr->srwx = 4|1; ptr->srwx = 4|1;
r_list_append (ret, ptr); r_list_append (ret, ptr);
@ -688,7 +688,7 @@ static RList* sections(RBinFile *arch) {
ptr->paddr = ptr->vaddr = bin->code_to; ptr->paddr = ptr->vaddr = bin->code_to;
ptr->size = ptr->vsize = arch->buf->length - ptr->vaddr; ptr->size = ptr->vsize = arch->buf->length - ptr->vaddr;
} else { } else {
ptr->size = ptr->vsize = ptr->vaddr - arch->buf->length; ptr->size = ptr->vsize = arch->buf->length - ptr->vaddr;
// hacky workaround // hacky workaround
dprintf ("Hack\n"); dprintf ("Hack\n");
//ptr->size = ptr->vsize = 1024; //ptr->size = ptr->vsize = 1024;

View File

@ -2129,7 +2129,9 @@ toro:
if (core->inc == 0) if (core->inc == 0)
core->inc = ds->oplen; core->inc = ds->oplen;
r_anal_op_fini (&ds->analop); if (ds->analop.mnemonic) {
r_anal_op_fini (&ds->analop);
}
if (!ds->lastfail) if (!ds->lastfail)
r_anal_op (core->anal, &ds->analop, ds->at, buf+idx, (int)(len-idx)); r_anal_op (core->anal, &ds->analop, ds->at, buf+idx, (int)(len-idx));

View File

@ -304,7 +304,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
r_cons_clear00 (); r_cons_clear00 ();
if (menu) { if (menu) {
r_cons_printf ("Flags in flagspace '%s'. Press '?' for help.\n\n", r_cons_printf ("Flags in flagspace '%s'. Press '?' for help.\n",
(core->flags->space_idx==-1)?"*":core->flags->spaces[core->flags->space_idx]); (core->flags->space_idx==-1)?"*":core->flags->spaces[core->flags->space_idx]);
hit = 0; hit = 0;
i = j = 0; i = j = 0;
@ -330,11 +330,14 @@ R_API int r_core_visual_trackflags(RCore *core) {
continue; continue;
} }
if (fs2) { if (fs2) {
int cols, rows = r_cons_get_size (&cols);
//int rows = 20;
rows -= 12;
r_cons_printf ("\n Selected: %s\n\n", fs2); r_cons_printf ("\n Selected: %s\n\n", fs2);
// Honor MAX_FORMATS here // Honor MAX_FORMATS here
switch (format) { switch (format) {
case 0: snprintf (cmd, sizeof (cmd), "px @ %s!64", fs2); core->printidx = 0; break; case 0: snprintf (cmd, sizeof (cmd), "px %d @ %s!64", rows*16, fs2); core->printidx = 0; break;
case 1: snprintf (cmd, sizeof (cmd), "pd 12 @ %s!64", fs2); core->printidx = 1; break; case 1: snprintf (cmd, sizeof (cmd), "pd %d @ %s!64", rows, fs2); core->printidx = 1; break;
case 2: snprintf (cmd, sizeof (cmd), "ps @ %s!64", fs2); core->printidx = 5; break; case 2: snprintf (cmd, sizeof (cmd), "ps @ %s!64", fs2); core->printidx = 5; break;
case 3: strcpy (cmd, "f="); break; case 3: strcpy (cmd, "f="); break;
default: format = 0; continue; default: format = 0; continue;
@ -342,7 +345,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
if (*cmd) r_core_cmd (core, cmd, 0); if (*cmd) r_core_cmd (core, cmd, 0);
} else r_cons_printf ("(no flags)\n"); } else r_cons_printf ("(no flags)\n");
} else { } else {
r_cons_printf ("Flag spaces:\n\n"); r_cons_printf ("Flag spaces:\n");
hit = 0; hit = 0;
for (j=i=0;i<R_FLAG_SPACES_MAX;i++) { for (j=i=0;i<R_FLAG_SPACES_MAX;i++) {
if (core->flags->spaces[i]) { if (core->flags->spaces[i]) {
@ -380,6 +383,9 @@ R_API int r_core_visual_trackflags(RCore *core) {
if (ch==-1||ch==4) return R_FALSE; if (ch==-1||ch==4) return R_FALSE;
ch = r_cons_arrow_to_hjkl (ch); // get ESC+char, return 'hjkl' char ch = r_cons_arrow_to_hjkl (ch); // get ESC+char, return 'hjkl' char
switch (ch) { switch (ch) {
case 'C':
r_config_set_i (core->config, "scr.color", r_config_get_i (core->config, "scr.color")?0:1);
break;
case 'J': option += 10; break; case 'J': option += 10; break;
case 'o': r_flag_sort (core->flags, 0); break; case 'o': r_flag_sort (core->flags, 0); break;
case 'n': r_flag_sort (core->flags, 1); break; case 'n': r_flag_sort (core->flags, 1); break;
@ -503,6 +509,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
" q - quit menu\n" " q - quit menu\n"
" j/k - down/up keys\n" " j/k - down/up keys\n"
" h/b - go back\n" " h/b - go back\n"
" C - toggle colors\n"
" l/' ' - accept current selection\n" " l/' ' - accept current selection\n"
" a/d/e - add/delete/edit flag\n" " a/d/e - add/delete/edit flag\n"
" +/- - increase/decrease block size\n" " +/- - increase/decrease block size\n"