* Handle strings meta info in dalvik disassemble

This commit is contained in:
earada 2011-06-26 22:42:34 +02:00
parent ef375bf85d
commit 21a9405a81
3 changed files with 112 additions and 42 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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 = {