mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-03 12:12:06 +00:00
* Handle strings meta info in dalvik disassemble
This commit is contained in:
parent
ef375bf85d
commit
21a9405a81
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user