From 21a9405a81079ee3eadad3b6bc1f5a28177116f0 Mon Sep 17 00:00:00 2001 From: earada Date: Sun, 26 Jun 2011 22:42:34 +0200 Subject: [PATCH] * Handle strings meta info in dalvik disassemble --- libr/asm/p/asm_dalvik.c | 112 ++++++++++++++++++++++++++++---------- libr/bin/format/dex/dex.h | 1 + libr/bin/p/bin_dex.c | 41 ++++++++++---- 3 files changed, 112 insertions(+), 42 deletions(-) diff --git a/libr/asm/p/asm_dalvik.c b/libr/asm/p/asm_dalvik.c index 74101c5428..6a385770c0 100644 --- a/libr/asm/p/asm_dalvik.c +++ b/libr/asm/p/asm_dalvik.c @@ -14,6 +14,7 @@ static int dalvik_disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) { int size = 0; int vA, vB, vC; char str[1024]; + ut64 offset; if (dalvik_opcodes[i].len <= len) { strcpy (op->buf_asm, dalvik_opcodes[i].name); @@ -118,7 +119,7 @@ static int dalvik_disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) { sprintf (str, " %#08x", vA); strcat (op->buf_asm, str); break; - case fmtopvAvBpCCCC: //TEST without pc + case fmtopvAvBpCCCC: vA = buf[1] & 0x0f; vB = (buf[1] & 0xf0)>>4; vC = (int) (buf[3] <<8 | buf[2]); @@ -190,58 +191,99 @@ static int dalvik_disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) { strcat (op->buf_asm, str); break; case fmtopvAAtBBBB: - //FIXME: strings & class & fieldmust be a dex(r_bin) section vA = (int) buf[1]; vB = (buf[3]<<8) | buf[2]; - if (buf[0] == 0x1a) - sprintf (str, " v%i, strings+%i", vA, vB); - else if (buf[0] == 0x1c || buf[0] == 0x1f || buf[0] == 0x22) - sprintf (str, " v%i, class+%i", vA, vB); - else - sprintf (str, " v%i, field+%i", vA, vB); - + if (buf[0] == 0x1a) { + offset = r_asm_get_offset(a, 's', vB); + if (offset == -1) + sprintf (str, " v%i, string+%i", vA, vB); + else + sprintf (str, " v%i, 0x%"PFMT64x, vA, offset); + } else if (buf[0] == 0x1c || buf[0] == 0x1f || buf[0] == 0x22) { + offset = r_asm_get_offset(a, 'c', vB); + if (offset == -1) + sprintf (str, " v%i, class+%i", vA, vB); + else + sprintf (str, " v%i, 0x%"PFMT64x, vA, offset); + } else { + offset = r_asm_get_offset(a, 'f', vB); + if (offset == -1) + sprintf (str, " v%i, field+%i", vA, vB); + else + sprintf (str, " v%i, 0x%"PFMT64x, vA, offset); + } strcat (op->buf_asm, str); break; - case fmtoptopvAvBoCCCC: //FIXME: obj must be a dex(r_bin) section + case fmtoptopvAvBoCCCC: vA = (buf[1] & 0x0f); vB = (buf[1] & 0xf0)>>4; vC = (buf[3]<<8) | buf[2]; - sprintf (str, " v%i, v%i, [obj+%04x]", vA, vB, vC); + offset = r_asm_get_offset(a, 'o', vC); + if (offset == -1) + sprintf (str, " v%i, v%i, [obj+%04x]", vA, vB, vC); + else + sprintf (str, " v%i, v%i, [0x%"PFMT64x"]", vA, vB, offset); strcat (op->buf_asm, str); break; - case fmtopAAtBBBB: //FIXME: thing must be a dex(r_bin) section + case fmtopAAtBBBB: vA = (int) buf[1]; vB = (buf[3]<<8) | buf[2]; - sprintf (str, " v%i, thing+%i", vA, vB); + offset = r_asm_get_offset(a, 't', vB); + if (offset == -1) + sprintf (str, " v%i, thing+%i", vA, vB); + else + sprintf (str, " v%i, 0x%"PFMT64x, vA, offset); strcat (op->buf_asm, str); break; - case fmtopvAvBtCCCC: //FIXME: class & field must be a dex section + case fmtopvAvBtCCCC: vA = (buf[1] & 0x0f); vB = (buf[1] & 0xf0)>>4; vC = (buf[3]<<8) | buf[2]; - if (buf[0] == 0x20 || buf[0] == 0x23) //instance-of & new-array - sprintf (str, " v%i, v%i, class+%i", vA, vB, vC); - else - sprintf (str, " v%i, v%i, field+%i", vA, vB, vC); + if (buf[0] == 0x20 || buf[0] == 0x23) { //instance-of & new-array + offset = r_asm_get_offset(a, 'c', vC); + if (offset == -1) + sprintf (str, " v%i, v%i, class+%i", vA, vB, vC); + else + sprintf (str, " v%i, v%i, 0x%"PFMT64x, vA, vB, offset); + } else { + offset = r_asm_get_offset(a, 'f', vC); + if (offset == -1) + sprintf (str, " v%i, v%i, field+%i", vA, vB, vC); + else + sprintf (str, " v%i, v%i, 0x%"PFMT64x, vA, vB, offset); + } strcat (op->buf_asm, str); break; - case fmtopvAAtBBBBBBBB: //FIXME: string must be a dex(r_bin) section + case fmtopvAAtBBBBBBBB: vA = (int) buf[1]; vB = (int) (buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24)); - sprintf (str, " v%i, string+%i", vA, vB); + offset = r_asm_get_offset(a, 's', vB); + if (offset == -1) + sprintf (str, " v%i, string+%i", vA, vB); + else + sprintf (str, " v%i, 0x%"PFMT64x, vA, offset); strcat (op->buf_asm, str); break; - case fmtopvCCCCmBBBB: //FIXME: class must be a dex(r_bin) section + case fmtopvCCCCmBBBB: vA = (int) buf[1]; vB = (buf[3]<<8) | buf[2]; vC = (buf[5]<<8) | buf[4]; - if (buf[0] == 0x25) // filled-new-array/range - sprintf (str, " {v%i..v%i}, class+%i", vC, vC+vA-1, vB); - else - sprintf (str, " {v%i..v%i}, method+%i", vC, vC+vA-1, vB); + if (buf[0] == 0x25) { // filled-new-array/range + offset = r_asm_get_offset(a, 'c', vB); + if (offset == -1) + sprintf (str, " {v%i..v%i}, class+%i", vC, vC+vA-1, vB); + else + sprintf (str, " {v%i..v%i}, 0x%"PFMT64x, vC, vC+vA-1, offset); + } else { + offset = r_asm_get_offset(a, 'm', vB); + if (offset == -1) + sprintf (str, " {v%i..v%i}, method+%i", vC, vC+vA-1, vB); + else + sprintf (str, " {v%i..v%i}, 0x%"PFMT64x, vC, vC+vA-1, offset); + } strcat (op->buf_asm, str); break; - case fmtopvXtBBBB: //FIXME: class & method must be a dex(r_bin) section + case fmtopvXtBBBB: vA = (int) (buf[1] & 0xf0)>>4; vB = (buf[3]<<8) | buf[2]; switch (vA) { @@ -263,10 +305,20 @@ static int dalvik_disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) { sprintf (str, " {}"); } strcat (op->buf_asm, str); - if (buf[0] == 0x24) // filled-new-array - sprintf (str, ", class+%i", vB); - else - sprintf (str, ", method+%i", vB); + if (buf[0] == 0x24) { // filled-new-array + offset = r_asm_get_offset(a, 'c', vB); + if (offset == -1) + sprintf (str, ", class+%i", vB); + else + sprintf (str, ", 0x%"PFMT64x, offset); + } else { + offset = r_asm_get_offset(a, 'm', vB); + if (offset == -1) + sprintf (str, ", method+%i", vB); + else + sprintf (str, ", 0x%"PFMT64x, offset); + + } strcat (op->buf_asm, str); break; case fmtoptinvokeI: // Any opcode has this formats diff --git a/libr/bin/format/dex/dex.h b/libr/bin/format/dex/dex.h index 23147cd9f2..4541be387e 100644 --- a/libr/bin/format/dex/dex.h +++ b/libr/bin/format/dex/dex.h @@ -44,6 +44,7 @@ struct r_bin_dex_obj_t { const char* file; struct r_buf_t* b; struct dex_header_t header; + ut32 *strings; }; struct r_bin_dex_str_t { diff --git a/libr/bin/p/bin_dex.c b/libr/bin/p/bin_dex.c index bd4b4293a3..db66f35257 100644 --- a/libr/bin/p/bin_dex.c +++ b/libr/bin/p/bin_dex.c @@ -54,12 +54,12 @@ static RList* strings(RBinArch *arch) { RList *ret = NULL; RBinString *ptr = NULL; struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj; - ut32 i, *string; + ut32 i; char buf[6]; int len; - string = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32)); - r_buf_read_at(bin->b, bin->header.strings_offset, (ut8*)string, + bin->strings = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32)); + r_buf_read_at(bin->b, bin->header.strings_offset, (ut8*)bin->strings, bin->header.strings_size * sizeof (ut32)); if (!(ret = r_list_new ())) return NULL; @@ -67,19 +67,19 @@ static RList* strings(RBinArch *arch) { for (i = 0; i < bin->header.strings_size; i++) { if (!(ptr = R_NEW (RBinString))) break; - r_buf_read_at (bin->b, string[i], (ut8*)&buf, 6); + r_buf_read_at (bin->b, bin->strings[i], (ut8*)&buf, 6); len = dex_read_uleb128 (buf); // len = R_BIN_SIZEOF_STRINGS-1; if (len>0 && len < R_BIN_SIZEOF_STRINGS) { - r_buf_read_at(bin->b, string[i]+1, (ut8*)&ptr->string, len); + //FIXME: size its uleb128 + r_buf_read_at(bin->b, bin->strings[i]+1, (ut8*)&ptr->string, len); ptr->string[(int) len]='\0'; - ptr->rva = ptr->offset = string[i]+1; + ptr->rva = ptr->offset = bin->strings[i]; ptr->size = len; ptr->ordinal = i+1; r_list_append (ret, ptr); } else eprintf ("dex_read_uleb128: invalid read\n"); } - free (string); return ret; } @@ -96,6 +96,7 @@ static RList* classes (RBinArch *arch) { for (i = 0; i < bin->header.class_size; i++) { r_buf_read_at (bin->b, (ut64) bin->header.class_offset, (ut8*)&entry, sizeof (struct dex_class_t)); +#if 0 eprintf ("ut32 class_id = %08x;\n", entry.class_id); eprintf ("ut32 access_flags = %08x;\n", entry.access_flags); eprintf ("ut32 super_class = %08x;\n", entry.super_class); @@ -104,18 +105,34 @@ static RList* classes (RBinArch *arch) { eprintf ("ut32 anotations_offset = %08x;\n", entry.anotations_offset); eprintf ("ut32 class_data_offset = %08x;\n", entry.class_data_offset); eprintf ("ut32 static_values_offset = %08x;\n", entry.static_values_offset); +#endif } - return ret; + return 0; //FIXME: This must be main offset } +//TODO static int getoffset (RBinArch *arch, int type, int idx) { struct r_bin_dex_obj_t *dex = arch->bin_obj; + switch (type) { - case 's': // symbol name - // dex->header.method_offset - return 0; // TODO: must be the offset to the ptr + case 'm': // methods + break; + case 'c': // class + break; + case 'f': // fields + break; + case 'o': // objects + break; + case 's': // strings + if (dex->header.strings_size > idx) { + printf ("Return 0x%x\n", dex->strings[idx]); + return dex->strings[idx]; + } + break; + case 't': // things + break; } - return 0; + return -1; } struct r_bin_plugin_t r_bin_plugin_dex = {