mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-02 18:27:18 +00:00
* 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:
parent
0b997374a0
commit
a38c2ece6d
@ -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++);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user