* Initial parse of dex files

- Load strings and methods
* Fix command 'r' parser
* Fix visual 'g' command without sections defined
This commit is contained in:
earada 2011-07-04 18:54:41 +02:00
parent 0b997374a0
commit a38c2ece6d
5 changed files with 131 additions and 32 deletions

View File

@ -18,6 +18,22 @@ struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf) {
bin->b = buf;
bin->size = buf->length;
r_buf_read_at (bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));
bin->strings = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32) + 1);
r_buf_read_at(bin->b, bin->header.strings_offset, (ut8*)bin->strings,
bin->header.strings_size * sizeof (ut32));
bin->methods = (struct dex_method_t *) malloc (bin->header.method_size *
sizeof (struct dex_method_t) + 1);
r_buf_read_at(bin->b, bin->header.method_offset, (ut8*)bin->methods,
bin->header.method_size * sizeof (struct dex_method_t));
bin->fields = (struct dex_field_t *) malloc (bin->header.fields_size *
sizeof (struct dex_field_t) + 1);
r_buf_read_at(bin->b, bin->header.fields_offset, (ut8*)bin->fields,
bin->header.fields_size * sizeof (struct dex_field_t));
return bin;
}
@ -44,6 +60,18 @@ int dex_read_uleb128 (const char *ptr) {
return result;
}
#define LEB_MAX_SIZE 6
int dex_uleb128_len (const char *ptr) {
int i, result = *(ptr++);
i=1;
while (result > 0x7f && i <= LEB_MAX_SIZE) {
result = *(ptr++);
i++;
}
return i;
}
#define SIG_EXTEND(X,Y) X = (X << Y) >> Y
int dex_read_sleb128 (const char *ptr) {
int cur, result = *(ptr++);

View File

@ -28,6 +28,24 @@ struct dex_header_t {
ut32 data_offset;
};
struct dex_proto_t {
ut32 shorty_id;
ut32 return_type_id;
ut32 params_id;
};
struct dex_field_t {
ut8 class_id;
ut8 type_id;
ut32 name_id;
};
struct dex_method_t {
ut8 class_id;
ut8 proto_id;
ut32 name_id;
};
struct dex_class_t {
ut32 class_id;
ut32 access_flags;
@ -41,10 +59,12 @@ struct dex_class_t {
struct r_bin_dex_obj_t {
int size;
const char* file;
struct r_buf_t* b;
const char *file;
struct r_buf_t *b;
struct dex_header_t header;
ut32 *strings;
struct dex_method_t *methods;
struct dex_field_t *fields;
};
struct r_bin_dex_str_t {
@ -56,7 +76,7 @@ struct r_bin_dex_str_t {
};
char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin);
struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf);
struct r_bin_dex_obj_t *r_bin_dex_new_buf(struct r_buf_t *buf);
struct r_bin_dex_str_t *r_bin_dex_get_strings (struct r_bin_dex_obj_t* bin);
int dex_read_uleb128 (const char *ptr);

View File

@ -46,11 +46,11 @@ static RBinInfo * info(RBinArch *arch) {
strncpy (ret->arch, "dalvik", R_BIN_SIZEOF_STRINGS);
ret->bits = 32;
ret->big_endian= 0;
ret->dbg_info = 4 | 8; /* LineNums | Syms */
ret->dbg_info = 1 | 4 | 8; /* Stripped | LineNums | Syms */
return ret;
}
static RList* strings(RBinArch *arch) {
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;
@ -58,9 +58,6 @@ static RList* strings(RBinArch *arch) {
char buf[6];
int len;
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;
ret->free = free;
@ -71,8 +68,8 @@ static RList* strings(RBinArch *arch) {
len = dex_read_uleb128 (buf);
// len = R_BIN_SIZEOF_STRINGS-1;
if (len>0 && len < R_BIN_SIZEOF_STRINGS) {
//FIXME: size its uleb128
r_buf_read_at(bin->b, bin->strings[i]+1, (ut8*)&ptr->string, len);
r_buf_read_at(bin->b, bin->strings[i]+dex_uleb128_len (buf),
(ut8*)&ptr->string, len);
ptr->string[(int) len]='\0';
ptr->rva = ptr->offset = bin->strings[i];
ptr->size = len;
@ -83,6 +80,56 @@ static RList* strings(RBinArch *arch) {
return ret;
}
static RList* methods (RBinArch *arch) {
RList *ret = NULL;
struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj;
int i, j, len;
char buf[6];
RBinSymbol *ptr;
if (!(ret = r_list_new ()))
return NULL;
ret->free = free;
for (i = 0; i<bin->header.method_size; i++) {
if (!(ptr = R_NEW (RBinSymbol)))
break;
r_buf_read_at (bin->b, bin->strings[bin->methods[i].name_id], (ut8*)&buf, 6);
strncpy (ptr->name, "method.", 7);
len = dex_read_uleb128 (buf);
r_buf_read_at(bin->b, bin->strings[bin->methods[i].name_id]+
dex_uleb128_len (buf), (ut8*)&ptr->name+7, len);
ptr->name[(int) len+7]='\0';
strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->type, "FUNC", R_BIN_SIZEOF_STRINGS);
ptr->rva = ptr->offset = bin->header.method_offset +
(sizeof (struct dex_method_t) * i);
ptr->size = sizeof (struct dex_method_t);
ptr->ordinal = i+1;
r_list_append (ret, ptr);
}
j=i;
for (i = 0; i<bin->header.fields_size; i++) {
if (!(ptr = R_NEW (RBinSymbol)))
break;
r_buf_read_at (bin->b, bin->strings[bin->fields[i].name_id], (ut8*)&buf, 6);
strncpy (ptr->name, "field.", 6);
len = dex_read_uleb128 (buf);
r_buf_read_at(bin->b, bin->strings[bin->fields[i].name_id]+
dex_uleb128_len (buf), (ut8*)&ptr->name+6, len);
ptr->name[(int) len+6]='\0';
strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->type, "FUNC", R_BIN_SIZEOF_STRINGS);
ptr->rva = ptr->offset = bin->header.fields_offset +
(sizeof (struct dex_field_t) * i);
ptr->size = sizeof (struct dex_field_t);
ptr->ordinal = j+i+1;
r_list_append (ret, ptr);
}
return ret;
}
//TODO
static RList* classes (RBinArch *arch) {
RList *ret = NULL;
@ -104,7 +151,7 @@ static RList* classes (RBinArch *arch) {
eprintf ("ut32 source_file = %08x;\n", entry.source_file);
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);
eprintf ("ut32 static_values_offset = %08x;\n\n", entry.static_values_offset);
#endif
}
return 0; //FIXME: This must be main offset
@ -116,18 +163,20 @@ static int getoffset (RBinArch *arch, int type, int idx) {
switch (type) {
case 'm': // methods
if (dex->header.method_size > idx)
return dex->header.method_offset+(sizeof (struct dex_method_t)*idx);
break;
case 'c': // class
break;
case 'f': // fields
if (dex->header.fields_size > idx)
return dex->header.fields_offset+(sizeof (struct dex_field_t)*idx);
break;
case 'o': // objects
break;
case 's': // strings
if (dex->header.strings_size > idx) {
printf ("Return 0x%x\n", dex->strings[idx]);
if (dex->header.strings_size > idx)
return dex->strings[idx];
}
break;
case 't': // things
break;
@ -147,7 +196,7 @@ struct r_bin_plugin_t r_bin_plugin_dex = {
.binsym = NULL,
.entries = &classes,
.sections = NULL,
.symbols = NULL,
.symbols = &methods,
.imports = NULL,
.strings = &strings,
.info = &info,

View File

@ -2926,23 +2926,23 @@ static int cmd_resize(void *data, const char *input) {
int grow;
oldsize = core->file->size;
while (*input==' ')
input++;
switch (*input) {
case ' ':
newsize = r_num_math (core->num, input+1);
break;
case '+':
case '-':
delta = (st64)r_num_math (NULL, input);
newsize = oldsize + delta;
break;
case '?':
default:
r_cons_printf (
"Usage: r[+-][ size]\n"
" r size expand or truncate file to given size\n"
" r-num remove num bytes, move following data down\n"
" r+num insert num bytes, move following data up\n");
return R_TRUE;
case '+':
case '-':
delta = (st64)r_num_math (NULL, input);
newsize = oldsize + delta;
break;
case '?':
r_cons_printf (
"Usage: r[+-][ size]\n"
" r size expand or truncate file to given size\n"
" r-num remove num bytes, move following data down\n"
" r+num insert num bytes, move following data up\n");
return R_TRUE;
default:
newsize = r_num_math (core->num, input+1);
}
grow = (newsize > oldsize);

View File

@ -189,10 +189,12 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
case 'g':
if (core->io->va) {
ut64 offset = r_io_section_get_vaddr (core->io, 0);
if (offset == -1)
offset = 0;
r_core_seek (core, offset, 1);
r_io_sundo_push (core->io);
} else
r_core_cmd (core, "s 0", 0);
r_io_sundo_push (core->io);
break;
case 'G':
if (core->io->va) {