Rizin
unix-like reverse engineering framework and cli tools
dex.c File Reference
#include "dex.h"
#include <rz_util.h>

Go to the source code of this file.

Classes

struct  dex_access_flags_readable_t
 

Macros

#define DEX_INVALID_CLASS   "Lunknown_class;"
 
#define DEX_INVALID_METHOD   "unknown_method"
 
#define read_le_bits_or_fail(bits, buf, val, fail)
 
#define read_le_at_bits_or_fail(bits, buf, val, offset, fail)
 
#define read_le32_or_fail(buf, val, fail)   read_le_bits_or_fail(32, buf, val, fail)
 
#define read_le16_or_fail(buf, val, fail)   read_le_bits_or_fail(16, buf, val, fail)
 
#define read_le32_at_or_fail(buf, val, offset, fail)   read_le_at_bits_or_fail(32, buf, val, offset, fail)
 
#define read_le16_at_or_fail(buf, val, offset, fail)   read_le_at_bits_or_fail(16, buf, val, offset, fail)
 
#define dex_is_static(a)   (a & ACCESS_FLAG_STATIC)
 
#define dex_is_varargs(a)   (a & ACCESS_FLAG_VARARGS)
 
#define dex_fail_if_bad_ids(name, z, s, g)
 
#define CLASS_ACCESS_FLAGS_SIZE   18
 
#define dex_field_id_free   free
 
#define dex_method_id_free   free
 

Typedefs

typedef struct dex_access_flags_readable_t DexAccessFlagsReadable
 

Functions

static void dex_string_free (DexString *string)
 
static DexStringdex_string_new (RzBuffer *buf, ut64 offset, st64 *pread)
 
static void dex_proto_id_free (DexProtoId *string)
 
static DexProtoIddex_proto_id_new (RzBuffer *buf, ut64 offset)
 
static DexFieldIddex_field_id_new (RzBuffer *buf, ut64 offset)
 
static DexMethodIddex_method_id_new (RzBuffer *buf, ut64 offset)
 
static void dex_class_def_free (DexClassDef *class_def)
 
static DexEncodedFielddex_new_encoded_field (RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first)
 
static DexEncodedMethoddex_new_encoded_method (RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first, RzPVector *method_ids)
 
static DexClassDefdex_class_def_new (RzBuffer *buf, ut64 offset, ut64 base, RzPVector *method_ids)
 
static void dex_resolve_virtual_method_code (RzBinDex *dex, DexMethodId *to_resolve, ut32 superclass_idx)
 
static void dex_resolve_all_virtual_methods (RzBinDex *dex)
 
static bool dex_create_relocations (RzBinDex *dex)
 
static bool dex_parse (RzBinDex *dex, ut64 base, RzBuffer *buf)
 
RZ_API void rz_bin_dex_free (RZ_NULLABLE RzBinDex *dex)
 Frees a RzBinDex struct. More...
 
RZ_API RZ_OWN RzBinDexrz_bin_dex_new (RZ_NONNULL RzBuffer *buf, ut64 base, RZ_NONNULL Sdb *kv)
 Parses the dex file and returns a RzBinDex struct. More...
 
RZ_API RZ_OWN char * rz_bin_dex_access_flags_readable (ut32 access_flags)
 
RZ_API RZ_OWN RzListrz_bin_dex_strings (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinString*> containing the dex strings. More...
 
static DexStringdex_resolve_string_id_native (RzBinDex *dex, ut32 string_idx)
 
static char * dex_resolve_string_id (RzBinDex *dex, ut32 string_idx)
 
static char * dex_resolve_type_id (RzBinDex *dex, ut32 type_idx)
 
static char * dex_resolve_proto_id (RzBinDex *dex, const char *name, ut32 proto_idx, bool varargs)
 
static ut64 dex_access_flags_to_bin_flags (ut64 access_flags)
 
static char * dex_resolve_library (const char *library)
 
static RzBinSymboldex_method_to_symbol (RzBinDex *dex, DexEncodedMethod *encoded_method, DexMethodId *method_id, bool is_imported)
 
static RzListdex_resolve_methods_in_class (RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
 
static RzBinFielddex_field_to_bin_field (RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_static)
 
static RzListdex_resolve_fields_in_class (RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
 
static RzBinSymboldex_field_to_symbol (RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_imported)
 
static RzListdex_resolve_fields_in_class_as_symbols (RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
 
static void free_rz_bin_class (RzBinClass *bclass)
 
RZ_API RZ_OWN RzListrz_bin_dex_classes (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinClass*> containing the dex classes. More...
 
static RzBinSectionsection_new (const char *name, ut32 perm, ut32 size, ut64 paddr, ut64 vaddr)
 
RZ_API RZ_OWN RzListrz_bin_dex_sections (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinSection*> containing the dex sections. More...
 
RZ_API RZ_OWN RzListrz_bin_dex_fields (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinField*> containing the dex fields. More...
 
RZ_API RZ_OWN RzListrz_bin_dex_symbols (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinSymbol*> containing the dex symbols. More...
 
RZ_API RZ_OWN RzListrz_bin_dex_imports (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinImport*> containing the dex imports. More...
 
static int compare_strings (const void *a, const void *b)
 
RZ_API RZ_OWN RzListrz_bin_dex_libraries (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<char*> containing the dex libraries. More...
 
static bool dex_resolve_symbol_in_class_methods (RzBinDex *dex, DexClassDef *class_def, RzBinSpecialSymbol resolve, ut64 *paddr, ut64 *vaddr)
 
RZ_API RZ_OWN RzBinAddrrz_bin_dex_resolve_symbol (RZ_NONNULL RzBinDex *dex, RzBinSpecialSymbol resolve)
 Returns a RzBinAddr pointer containing the resolved RzBinSpecialSymbol. More...
 
static RzListdex_resolve_entrypoints_in_class (RzBinDex *dex, DexClassDef *class_def)
 
RZ_API RZ_OWN RzListrz_bin_dex_entrypoints (RZ_NONNULL RzBinDex *dex)
 Returns a RzList<RzBinAddr*> containing the dex entripoints. More...
 
RZ_API RZ_BORROW RzBufferrz_bin_dex_relocations (RZ_NONNULL RzBinDex *dex)
 
RZ_API RZ_OWN char * rz_bin_dex_resolve_method_by_idx (RZ_NONNULL RzBinDex *dex, ut32 method_idx)
 Returns the resolved string linked to the given method id. More...
 
RZ_API RZ_OWN char * rz_bin_dex_resolve_field_by_idx (RZ_NONNULL RzBinDex *dex, ut32 field_idx)
 Returns the resolved string linked to the given field id. More...
 
RZ_API ut64 rz_bin_dex_resolve_string_offset_by_idx (RZ_NONNULL RzBinDex *dex, ut32 string_idx)
 Returns the resolved offset linked to the given string id. More...
 
RZ_API ut64 rz_bin_dex_resolve_type_id_offset_by_idx (RZ_NONNULL RzBinDex *dex, ut32 type_idx)
 Returns the resolved offset linked to the given type id. More...
 
RZ_API ut64 rz_bin_dex_resolve_method_offset_by_idx (RZ_NONNULL RzBinDex *dex, ut32 method_idx)
 Returns the resolved offset linked to the given method id. More...
 
RZ_API RZ_OWN char * rz_bin_dex_resolve_type_id_by_idx (RZ_NONNULL RzBinDex *dex, ut32 type_idx)
 Returns the resolved string linked to the given type id. More...
 
RZ_API RZ_OWN char * rz_bin_dex_resolve_string_by_idx (RZ_NONNULL RzBinDex *dex, ut32 string_idx)
 Returns the resolved string linked to the given string id. More...
 
RZ_API RZ_OWN char * rz_bin_dex_resolve_class_by_idx (RZ_NONNULL RzBinDex *dex, ut32 class_idx)
 Returns the resolved string linked to the given class id. More...
 
RZ_API RZ_OWN char * rz_bin_dex_resolve_proto_by_idx (RZ_NONNULL RzBinDex *dex, ut32 proto_idx)
 Returns the resolved string linked to the given prototype id. More...
 
RZ_API void rz_bin_dex_checksum (RZ_NONNULL RzBinDex *dex, RZ_NONNULL RzBinHash *hash)
 Sets the RzBinHash dex checksum (adler32) More...
 
RZ_API void rz_bin_dex_sha1 (RZ_NONNULL RzBinDex *dex, RZ_NONNULL RzBinHash *hash)
 Sets the RzBinHash dex digest (sha1) More...
 
RZ_API RZ_OWN char * rz_bin_dex_version (RZ_NONNULL RzBinDex *dex)
 Returns the dex version (string format) More...
 
RZ_API ut64 rz_bin_dex_debug_info (RZ_NONNULL RzBinDex *dex)
 Returns the dex debug info RzBin values. More...
 

Variables

static const DexAccessFlagsReadable access_flags_list [CLASS_ACCESS_FLAGS_SIZE]
 

Macro Definition Documentation

◆ CLASS_ACCESS_FLAGS_SIZE

#define CLASS_ACCESS_FLAGS_SIZE   18

Definition at line 47 of file dex.c.

◆ dex_fail_if_bad_ids

#define dex_fail_if_bad_ids (   name,
  z,
  s,
  g 
)
Value:
do { \
ut64 end = name##_offset; \
end += name##_size * (z); \
if (end >= (s)) { \
goto g; \
} \
} while (0)
struct @667 g
static RzSocket * s
Definition: rtr.c:28
Definition: z80asm.h:102

Definition at line 38 of file dex.c.

◆ dex_field_id_free

#define dex_field_id_free   free

Definition at line 147 of file dex.c.

◆ DEX_INVALID_CLASS

#define DEX_INVALID_CLASS   "Lunknown_class;"

Definition at line 8 of file dex.c.

◆ DEX_INVALID_METHOD

#define DEX_INVALID_METHOD   "unknown_method"

Definition at line 9 of file dex.c.

◆ dex_is_static

#define dex_is_static (   a)    (a & ACCESS_FLAG_STATIC)

Definition at line 35 of file dex.c.

◆ dex_is_varargs

#define dex_is_varargs (   a)    (a & ACCESS_FLAG_VARARGS)

Definition at line 36 of file dex.c.

◆ dex_method_id_free

#define dex_method_id_free   free

Definition at line 165 of file dex.c.

◆ read_le16_at_or_fail

#define read_le16_at_or_fail (   buf,
  val,
  offset,
  fail 
)    read_le_at_bits_or_fail(16, buf, val, offset, fail)

Definition at line 33 of file dex.c.

◆ read_le16_or_fail

#define read_le16_or_fail (   buf,
  val,
  fail 
)    read_le_bits_or_fail(16, buf, val, fail)

Definition at line 31 of file dex.c.

◆ read_le32_at_or_fail

#define read_le32_at_or_fail (   buf,
  val,
  offset,
  fail 
)    read_le_at_bits_or_fail(32, buf, val, offset, fail)

Definition at line 32 of file dex.c.

◆ read_le32_or_fail

#define read_le32_or_fail (   buf,
  val,
  fail 
)    read_le_bits_or_fail(32, buf, val, fail)

Definition at line 30 of file dex.c.

◆ read_le_at_bits_or_fail

#define read_le_at_bits_or_fail (   bits,
  buf,
  val,
  offset,
  fail 
)
Value:
do { \
if (!rz_buf_read_le##bits##_at(buf, offset, &val)) { \
goto fail; \
} \
} while (0)
ut16 val
Definition: armass64_const.h:6
int bits(struct state *s, int need)
Definition: blast.c:72
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
#define fail(test)
Definition: tests.h:29

Definition at line 23 of file dex.c.

◆ read_le_bits_or_fail

#define read_le_bits_or_fail (   bits,
  buf,
  val,
  fail 
)
Value:
do { \
if (!rz_buf_read_le##bits(buf, &val)) { \
goto fail; \
} \
} while (0)

Definition at line 16 of file dex.c.

Typedef Documentation

◆ DexAccessFlagsReadable

Function Documentation

◆ compare_strings()

static int compare_strings ( const void *  a,
const void *  b 
)
static

Definition at line 1513 of file dex.c.

1513  {
1514  return strcmp((const char *)a, (const char *)b);
1515 }
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41

References a, and b.

Referenced by rz_bin_dex_libraries().

◆ dex_access_flags_to_bin_flags()

static ut64 dex_access_flags_to_bin_flags ( ut64  access_flags)
static

Definition at line 836 of file dex.c.

836  {
837  ut64 flags = 0;
838  if (access_flags & ACCESS_FLAG_PUBLIC) {
840  }
841  if (access_flags & ACCESS_FLAG_PRIVATE) {
843  }
844  if (access_flags & ACCESS_FLAG_PROTECTED) {
846  }
847  if (access_flags & ACCESS_FLAG_STATIC) {
849  }
850  if (access_flags & ACCESS_FLAG_FINAL) {
852  }
853  if (access_flags & ACCESS_FLAG_SYNCHRONIZED) {
855  }
856  if (access_flags & ACCESS_FLAG_BRIDGE) {
858  }
859  if (access_flags & ACCESS_FLAG_VARARGS) {
861  }
862  if (access_flags & ACCESS_FLAG_NATIVE) {
864  }
865  // RZ_BIN_METH_INTERFACE does not exists
866  // if (access_flags & ACCESS_FLAG_INTERFACE) {
867  // flags |= RZ_BIN_METH_INTERFACE;
868  //}
869  if (access_flags & ACCESS_FLAG_ABSTRACT) {
871  }
872  if (access_flags & ACCESS_FLAG_STRICT) {
874  }
875  if (access_flags & ACCESS_FLAG_SYNTHETIC) {
877  }
878  // RZ_BIN_METH_ANNOTATION does not exists
879  // if (access_flags & ACCESS_FLAG_ANNOTATION) {
880  // flags |= RZ_BIN_METH_ANNOTATION;
881  //}
882  // RZ_BIN_METH_ENUM does not exists
883  // if (access_flags & ACCESS_FLAG_ENUM) {
884  // flags |= RZ_BIN_METH_ENUM;
885  //}
886  // RZ_BIN_METH_MODULE does not exists
887  // if (access_flags & ACCESS_FLAG_MODULE) {
888  // flags |= RZ_BIN_METH_MODULE;
889  //}
890  if (access_flags & ACCESS_FLAG_CONSTRUCTOR) {
892  }
893  if (access_flags & ACCESS_FLAG_DECLARED_SYNCHRONIZED) {
895  }
896  return flags;
897 }
@ ACCESS_FLAG_SYNTHETIC
Definition: dex.h:53
@ ACCESS_FLAG_CONSTRUCTOR
Definition: dex.h:57
@ ACCESS_FLAG_SYNCHRONIZED
Definition: dex.h:46
@ ACCESS_FLAG_VARARGS
Definition: dex.h:48
@ ACCESS_FLAG_DECLARED_SYNCHRONIZED
Definition: dex.h:58
@ ACCESS_FLAG_NATIVE
Definition: dex.h:49
@ ACCESS_FLAG_PRIVATE
Definition: dex.h:42
@ ACCESS_FLAG_PROTECTED
Definition: dex.h:43
@ ACCESS_FLAG_STATIC
Definition: dex.h:44
@ ACCESS_FLAG_BRIDGE
Definition: dex.h:47
@ ACCESS_FLAG_STRICT
Definition: dex.h:52
@ ACCESS_FLAG_ABSTRACT
Definition: dex.h:51
@ ACCESS_FLAG_FINAL
Definition: dex.h:45
@ ACCESS_FLAG_PUBLIC
Definition: dex.h:41
#define RZ_BIN_METH_CONSTRUCTOR
Definition: rz_bin.h:103
#define RZ_BIN_METH_SYNCHRONIZED
Definition: rz_bin.h:96
#define RZ_BIN_METH_PUBLIC
Definition: rz_bin.h:85
#define RZ_BIN_METH_VARARGS
Definition: rz_bin.h:99
#define RZ_BIN_METH_SYNTHETIC
Definition: rz_bin.h:100
#define RZ_BIN_METH_STRICT
Definition: rz_bin.h:101
#define RZ_BIN_METH_ABSTRACT
Definition: rz_bin.h:95
#define RZ_BIN_METH_DECLARED_SYNCHRONIZED
Definition: rz_bin.h:104
#define RZ_BIN_METH_FINAL
Definition: rz_bin.h:91
#define RZ_BIN_METH_BRIDGE
Definition: rz_bin.h:98
#define RZ_BIN_METH_STATIC
Definition: rz_bin.h:84
#define RZ_BIN_METH_PRIVATE
Definition: rz_bin.h:86
#define RZ_BIN_METH_PROTECTED
Definition: rz_bin.h:87
#define RZ_BIN_METH_NATIVE
Definition: rz_bin.h:97
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References ACCESS_FLAG_ABSTRACT, ACCESS_FLAG_BRIDGE, ACCESS_FLAG_CONSTRUCTOR, ACCESS_FLAG_DECLARED_SYNCHRONIZED, ACCESS_FLAG_FINAL, ACCESS_FLAG_NATIVE, ACCESS_FLAG_PRIVATE, ACCESS_FLAG_PROTECTED, ACCESS_FLAG_PUBLIC, ACCESS_FLAG_STATIC, ACCESS_FLAG_STRICT, ACCESS_FLAG_SYNCHRONIZED, ACCESS_FLAG_SYNTHETIC, ACCESS_FLAG_VARARGS, flags, RZ_BIN_METH_ABSTRACT, RZ_BIN_METH_BRIDGE, RZ_BIN_METH_CONSTRUCTOR, RZ_BIN_METH_DECLARED_SYNCHRONIZED, RZ_BIN_METH_FINAL, RZ_BIN_METH_NATIVE, RZ_BIN_METH_PRIVATE, RZ_BIN_METH_PROTECTED, RZ_BIN_METH_PUBLIC, RZ_BIN_METH_STATIC, RZ_BIN_METH_STRICT, RZ_BIN_METH_SYNCHRONIZED, RZ_BIN_METH_SYNTHETIC, RZ_BIN_METH_VARARGS, and ut64().

Referenced by dex_field_to_bin_field(), dex_field_to_symbol(), and dex_method_to_symbol().

◆ dex_class_def_free()

static void dex_class_def_free ( DexClassDef class_def)
static

Definition at line 183 of file dex.c.

183  {
184  if (!class_def) {
185  return;
186  }
187  rz_list_free(class_def->static_fields);
188  rz_list_free(class_def->instance_fields);
189  rz_list_free(class_def->direct_methods);
190  rz_list_free(class_def->virtual_methods);
191  free(class_def->interfaces);
192  free(class_def);
193 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RzList * instance_fields
Definition: dex.h:154
RzList * direct_methods
Definition: dex.h:155
ut16 * interfaces
Definition: dex.h:151
RzList * virtual_methods
Definition: dex.h:156
RzList * static_fields
Definition: dex.h:153

References dex_class_def_t::direct_methods, free(), dex_class_def_t::instance_fields, dex_class_def_t::interfaces, rz_list_free(), dex_class_def_t::static_fields, and dex_class_def_t::virtual_methods.

Referenced by dex_class_def_new(), and rz_bin_dex_new().

◆ dex_class_def_new()

static DexClassDef* dex_class_def_new ( RzBuffer buf,
ut64  offset,
ut64  base,
RzPVector method_ids 
)
static

Definition at line 262 of file dex.c.

262  {
263  DexClassDef *class_def = RZ_NEW0(DexClassDef);
264  if (!class_def) {
265  return NULL;
266  }
267 
268  ut64 static_fields_size = 0;
269  ut64 instance_fields_size = 0;
270  ut64 direct_methods_size = 0;
271  ut64 virtual_methods_size = 0;
272  ut64 diff_value_prev;
273 
274  class_def->static_fields = /* */ rz_list_newf((RzListFree)free);
276  class_def->direct_methods = /* */ rz_list_newf((RzListFree)free);
278 
279  read_le16_or_fail(buf, class_def->class_idx, dex_class_def_new_fail);
280  read_le16_or_fail(buf, class_def->_padding1, dex_class_def_new_fail);
281  read_le32_or_fail(buf, class_def->access_flags, dex_class_def_new_fail);
282  read_le16_or_fail(buf, class_def->superclass_idx, dex_class_def_new_fail);
283  read_le16_or_fail(buf, class_def->_padding2, dex_class_def_new_fail);
284  read_le32_or_fail(buf, class_def->interfaces_offset, dex_class_def_new_fail);
285  read_le32_or_fail(buf, class_def->source_file_idx, dex_class_def_new_fail);
286  read_le32_or_fail(buf, class_def->annotations_offset, dex_class_def_new_fail);
287  read_le32_or_fail(buf, class_def->class_data_offset, dex_class_def_new_fail);
288  read_le32_or_fail(buf, class_def->static_values_offset, dex_class_def_new_fail);
289  class_def->offset = offset;
290 
291  if (class_def->interfaces_offset > 0) {
292  if (rz_buf_seek(buf, class_def->interfaces_offset, RZ_BUF_SET) < 0) {
293  goto dex_class_def_new_fail;
294  }
295  read_le32_or_fail(buf, class_def->n_interfaces, dex_class_def_new_fail);
296  if (class_def->n_interfaces > 0) {
297  class_def->interfaces = RZ_NEWS0(ut16, class_def->n_interfaces);
298  if (!class_def->interfaces) {
299  goto dex_class_def_new_fail;
300  }
301  for (ut32 i = 0; i < class_def->n_interfaces; ++i) {
302  read_le16_or_fail(buf, class_def->interfaces[i], dex_class_def_new_fail);
303  }
304  }
305  }
306 
307  if (!class_def->class_data_offset) {
308  return class_def;
309  }
310 
311  if (rz_buf_seek(buf, class_def->class_data_offset, RZ_BUF_SET) < 0) {
312  goto dex_class_def_new_fail;
313  }
314 
315  rz_buf_uleb128(buf, &static_fields_size);
316  rz_buf_uleb128(buf, &instance_fields_size);
317  rz_buf_uleb128(buf, &direct_methods_size);
318  rz_buf_uleb128(buf, &virtual_methods_size);
319 
320  for (ut64 i = 0; i < static_fields_size; ++i) {
321  DexEncodedField *encoded_field = dex_new_encoded_field(buf, base, &diff_value_prev, i < 1);
322  if (!encoded_field || !rz_list_append(class_def->static_fields, encoded_field)) {
323  free(encoded_field);
324  goto dex_class_def_new_fail;
325  }
326  }
327 
328  for (ut64 i = 0; i < instance_fields_size; ++i) {
329  DexEncodedField *encoded_field = dex_new_encoded_field(buf, base, &diff_value_prev, i < 1);
330  if (!encoded_field || !rz_list_append(class_def->instance_fields, encoded_field)) {
331  free(encoded_field);
332  goto dex_class_def_new_fail;
333  }
334  }
335 
336  for (ut64 i = 0; i < direct_methods_size; ++i) {
337  DexEncodedMethod *encoded_method = dex_new_encoded_method(buf, base, &diff_value_prev, i < 1, method_ids);
338  if (!encoded_method || !rz_list_append(class_def->direct_methods, encoded_method)) {
339  free(encoded_method);
340  goto dex_class_def_new_fail;
341  }
342  }
343 
344  for (ut64 i = 0; i < virtual_methods_size; ++i) {
345  DexEncodedMethod *encoded_method = dex_new_encoded_method(buf, base, &diff_value_prev, i < 1, method_ids);
346  if (!encoded_method || !rz_list_append(class_def->virtual_methods, encoded_method)) {
347  free(encoded_method);
348  goto dex_class_def_new_fail;
349  }
350  }
351 
352  return class_def;
353 
354 dex_class_def_new_fail:
355  dex_class_def_free(class_def);
356  return NULL;
357 }
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
uint32_t ut32
static DexEncodedField * dex_new_encoded_field(RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first)
Definition: dex.c:195
#define read_le32_or_fail(buf, val, fail)
Definition: dex.c:30
static DexEncodedMethod * dex_new_encoded_method(RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first, RzPVector *method_ids)
Definition: dex.c:216
static void dex_class_def_free(DexClassDef *class_def)
Definition: dex.c:183
#define read_le16_or_fail(buf, val, fail)
Definition: dex.c:31
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
RZ_API st64 rz_buf_uleb128(RZ_NONNULL RzBuffer *buffer, RZ_NONNULL ut64 *value)
Decodes ULEB128 from RzBuffer.
Definition: buf.c:1353
#define RZ_BUF_SET
Definition: rz_buf.h:14
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
ut32 class_data_offset
Definition: dex.h:146
ut32 n_interfaces
Definition: dex.h:150
ut32 access_flags
Definition: dex.h:140
ut32 source_file_idx
Definition: dex.h:144
ut32 annotations_offset
Definition: dex.h:145
ut32 interfaces_offset
Definition: dex.h:143
ut32 static_values_offset
Definition: dex.h:147
ut16 _padding2
Definition: dex.h:142
ut16 _padding1
Definition: dex.h:139
ut64 offset
Definition: dex.h:148
ut16 superclass_idx
Definition: dex.h:141
ut16 class_idx
Definition: dex.h:138

References dex_class_def_t::_padding1, dex_class_def_t::_padding2, dex_class_def_t::access_flags, dex_class_def_t::annotations_offset, dex_class_def_t::class_data_offset, dex_class_def_t::class_idx, dex_class_def_free(), dex_new_encoded_field(), dex_new_encoded_method(), dex_class_def_t::direct_methods, free(), i, dex_class_def_t::instance_fields, dex_class_def_t::interfaces, dex_class_def_t::interfaces_offset, dex_class_def_t::n_interfaces, NULL, dex_class_def_t::offset, read_le16_or_fail, read_le32_or_fail, rz_buf_seek(), RZ_BUF_SET, rz_buf_uleb128(), rz_list_append(), rz_list_newf(), RZ_NEW0, RZ_NEWS0, dex_class_def_t::source_file_idx, dex_class_def_t::static_fields, dex_class_def_t::static_values_offset, dex_class_def_t::superclass_idx, ut64(), and dex_class_def_t::virtual_methods.

Referenced by dex_parse().

◆ dex_create_relocations()

static bool dex_create_relocations ( RzBinDex dex)
static

Definition at line 393 of file dex.c.

393  {
394  void **iter_p0;
395  RzListIter *iter_l;
396  DexClassDef *class_def;
397  DexEncodedMethod *encoded_method = NULL;
398  DexMethodId *method_id = NULL;
399 
400  dex->relocs_size = 0;
401  rz_pvector_foreach (dex->method_ids, iter_p0) {
402  method_id = (DexMethodId *)*iter_p0;
403  if (method_id->code_offset) {
404  continue;
405  }
406  // patch the imported method.
407  method_id->code_offset = dex->relocs_offset + dex->relocs_size;
408  method_id->code_size = 2;
409  dex->relocs_size += 2;
410  }
411 
412  // sync classes with method_ids
413  rz_pvector_foreach (dex->class_defs, iter_p0) {
414  class_def = (DexClassDef *)*iter_p0;
415  rz_list_foreach (class_def->direct_methods, iter_l, encoded_method) {
416  if (encoded_method->code_offset) {
417  continue;
418  }
419  method_id = NULL;
420  if (encoded_method->method_idx < rz_pvector_len(dex->method_ids)) {
421  method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
422  if (method_id->code_offset) {
423  encoded_method->code_offset = method_id->code_offset;
424  encoded_method->code_size = method_id->code_size;
425  continue;
426  }
427  }
428 
429  // patch the imported method.
430  encoded_method->code_offset = dex->relocs_offset + dex->relocs_size;
431  encoded_method->code_size = 2;
432  dex->relocs_size += 2;
433  if (method_id) {
434  method_id->code_offset = encoded_method->code_offset;
435  method_id->code_size = encoded_method->code_size;
436  }
437  }
438 
439  rz_list_foreach (class_def->virtual_methods, iter_l, encoded_method) {
440  if (encoded_method->code_offset) {
441  continue;
442  }
443  method_id = NULL;
444  if (encoded_method->method_idx < rz_pvector_len(dex->method_ids)) {
445  method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
446  if (method_id->code_offset) {
447  encoded_method->code_offset = method_id->code_offset;
448  encoded_method->code_size = method_id->code_size;
449  continue;
450  }
451  }
452 
453  // patch the imported method.
454  encoded_method->code_offset = dex->relocs_offset + dex->relocs_size;
455  encoded_method->code_size = 2;
456  dex->relocs_size += 2;
457  if (method_id) {
458  method_id->code_offset = encoded_method->code_offset;
459  method_id->code_size = encoded_method->code_size;
460  }
461  }
462  }
463 
464  if (dex->relocs_size < 1) {
465  return true;
466  }
467  dex->relocs_code = malloc(dex->relocs_size);
468  if (!dex->relocs_code) {
469  return false;
470  }
471  for (ut32 i = 0; i < dex->relocs_size; i += 2) {
472  dex->relocs_code[i] = 0x0e;
473  dex->relocs_code[i + 1] = 0x00;
474  }
476  return dex->relocs_buffer;
477 }
void * malloc(size_t size)
Definition: malloc.c:123
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
ut64 code_offset
Definition: dex.h:126
ut64 code_size
Definition: dex.h:104
ut64 code_offset
Definition: dex.h:103
ut64 relocs_offset
Definition: dex.h:198
ut32 relocs_size
Definition: dex.h:199
ut8 * relocs_code
Definition: dex.h:200
RzPVector * method_ids
Definition: dex.h:193
RzPVector * class_defs
Definition: dex.h:194
RzBuffer * relocs_buffer
Definition: dex.h:201

References dex_t::class_defs, dex_method_id_t::code_offset, dex_encoded_method_t::code_offset, dex_method_id_t::code_size, dex_encoded_method_t::code_size, dex_class_def_t::direct_methods, i, malloc(), dex_t::method_ids, dex_encoded_method_t::method_idx, NULL, dex_t::relocs_buffer, dex_t::relocs_code, dex_t::relocs_offset, dex_t::relocs_size, rz_buf_new_with_bytes(), rz_pvector_at(), rz_pvector_foreach, rz_pvector_len(), and dex_class_def_t::virtual_methods.

Referenced by dex_parse().

◆ dex_field_id_new()

static DexFieldId* dex_field_id_new ( RzBuffer buf,
ut64  offset 
)
static

Definition at line 148 of file dex.c.

148  {
150  if (!field_id) {
151  return NULL;
152  }
153 
154  read_le16_or_fail(buf, field_id->class_idx, dex_field_id_new_fail);
155  read_le16_or_fail(buf, field_id->type_idx, dex_field_id_new_fail);
156  read_le32_or_fail(buf, field_id->name_idx, dex_field_id_new_fail);
157  field_id->offset = offset;
158  return field_id;
159 
160 dex_field_id_new_fail:
161  free(field_id);
162  return NULL;
163 }
@ field_id
Definition: parser.c:1736

References field_id, free(), NULL, read_le16_or_fail, read_le32_or_fail, and RZ_NEW0.

Referenced by dex_parse().

◆ dex_field_to_bin_field()

static RzBinField* dex_field_to_bin_field ( RzBinDex dex,
DexEncodedField encoded_field,
DexFieldId field_id,
bool  is_static 
)
static

Definition at line 986 of file dex.c.

986  {
987  RzBinField *field = RZ_NEW0(RzBinField);
988  if (!field) {
989  return NULL;
990  }
991 
992  ut64 access_flags = encoded_field->access_flags;
993  if (is_static) {
994  access_flags |= ACCESS_FLAG_STATIC;
995  }
996 
997  field->vaddr = RZ_DEX_VIRT_ADDRESS + encoded_field->offset;
998  field->paddr = encoded_field->offset;
999  field->visibility = encoded_field->access_flags & UT32_MAX;
1000  field->visibility_str = rz_bin_dex_access_flags_readable(access_flags);
1001  field->name = dex_resolve_string_id(dex, field_id->name_idx);
1002  field->type = dex_resolve_type_id(dex, field_id->type_idx);
1003  field->flags = dex_access_flags_to_bin_flags(access_flags);
1004 
1005  return field;
1006 }
static char * dex_resolve_string_id(RzBinDex *dex, ut32 string_idx)
Definition: dex.c:774
static ut64 dex_access_flags_to_bin_flags(ut64 access_flags)
Definition: dex.c:836
static char * dex_resolve_type_id(RzBinDex *dex, ut32 type_idx)
Definition: dex.c:783
RZ_API RZ_OWN char * rz_bin_dex_access_flags_readable(ut32 access_flags)
Definition: dex.c:710
#define RZ_DEX_VIRT_ADDRESS
Definition: dex.h:13
#define UT32_MAX
Definition: rz_types_base.h:99
ut64 access_flags
Definition: dex.h:111
ut64 vaddr
Definition: rz_bin.h:762
char * name
Definition: rz_bin.h:767
ut64 flags
Definition: rz_bin.h:773
ut32 visibility
Definition: rz_bin.h:766
char * type
Definition: rz_bin.h:768
char * visibility_str
Definition: rz_bin.h:769
ut64 paddr
Definition: rz_bin.h:763

References ACCESS_FLAG_STATIC, dex_encoded_field_t::access_flags, dex_access_flags_to_bin_flags(), dex_resolve_string_id(), dex_resolve_type_id(), field_id, rz_bin_field_t::flags, rz_bin_field_t::name, NULL, dex_encoded_field_t::offset, rz_bin_field_t::paddr, rz_bin_dex_access_flags_readable(), RZ_DEX_VIRT_ADDRESS, RZ_NEW0, rz_bin_field_t::type, UT32_MAX, ut64(), rz_bin_field_t::vaddr, rz_bin_field_t::visibility, and rz_bin_field_t::visibility_str.

Referenced by dex_resolve_fields_in_class().

◆ dex_field_to_symbol()

static RzBinSymbol* dex_field_to_symbol ( RzBinDex dex,
DexEncodedField encoded_field,
DexFieldId field_id,
bool  is_imported 
)
static

Definition at line 1053 of file dex.c.

1053  {
1054  RzBinSymbol *field = RZ_NEW0(RzBinSymbol);
1055  if (!field) {
1056  return NULL;
1057  }
1058 
1059  field->name = dex_resolve_string_id(dex, field_id->name_idx);
1060  field->classname = dex_resolve_type_id(dex, field_id->class_idx);
1061  field->libname = dex_resolve_library(field->classname);
1063  field->is_imported = false;
1064  field->visibility = encoded_field->access_flags & UT32_MAX;
1066  field->vaddr = RZ_DEX_VIRT_ADDRESS + encoded_field->offset;
1067  field->paddr = encoded_field->offset;
1068  field->ordinal = encoded_field->field_idx;
1069  field->method_flags = dex_access_flags_to_bin_flags(encoded_field->access_flags);
1070  field->type = RZ_BIN_TYPE_FIELD_STR;
1071 
1072  return field;
1073 }
#define dex_is_static(a)
Definition: dex.c:35
static char * dex_resolve_library(const char *library)
Definition: dex.c:899
#define RZ_BIN_TYPE_FIELD_STR
Definition: rz_bin.h:120
#define RZ_BIN_BIND_LOCAL_STR
Definition: rz_bin.h:106
#define RZ_BIN_BIND_GLOBAL_STR
Definition: rz_bin.h:107
ut64 field_idx
Definition: dex.h:110
const char * bind
Definition: rz_bin.h:681
char * visibility_str
Definition: rz_bin.h:686
bool is_imported
Definition: rz_bin.h:684
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
char * classname
Definition: rz_bin.h:678
ut32 ordinal
Definition: rz_bin.h:692
ut64 method_flags
Definition: rz_bin.h:696
ut32 visibility
Definition: rz_bin.h:693
char * libname
Definition: rz_bin.h:677

References dex_encoded_field_t::access_flags, rz_bin_symbol_t::bind, rz_bin_symbol_t::classname, dex_access_flags_to_bin_flags(), dex_is_static, dex_resolve_library(), dex_resolve_string_id(), dex_resolve_type_id(), field_id, dex_encoded_field_t::field_idx, rz_bin_symbol_t::is_imported, rz_bin_symbol_t::libname, rz_bin_symbol_t::method_flags, rz_bin_symbol_t::name, NULL, dex_encoded_field_t::offset, rz_bin_symbol_t::ordinal, rz_bin_symbol_t::paddr, RZ_BIN_BIND_GLOBAL_STR, RZ_BIN_BIND_LOCAL_STR, rz_bin_dex_access_flags_readable(), RZ_BIN_TYPE_FIELD_STR, RZ_DEX_VIRT_ADDRESS, RZ_NEW0, rz_bin_symbol_t::type, UT32_MAX, rz_bin_symbol_t::vaddr, rz_bin_symbol_t::visibility, and rz_bin_symbol_t::visibility_str.

Referenced by dex_resolve_fields_in_class_as_symbols().

◆ dex_method_id_new()

static DexMethodId* dex_method_id_new ( RzBuffer buf,
ut64  offset 
)
static

Definition at line 166 of file dex.c.

166  {
167  DexMethodId *method_id = RZ_NEW0(DexMethodId);
168  if (!method_id) {
169  return NULL;
170  }
171 
172  read_le16_or_fail(buf, method_id->class_idx, dex_method_id_new_fail);
173  read_le16_or_fail(buf, method_id->proto_idx, dex_method_id_new_fail);
174  read_le32_or_fail(buf, method_id->name_idx, dex_method_id_new_fail);
175  method_id->offset = offset;
176  return method_id;
177 
178 dex_method_id_new_fail:
179  free(method_id);
180  return NULL;
181 }
ut32 name_idx
Definition: dex.h:100
ut16 class_idx
Definition: dex.h:98
ut16 proto_idx
Definition: dex.h:99
ut64 offset
Definition: dex.h:101

References dex_method_id_t::class_idx, free(), dex_method_id_t::name_idx, NULL, dex_method_id_t::offset, dex_method_id_t::proto_idx, read_le16_or_fail, read_le32_or_fail, and RZ_NEW0.

Referenced by dex_parse().

◆ dex_method_to_symbol()

static RzBinSymbol* dex_method_to_symbol ( RzBinDex dex,
DexEncodedMethod encoded_method,
DexMethodId method_id,
bool  is_imported 
)
static

Definition at line 909 of file dex.c.

909  {
910  RzBinSymbol *symbol = RZ_NEW0(RzBinSymbol);
911  if (!symbol) {
912  return NULL;
913  }
914 
915  bool varargs = dex_is_varargs(encoded_method->access_flags);
916  symbol->name = dex_resolve_string_id(dex, method_id->name_idx);
917  symbol->classname = dex_resolve_type_id(dex, method_id->class_idx);
918  symbol->libname = dex_resolve_library(symbol->classname);
919  symbol->dname = dex_resolve_proto_id(dex, symbol->name, method_id->proto_idx, varargs);
921  symbol->is_imported = is_imported;
922  symbol->visibility = encoded_method->access_flags & UT32_MAX;
924  symbol->size = encoded_method->code_size;
925  if (encoded_method->code_offset < RZ_DEX_RELOC_ADDRESS) {
926  symbol->vaddr = RZ_DEX_VIRT_ADDRESS + encoded_method->code_offset;
927  symbol->paddr = encoded_method->code_offset;
928  } else {
929  symbol->vaddr = encoded_method->code_offset;
930  symbol->paddr = 0;
931  }
932  symbol->ordinal = encoded_method->method_idx;
933  symbol->method_flags = dex_access_flags_to_bin_flags(encoded_method->access_flags);
934  symbol->type = RZ_BIN_TYPE_METH_STR;
935 
936  return symbol;
937 }
#define dex_is_varargs(a)
Definition: dex.c:36
static char * dex_resolve_proto_id(RzBinDex *dex, const char *name, ut32 proto_idx, bool varargs)
Definition: dex.c:792
#define RZ_DEX_RELOC_ADDRESS
Definition: dex.h:14
#define RZ_BIN_TYPE_METH_STR
Definition: rz_bin.h:122
ut64 access_flags
Definition: dex.h:117
char * dname
Definition: rz_bin.h:676

References dex_encoded_method_t::access_flags, rz_bin_symbol_t::bind, dex_method_id_t::class_idx, rz_bin_symbol_t::classname, dex_encoded_method_t::code_offset, dex_encoded_method_t::code_size, dex_access_flags_to_bin_flags(), dex_is_static, dex_is_varargs, dex_resolve_library(), dex_resolve_proto_id(), dex_resolve_string_id(), dex_resolve_type_id(), rz_bin_symbol_t::dname, rz_bin_symbol_t::is_imported, rz_bin_symbol_t::libname, rz_bin_symbol_t::method_flags, dex_encoded_method_t::method_idx, rz_bin_symbol_t::name, dex_method_id_t::name_idx, NULL, rz_bin_symbol_t::ordinal, rz_bin_symbol_t::paddr, dex_method_id_t::proto_idx, RZ_BIN_BIND_GLOBAL_STR, RZ_BIN_BIND_LOCAL_STR, rz_bin_dex_access_flags_readable(), RZ_BIN_TYPE_METH_STR, RZ_DEX_RELOC_ADDRESS, RZ_DEX_VIRT_ADDRESS, RZ_NEW0, rz_bin_symbol_t::size, rz_bin_symbol_t::type, UT32_MAX, rz_bin_symbol_t::vaddr, rz_bin_symbol_t::visibility, and rz_bin_symbol_t::visibility_str.

Referenced by dex_resolve_methods_in_class().

◆ dex_new_encoded_field()

static DexEncodedField* dex_new_encoded_field ( RzBuffer buf,
ut64  base,
ut64 diff_value_prev,
bool  first 
)
static

Definition at line 195 of file dex.c.

195  {
196  DexEncodedField *encoded_field = RZ_NEW0(DexEncodedField);
197  if (!encoded_field) {
198  return NULL;
199  }
200  ut64 diff_value = 0;
201 
202  encoded_field->offset = rz_buf_tell(buf) + base;
203  rz_buf_uleb128(buf, &diff_value);
204  rz_buf_uleb128(buf, &encoded_field->access_flags);
205 
206  if (first) {
207  encoded_field->field_idx = diff_value;
208  *diff_value_prev = diff_value;
209  } else {
210  encoded_field->field_idx = *diff_value_prev + diff_value;
211  *diff_value_prev = encoded_field->field_idx;
212  }
213  return encoded_field;
214 }
RZ_API ut64 rz_buf_tell(RZ_NONNULL RzBuffer *b)
Return the current cursor position.
Definition: buf.c:1238

References dex_encoded_field_t::access_flags, dex_encoded_field_t::field_idx, NULL, dex_encoded_field_t::offset, rz_buf_tell(), rz_buf_uleb128(), RZ_NEW0, and ut64().

Referenced by dex_class_def_new().

◆ dex_new_encoded_method()

static DexEncodedMethod* dex_new_encoded_method ( RzBuffer buf,
ut64  base,
ut64 diff_value_prev,
bool  first,
RzPVector method_ids 
)
static

Definition at line 216 of file dex.c.

216  {
217  DexEncodedMethod *encoded_method = RZ_NEW0(DexEncodedMethod);
218  if (!encoded_method) {
219  return NULL;
220  }
221  ut64 diff_value = 0;
222  ut64 code_offset = 0;
223 
224  encoded_method->offset = rz_buf_tell(buf) + base;
225  rz_buf_uleb128(buf, &diff_value);
226  rz_buf_uleb128(buf, &encoded_method->access_flags);
227  rz_buf_uleb128(buf, &code_offset);
228 
229  if (first) {
230  encoded_method->method_idx = diff_value;
231  *diff_value_prev = diff_value;
232  } else {
233  encoded_method->method_idx = *diff_value_prev + diff_value;
234  *diff_value_prev = encoded_method->method_idx;
235  }
236 
237  if (code_offset > 0) {
238  read_le16_at_or_fail(buf, encoded_method->registers_size, code_offset, dex_new_encoded_method_fail);
239  read_le16_at_or_fail(buf, encoded_method->ins_size, code_offset + 2, dex_new_encoded_method_fail);
240  read_le16_at_or_fail(buf, encoded_method->outs_size, code_offset + 4, dex_new_encoded_method_fail);
241  read_le16_at_or_fail(buf, encoded_method->tries_size, code_offset + 6, dex_new_encoded_method_fail);
242  read_le32_at_or_fail(buf, encoded_method->debug_info_offset, code_offset + 8, dex_new_encoded_method_fail);
243  read_le32_at_or_fail(buf, encoded_method->code_size, code_offset + 12, dex_new_encoded_method_fail);
244  encoded_method->code_size *= sizeof(ut16); // code ushort[insns_size]
245  encoded_method->code_offset = code_offset + 16 + base;
246 
247  if (encoded_method->method_idx < rz_pvector_len(method_ids)) {
248  DexMethodId *method_id = (DexMethodId *)rz_pvector_at(method_ids, encoded_method->method_idx);
249  if (method_id) {
250  method_id->code_offset = encoded_method->code_offset;
251  method_id->code_size = encoded_method->code_size;
252  }
253  }
254  }
255  return encoded_method;
256 
257 dex_new_encoded_method_fail:
258  free(encoded_method);
259  return NULL;
260 }
#define read_le32_at_or_fail(buf, val, offset, fail)
Definition: dex.c:32
#define read_le16_at_or_fail(buf, val, offset, fail)
Definition: dex.c:33
ut16 registers_size
Definition: dex.h:120
ut32 debug_info_offset
Definition: dex.h:124

References dex_encoded_method_t::access_flags, dex_method_id_t::code_offset, dex_encoded_method_t::code_offset, dex_method_id_t::code_size, dex_encoded_method_t::code_size, dex_encoded_method_t::debug_info_offset, free(), dex_encoded_method_t::ins_size, dex_encoded_method_t::method_idx, NULL, dex_encoded_method_t::offset, dex_encoded_method_t::outs_size, read_le16_at_or_fail, read_le32_at_or_fail, dex_encoded_method_t::registers_size, rz_buf_tell(), rz_buf_uleb128(), RZ_NEW0, rz_pvector_at(), rz_pvector_len(), dex_encoded_method_t::tries_size, and ut64().

Referenced by dex_class_def_new().

◆ dex_parse()

static bool dex_parse ( RzBinDex dex,
ut64  base,
RzBuffer buf 
)
static

Definition at line 479 of file dex.c.

479  {
480  ut64 offset = 0;
481  st64 read = 0;
483  if (buffer_size < 116) {
484  // 116 bytes is the smalled dex that can be built.
485  RZ_LOG_ERROR("dex bin: invalid buffer size (size < 116)\n");
486  goto dex_parse_bad;
487  }
488 
489  dex->header_offset = base;
490  dex->relocs_offset = base + RZ_DEX_RELOC_ADDRESS;
491  rz_buf_read(buf, dex->magic, sizeof(dex->magic));
492  rz_buf_read(buf, dex->version, sizeof(dex->version));
493  dex->checksum_offset = rz_buf_tell(buf) + base;
494  read_le32_or_fail(buf, dex->checksum, dex_parse_bad);
495  dex->signature_offset = rz_buf_tell(buf) + base;
496  rz_buf_read(buf, dex->signature, sizeof(dex->signature));
497  read_le32_or_fail(buf, dex->file_size, dex_parse_bad);
498  read_le32_or_fail(buf, dex->header_size, dex_parse_bad);
499  read_le32_or_fail(buf, dex->endian_tag, dex_parse_bad);
500 
501  read_le32_or_fail(buf, dex->link_size, dex_parse_bad);
502  read_le32_or_fail(buf, dex->link_offset, dex_parse_bad);
503 
504  read_le32_or_fail(buf, dex->map_offset, dex_parse_bad);
505 
506  read_le32_or_fail(buf, dex->string_ids_size, dex_parse_bad);
507  read_le32_or_fail(buf, dex->string_ids_offset, dex_parse_bad);
508  // string_ids points to an array of offsets.
509  dex_fail_if_bad_ids(dex->string_ids, sizeof(ut32), buffer_size, dex_parse_bad);
510 
511  read_le32_or_fail(buf, dex->type_ids_size, dex_parse_bad);
512  read_le32_or_fail(buf, dex->type_ids_offset, dex_parse_bad);
513  dex_fail_if_bad_ids(dex->type_ids, DEX_TYPE_ID_SIZE, buffer_size, dex_parse_bad);
514 
515  read_le32_or_fail(buf, dex->proto_ids_size, dex_parse_bad);
516  read_le32_or_fail(buf, dex->proto_ids_offset, dex_parse_bad);
518 
519  read_le32_or_fail(buf, dex->field_ids_size, dex_parse_bad);
520  read_le32_or_fail(buf, dex->field_ids_offset, dex_parse_bad);
522 
523  read_le32_or_fail(buf, dex->method_ids_size, dex_parse_bad);
524  read_le32_or_fail(buf, dex->method_ids_offset, dex_parse_bad);
526 
527  read_le32_or_fail(buf, dex->class_defs_size, dex_parse_bad);
528  read_le32_or_fail(buf, dex->class_defs_offset, dex_parse_bad);
529 
530  read_le32_or_fail(buf, dex->data_size, dex_parse_bad);
531  read_le32_or_fail(buf, dex->data_offset, dex_parse_bad);
532 
533  /* Strings */
534  offset = dex->string_ids_offset;
535  if (!rz_pvector_reserve(dex->strings, dex->string_ids_size)) {
536  goto dex_parse_bad;
537  }
538  for (ut32 i = 0; i < dex->string_ids_size; ++i, offset += sizeof(ut32)) {
539  ut32 string_offset = 0;
540  read_le32_at_or_fail(buf, string_offset, offset, dex_parse_bad);
541 
542  if (rz_buf_seek(buf, string_offset, RZ_BUF_SET) < 0) {
543  goto dex_parse_bad;
544  }
545  DexString *string = dex_string_new(buf, base + string_offset, &read);
546  if (!string) {
547  goto dex_parse_bad;
548  }
549  rz_pvector_push(dex->strings, string);
550  }
551 
552  /* Type Ids */
553  dex->types = RZ_NEWS0(DexTypeId, dex->type_ids_size);
554  if (!dex->types) {
555  goto dex_parse_bad;
556  }
557  if (rz_buf_seek(buf, dex->type_ids_offset, RZ_BUF_SET) < 0) {
558  goto dex_parse_bad;
559  }
560  for (ut32 i = 0; i < dex->type_ids_size; ++i) {
561  read_le32_or_fail(buf, dex->types[i], dex_parse_bad);
562  }
563 
564  /* Proto Ids */
565  offset = dex->proto_ids_offset;
566  if (!rz_pvector_reserve(dex->proto_ids, dex->proto_ids_size)) {
567  goto dex_parse_bad;
568  }
569  for (ut32 i = 0; i < dex->proto_ids_size; ++i, offset += DEX_PROTO_ID_SIZE) {
570  if (rz_buf_seek(buf, offset, RZ_BUF_SET) < 0) {
571  goto dex_parse_bad;
572  }
573  DexProtoId *proto_id = dex_proto_id_new(buf, base + offset);
574  if (!proto_id) {
575  goto dex_parse_bad;
576  }
577  rz_pvector_push(dex->proto_ids, proto_id);
578  }
579 
580  /* Field Ids */
581  offset = dex->field_ids_offset;
582  if (!rz_pvector_reserve(dex->field_ids, dex->field_ids_size)) {
583  goto dex_parse_bad;
584  }
585  for (ut32 i = 0; i < dex->field_ids_size; ++i, offset += DEX_FIELD_ID_SIZE) {
586  if (rz_buf_seek(buf, offset, RZ_BUF_SET) < 0) {
587  goto dex_parse_bad;
588  }
590  if (!field_id) {
591  goto dex_parse_bad;
592  }
594  }
595 
596  /* Method Ids */
597  offset = dex->method_ids_offset;
598  if (!rz_pvector_reserve(dex->method_ids, dex->method_ids_size)) {
599  goto dex_parse_bad;
600  }
601  for (ut32 i = 0; i < dex->method_ids_size; ++i, offset += DEX_METHOD_ID_SIZE) {
602  if (rz_buf_seek(buf, offset, RZ_BUF_SET) < 0) {
603  goto dex_parse_bad;
604  }
605  DexMethodId *method_id = dex_method_id_new(buf, base + offset);
606  if (!method_id) {
607  goto dex_parse_bad;
608  }
609  rz_pvector_push(dex->method_ids, method_id);
610  }
611 
612  /* Class Defs */
613  offset = dex->class_defs_offset;
614  if (!rz_pvector_reserve(dex->class_defs, dex->class_defs_size)) {
615  goto dex_parse_bad;
616  }
617  for (ut32 i = 0; i < dex->class_defs_size; ++i, offset += DEX_CLASS_DEF_SIZE) {
618  if (rz_buf_seek(buf, offset, RZ_BUF_SET) < 0) {
619  goto dex_parse_bad;
620  }
621  DexClassDef *class_def = dex_class_def_new(buf, base + offset, base, dex->method_ids);
622  if (!class_def) {
623  goto dex_parse_bad;
624  }
625  rz_pvector_push(dex->class_defs, class_def);
626  }
627 
628  /* Resolve all virtual methods */
630 
631  /* generate relocation code buffer this buffer will contain a
632  * sequence of 0e00, i.e 'return-void', which will be used to
633  * resolve imports for the xrefs.
634  */
635  if (!dex_create_relocations(dex)) {
636  goto dex_parse_bad;
637  }
638 
639  return true;
640 
641 dex_parse_bad:
642  rz_bin_dex_free(dex);
643  return false;
644 }
RZ_API void rz_bin_dex_free(RZ_NULLABLE RzBinDex *dex)
Frees a RzBinDex struct.
Definition: dex.c:649
#define dex_fail_if_bad_ids(name, z, s, g)
Definition: dex.c:38
static DexFieldId * dex_field_id_new(RzBuffer *buf, ut64 offset)
Definition: dex.c:148
static DexMethodId * dex_method_id_new(RzBuffer *buf, ut64 offset)
Definition: dex.c:166
static DexClassDef * dex_class_def_new(RzBuffer *buf, ut64 offset, ut64 base, RzPVector *method_ids)
Definition: dex.c:262
static DexString * dex_string_new(RzBuffer *buf, ut64 offset, st64 *pread)
Definition: dex.c:77
static DexProtoId * dex_proto_id_new(RzBuffer *buf, ut64 offset)
Definition: dex.c:112
static bool dex_create_relocations(RzBinDex *dex)
Definition: dex.c:393
static void dex_resolve_all_virtual_methods(RzBinDex *dex)
Definition: dex.c:377
ut32 DexTypeId
Definition: dex.h:77
#define DEX_PROTO_ID_SIZE
Definition: dex.h:87
#define DEX_METHOD_ID_SIZE
Definition: dex.h:106
#define DEX_CLASS_DEF_SIZE
Definition: dex.h:158
#define DEX_TYPE_ID_SIZE
Definition: dex.h:78
#define DEX_FIELD_ID_SIZE
Definition: dex.h:95
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define st64
Definition: rz_types_base.h:10
static void ** rz_pvector_reserve(RzPVector *vec, size_t capacity)
Definition: rz_vector.h:312
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
ut64 signature_offset
Definition: dex.h:167
ut32 data_size
Definition: dex.h:186
ut32 type_ids_offset
Definition: dex.h:177
ut32 string_ids_size
Definition: dex.h:174
ut32 proto_ids_size
Definition: dex.h:178
ut8 signature[20]
Definition: dex.h:166
ut32 endian_tag
Definition: dex.h:170
ut32 class_defs_size
Definition: dex.h:184
ut32 type_ids_size
Definition: dex.h:176
ut32 method_ids_size
Definition: dex.h:182
ut32 checksum
Definition: dex.h:164
ut32 link_offset
Definition: dex.h:172
RzPVector * strings
Definition: dex.h:190
ut32 header_size
Definition: dex.h:169
RzPVector * field_ids
Definition: dex.h:192
ut32 data_offset
Definition: dex.h:187
DexTypeId * types
Definition: dex.h:196
ut64 header_offset
Definition: dex.h:161
ut32 link_size
Definition: dex.h:171
ut32 string_ids_offset
Definition: dex.h:175
ut32 method_ids_offset
Definition: dex.h:183
ut8 version[4]
Definition: dex.h:163
ut32 class_defs_offset
Definition: dex.h:185
ut32 field_ids_offset
Definition: dex.h:181
ut64 checksum_offset
Definition: dex.h:165
ut8 magic[4]
Definition: dex.h:162
ut32 map_offset
Definition: dex.h:173
RzPVector * proto_ids
Definition: dex.h:191
ut32 field_ids_size
Definition: dex.h:180
ut32 proto_ids_offset
Definition: dex.h:179
ut32 file_size
Definition: dex.h:168
#define buffer_size(buffer)
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References buffer_size, dex_t::checksum, dex_t::checksum_offset, dex_t::class_defs, dex_t::class_defs_offset, dex_t::class_defs_size, dex_t::data_offset, dex_t::data_size, dex_class_def_new(), DEX_CLASS_DEF_SIZE, dex_create_relocations(), dex_fail_if_bad_ids, dex_field_id_new(), DEX_FIELD_ID_SIZE, dex_method_id_new(), DEX_METHOD_ID_SIZE, dex_proto_id_new(), DEX_PROTO_ID_SIZE, dex_resolve_all_virtual_methods(), dex_string_new(), DEX_TYPE_ID_SIZE, dex_t::endian_tag, field_id, dex_t::field_ids, dex_t::field_ids_offset, dex_t::field_ids_size, dex_t::file_size, dex_t::header_offset, dex_t::header_size, i, dex_t::link_offset, dex_t::link_size, dex_t::magic, dex_t::map_offset, dex_t::method_ids, dex_t::method_ids_offset, dex_t::method_ids_size, dex_t::proto_ids, dex_t::proto_ids_offset, dex_t::proto_ids_size, read(), read_le32_at_or_fail, read_le32_or_fail, dex_t::relocs_offset, rz_bin_dex_free(), rz_buf_read(), rz_buf_seek(), RZ_BUF_SET, rz_buf_size(), rz_buf_tell(), RZ_DEX_RELOC_ADDRESS, RZ_LOG_ERROR, RZ_NEWS0, rz_pvector_push(), rz_pvector_reserve(), dex_t::signature, dex_t::signature_offset, st64, dex_t::string_ids_offset, dex_t::string_ids_size, dex_t::strings, dex_t::type_ids_offset, dex_t::type_ids_size, dex_t::types, ut64(), and dex_t::version.

Referenced by rz_bin_dex_new().

◆ dex_proto_id_free()

static void dex_proto_id_free ( DexProtoId string)
static

Definition at line 104 of file dex.c.

104  {
105  if (!string) {
106  return;
107  }
108  free(string->type_list);
109  free(string);
110 }
ut16 * type_list
Definition: dex.h:84

References free(), and dex_proto_id_t::type_list.

Referenced by rz_bin_dex_new().

◆ dex_proto_id_new()

static DexProtoId* dex_proto_id_new ( RzBuffer buf,
ut64  offset 
)
static

Definition at line 112 of file dex.c.

112  {
113  DexProtoId *proto_id = RZ_NEW0(DexProtoId);
114  if (!proto_id) {
115  return NULL;
116  }
117 
118  ut32 parameters_offset = 0;
119  proto_id->offset = offset;
120  read_le32_or_fail(buf, proto_id->shorty_idx, dex_proto_id_new_fail);
121  read_le32_or_fail(buf, proto_id->return_type_idx, dex_proto_id_new_fail);
122 
123  read_le32_or_fail(buf, parameters_offset, dex_proto_id_new_fail);
124  if (parameters_offset > 0) {
125  ut32 count = 0;
126  read_le32_at_or_fail(buf, count, parameters_offset, dex_proto_id_new_fail);
127 
128  proto_id->type_list_size = count;
129  proto_id->type_list = RZ_NEWS(ut16, count);
130  if (!proto_id->type_list) {
131  goto dex_proto_id_new_fail;
132  }
133 
134  parameters_offset += sizeof(ut32);
135  for (ut32 i = 0; i < count; ++i, parameters_offset += sizeof(ut16)) {
136  read_le16_at_or_fail(buf, proto_id->type_list[i], parameters_offset, dex_proto_id_new_fail);
137  }
138  }
139 
140  return proto_id;
141 
142 dex_proto_id_new_fail:
143  free(proto_id);
144  return NULL;
145 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
ut32 shorty_idx
Definition: dex.h:81
ut64 offset
Definition: dex.h:85
ut32 return_type_idx
Definition: dex.h:82
ut32 type_list_size
Definition: dex.h:83

References count, free(), i, NULL, dex_proto_id_t::offset, read_le16_at_or_fail, read_le32_at_or_fail, read_le32_or_fail, dex_proto_id_t::return_type_idx, RZ_NEW0, RZ_NEWS, dex_proto_id_t::shorty_idx, dex_proto_id_t::type_list, and dex_proto_id_t::type_list_size.

Referenced by dex_parse().

◆ dex_resolve_all_virtual_methods()

static void dex_resolve_all_virtual_methods ( RzBinDex dex)
static

Definition at line 377 of file dex.c.

377  {
378  DexClassDef *class_def;
379  DexMethodId *method_id = NULL;
380  void **it;
381  dex->relocs_size = 0;
382  rz_pvector_foreach (dex->method_ids, it) {
383  method_id = (DexMethodId *)*it;
384  if (method_id->code_offset ||
385  method_id->class_idx >= rz_pvector_len(dex->class_defs)) {
386  continue;
387  }
388  class_def = rz_pvector_at(dex->class_defs, method_id->class_idx);
389  dex_resolve_virtual_method_code(dex, method_id, class_def->superclass_idx);
390  }
391 }
static void dex_resolve_virtual_method_code(RzBinDex *dex, DexMethodId *to_resolve, ut32 superclass_idx)
Definition: dex.c:359

References dex_t::class_defs, dex_method_id_t::class_idx, dex_method_id_t::code_offset, dex_resolve_virtual_method_code(), dex_t::method_ids, NULL, dex_t::relocs_size, rz_pvector_at(), rz_pvector_foreach, rz_pvector_len(), and dex_class_def_t::superclass_idx.

Referenced by dex_parse().

◆ dex_resolve_entrypoints_in_class()

static RzList* dex_resolve_entrypoints_in_class ( RzBinDex dex,
DexClassDef class_def 
)
static

Definition at line 1693 of file dex.c.

1693  {
1694  RzListIter *it;
1695  DexEncodedMethod *encoded_method = NULL;
1696  RzList *entrypoints = NULL;
1697 
1699  if (!entrypoints) {
1700  return NULL;
1701  }
1702 
1703  rz_list_foreach (class_def->direct_methods, it, encoded_method) {
1704  if (!dex_is_static(encoded_method->access_flags)) {
1705  // entrypoints are static
1706  continue;
1707  }
1708 
1709  if (encoded_method->method_idx >= rz_pvector_len(dex->method_ids)) {
1710  RZ_LOG_INFO("cannot find direct method with index %" PFMT64u "\n", encoded_method->method_idx);
1711  continue;
1712  }
1713  DexMethodId *method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
1714 
1715  char *name = dex_resolve_string_id(dex, method_id->name_idx);
1716  if (!name) {
1717  continue;
1718  }
1719 
1720  if (strcmp(name, "main") != 0 && strcmp(name, "<init>") != 0 && strcmp(name, "<clinit>") != 0) {
1721  free(name);
1722  continue;
1723  }
1724  free(name);
1725 
1726  RzBinAddr *entrypoint = RZ_NEW0(RzBinAddr);
1727  if (!entrypoint) {
1728  break;
1729  }
1730  if (encoded_method->code_offset < RZ_DEX_RELOC_ADDRESS) {
1731  entrypoint->vaddr = RZ_DEX_VIRT_ADDRESS + encoded_method->code_offset;
1732  entrypoint->paddr = encoded_method->code_offset;
1733  } else {
1734  entrypoint->vaddr = encoded_method->code_offset;
1735  entrypoint->paddr = 0;
1736  }
1737  if (entrypoint && !rz_list_append(entrypoints, entrypoint)) {
1738  free(entrypoint);
1739  }
1740  }
1741 
1742  rz_list_foreach (class_def->virtual_methods, it, encoded_method) {
1743  if (!dex_is_static(encoded_method->access_flags)) {
1744  // entrypoints are static
1745  continue;
1746  }
1747 
1748  if (encoded_method->method_idx >= rz_pvector_len(dex->method_ids)) {
1749  RZ_LOG_INFO("cannot find virtual method with index %" PFMT64u "\n", encoded_method->method_idx);
1750  continue;
1751  }
1752 
1753  DexMethodId *method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
1754  if (method_id->code_offset < 1) {
1755  // if there is no code, skip
1756  continue;
1757  }
1758 
1759  char *name = dex_resolve_string_id(dex, method_id->name_idx);
1760  if (!name) {
1761  continue;
1762  }
1763 
1764  if (strcmp(name, "main") != 0 && strcmp(name, "<init>") != 0 && strcmp(name, "<clinit>") != 0) {
1765  free(name);
1766  continue;
1767  }
1768  free(name);
1769 
1770  RzBinAddr *entrypoint = RZ_NEW0(RzBinAddr);
1771  if (!entrypoint) {
1772  break;
1773  }
1774  if (encoded_method->code_offset < RZ_DEX_RELOC_ADDRESS) {
1775  entrypoint->vaddr = RZ_DEX_VIRT_ADDRESS + encoded_method->code_offset;
1776  entrypoint->paddr = encoded_method->code_offset;
1777  } else {
1778  entrypoint->vaddr = encoded_method->code_offset;
1779  entrypoint->paddr = 0;
1780  }
1781  if (entrypoint && !rz_list_append(entrypoints, entrypoint)) {
1782  free(entrypoint);
1783  }
1784  }
1785 
1786  return entrypoints;
1787 }
static RzList * entrypoints(RzBinFile *bf)
Definition: bin_dex.c:134
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define PFMT64u
Definition: rz_types.h:395
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187

References dex_encoded_method_t::access_flags, dex_method_id_t::code_offset, dex_encoded_method_t::code_offset, dex_is_static, dex_resolve_string_id(), dex_class_def_t::direct_methods, entrypoints(), free(), dex_t::method_ids, dex_encoded_method_t::method_idx, dex_method_id_t::name_idx, NULL, rz_bin_addr_t::paddr, PFMT64u, RZ_DEX_RELOC_ADDRESS, RZ_DEX_VIRT_ADDRESS, rz_list_append(), rz_list_newf(), RZ_LOG_INFO, RZ_NEW0, rz_pvector_at(), rz_pvector_len(), rz_bin_addr_t::vaddr, and dex_class_def_t::virtual_methods.

Referenced by rz_bin_dex_entrypoints().

◆ dex_resolve_fields_in_class()

static RzList* dex_resolve_fields_in_class ( RzBinDex dex,
DexClassDef class_def,
ut8 inserted 
)
static

Definition at line 1008 of file dex.c.

1008  {
1010  if (!fields) {
1011  return NULL;
1012  }
1014  DexEncodedField *encoded_field = NULL;
1015  RzListIter *it = NULL;
1016 
1017  rz_list_foreach (class_def->static_fields, it, encoded_field) {
1018  if (encoded_field->field_idx >= rz_pvector_len(dex->field_ids)) {
1019  RZ_LOG_INFO("cannot find static field with index %" PFMT64u "\n", encoded_field->field_idx);
1020  continue;
1021  } else if (inserted[encoded_field->field_idx]) {
1022  continue;
1023  }
1024  inserted[encoded_field->field_idx] = true;
1025  field_id = (DexFieldId *)rz_pvector_at(dex->field_ids, encoded_field->field_idx);
1026 
1027  RzBinField *field = dex_field_to_bin_field(dex, encoded_field, field_id, true);
1028  if (!field || !rz_list_append(fields, field)) {
1029  rz_bin_field_free(field);
1030  break;
1031  }
1032  }
1033 
1034  rz_list_foreach (class_def->instance_fields, it, encoded_field) {
1035  if (encoded_field->field_idx >= rz_pvector_len(dex->field_ids)) {
1036  RZ_LOG_INFO("cannot find instance field with index %" PFMT64u "\n", encoded_field->field_idx);
1037  continue;
1038  } else if (inserted[encoded_field->field_idx]) {
1039  continue;
1040  }
1041  inserted[encoded_field->field_idx] = true;
1042  field_id = (DexFieldId *)rz_pvector_at(dex->field_ids, encoded_field->field_idx);
1043 
1044  RzBinField *field = dex_field_to_bin_field(dex, encoded_field, field_id, false);
1045  if (!field || !rz_list_append(fields, field)) {
1046  rz_bin_field_free(field);
1047  break;
1048  }
1049  }
1050  return fields;
1051 }
const aarch64_field fields[]
Definition: aarch64-opc.c:205
RZ_API void rz_bin_field_free(RzBinField *field)
Definition: bin.c:950
static RzBinField * dex_field_to_bin_field(RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_static)
Definition: dex.c:986

References dex_field_to_bin_field(), field_id, dex_t::field_ids, dex_encoded_field_t::field_idx, fields, dex_class_def_t::instance_fields, NULL, PFMT64u, rz_bin_field_free(), rz_list_append(), rz_list_newf(), RZ_LOG_INFO, rz_pvector_at(), rz_pvector_len(), and dex_class_def_t::static_fields.

Referenced by rz_bin_dex_classes(), and rz_bin_dex_fields().

◆ dex_resolve_fields_in_class_as_symbols()

static RzList* dex_resolve_fields_in_class_as_symbols ( RzBinDex dex,
DexClassDef class_def,
ut8 inserted 
)
static

Definition at line 1075 of file dex.c.

1075  {
1077  if (!fields) {
1078  return NULL;
1079  }
1081  DexEncodedField *encoded_field = NULL;
1082  RzListIter *it = NULL;
1083 
1084  rz_list_foreach (class_def->static_fields, it, encoded_field) {
1085  if (encoded_field->field_idx >= rz_pvector_len(dex->field_ids)) {
1086  RZ_LOG_INFO("cannot find static field with index %" PFMT64u "\n", encoded_field->field_idx);
1087  continue;
1088  }
1089  field_id = (DexFieldId *)rz_pvector_at(dex->field_ids, encoded_field->field_idx);
1090  inserted[encoded_field->field_idx] = true;
1091 
1092  RzBinSymbol *field = dex_field_to_symbol(dex, encoded_field, field_id, false);
1093  if (!field || !rz_list_append(fields, field)) {
1094  rz_bin_symbol_free(field);
1095  break;
1096  }
1097  }
1098 
1099  rz_list_foreach (class_def->instance_fields, it, encoded_field) {
1100  if (encoded_field->field_idx >= rz_pvector_len(dex->field_ids)) {
1101  RZ_LOG_INFO("cannot find instance field with index %" PFMT64u "\n", encoded_field->field_idx);
1102  continue;
1103  }
1104  field_id = (DexFieldId *)rz_pvector_at(dex->field_ids, encoded_field->field_idx);
1105  inserted[encoded_field->field_idx] = true;
1106 
1107  RzBinSymbol *field = dex_field_to_symbol(dex, encoded_field, field_id, false);
1108  if (!field || !rz_list_append(fields, field)) {
1109  rz_bin_symbol_free(field);
1110  break;
1111  }
1112  }
1113  return fields;
1114 }
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
static RzBinSymbol * dex_field_to_symbol(RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_imported)
Definition: dex.c:1053

References dex_field_to_symbol(), field_id, dex_t::field_ids, dex_encoded_field_t::field_idx, fields, dex_class_def_t::instance_fields, NULL, PFMT64u, rz_bin_symbol_free(), rz_list_append(), rz_list_newf(), RZ_LOG_INFO, rz_pvector_at(), rz_pvector_len(), and dex_class_def_t::static_fields.

Referenced by rz_bin_dex_symbols().

◆ dex_resolve_library()

static char* dex_resolve_library ( const char *  library)
static

Definition at line 899 of file dex.c.

899  {
900  if (!library || library[0] != 'L') {
901  return NULL;
902  }
903  char *demangled = strdup(library + 1);
904  rz_str_replace_ch(demangled, '/', '.', 1);
905  demangled[strlen(demangled) - 1] = 0;
906  return demangled;
907 }
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
RZ_API int rz_str_replace_ch(char *s, char a, char b, bool g)
Definition: str.c:139

References NULL, rz_str_replace_ch(), and strdup().

Referenced by dex_field_to_symbol(), dex_method_to_symbol(), and rz_bin_dex_symbols().

◆ dex_resolve_methods_in_class()

static RzList* dex_resolve_methods_in_class ( RzBinDex dex,
DexClassDef class_def,
ut8 inserted 
)
static

Definition at line 939 of file dex.c.

939  {
941  if (!methods) {
942  return NULL;
943  }
944 
945  DexMethodId *method_id = NULL;
946  DexEncodedMethod *encoded_method = NULL;
947  RzListIter *it = NULL;
948 
949  rz_list_foreach (class_def->direct_methods, it, encoded_method) {
950  if (encoded_method->method_idx >= rz_pvector_len(dex->method_ids)) {
951  RZ_LOG_INFO("cannot find direct method with index %" PFMT64u "\n", encoded_method->method_idx);
952  continue;
953  } else if (inserted[encoded_method->method_idx]) {
954  continue;
955  }
956  method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
957  inserted[encoded_method->method_idx] = true;
958 
959  RzBinSymbol *symbol = dex_method_to_symbol(dex, encoded_method, method_id, false);
960  if (!symbol || !rz_list_append(methods, symbol)) {
961  rz_bin_symbol_free(symbol);
962  break;
963  }
964  }
965 
966  rz_list_foreach (class_def->virtual_methods, it, encoded_method) {
967  if (encoded_method->method_idx >= rz_pvector_len(dex->method_ids)) {
968  RZ_LOG_INFO("cannot find virtual method with index %" PFMT64u "\n", encoded_method->method_idx);
969  continue;
970  } else if (inserted[encoded_method->method_idx]) {
971  continue;
972  }
973  method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
974  inserted[encoded_method->method_idx] = true;
975 
976  RzBinSymbol *symbol = dex_method_to_symbol(dex, encoded_method, method_id, false);
977  if (!symbol || !rz_list_append(methods, symbol)) {
978  rz_bin_symbol_free(symbol);
979  break;
980  }
981  }
982 
983  return methods;
984 }
static RzBinSymbol * dex_method_to_symbol(RzBinDex *dex, DexEncodedMethod *encoded_method, DexMethodId *method_id, bool is_imported)
Definition: dex.c:909

References dex_method_to_symbol(), dex_class_def_t::direct_methods, dex_t::method_ids, dex_encoded_method_t::method_idx, NULL, PFMT64u, rz_bin_symbol_free(), rz_list_append(), rz_list_newf(), RZ_LOG_INFO, rz_pvector_at(), rz_pvector_len(), and dex_class_def_t::virtual_methods.

Referenced by rz_bin_dex_classes(), and rz_bin_dex_symbols().

◆ dex_resolve_proto_id()

static char* dex_resolve_proto_id ( RzBinDex dex,
const char *  name,
ut32  proto_idx,
bool  varargs 
)
static

Definition at line 792 of file dex.c.

792  {
793  if (proto_idx >= rz_pvector_len(dex->proto_ids)) {
794  RZ_LOG_INFO("cannot find proto_id with index %u\n", proto_idx);
795  return NULL;
796  }
797 
798  DexProtoId *proto_id = (DexProtoId *)rz_pvector_at(dex->proto_ids, proto_idx);
799  if (proto_id->return_type_idx >= dex->type_ids_size) {
800  RZ_LOG_INFO("cannot find return type id with index %u\n", proto_id->return_type_idx);
801  return NULL;
802  }
803 
805  if (!sb) {
806  return NULL;
807  }
808 
809  const DexString *return_type = dex_resolve_string_id_native(dex, dex->types[proto_id->return_type_idx]);
810  if (!return_type) {
811  RZ_LOG_INFO("cannot find return type string with index %u\n", proto_id->return_type_idx);
813  return NULL;
814  }
815 
816  rz_strbuf_append(sb, "(");
817  for (ut32 i = 0; i < proto_id->type_list_size; ++i) {
818  ut32 type_idx = proto_id->type_list[i];
819 
820  const DexString *param = dex_resolve_string_id_native(dex, dex->types[type_idx]);
821  if (!param) {
822  RZ_LOG_INFO("cannot find param string with index %d\n", dex->types[type_idx]);
824  return NULL;
825  }
826  if (varargs && (i + 1) >= proto_id->type_list_size) {
827  rz_strbuf_append(sb, "...");
828  }
829  rz_strbuf_append_n(sb, param->data, param->size);
830  }
831  rz_strbuf_append(sb, ")");
832  rz_strbuf_append_n(sb, return_type->data, return_type->size);
833  return rz_strbuf_drain(sb);
834 }
static SblHeader sb
Definition: bin_mbn.c:26
static DexString * dex_resolve_string_id_native(RzBinDex *dex, ut32 string_idx)
Definition: dex.c:767
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l)
Definition: strbuf.c:229
char * data
Definition: dex.h:73
ut64 size
Definition: dex.h:71

References dex_string_t::data, dex_resolve_string_id_native(), i, NULL, dex_t::proto_ids, dex_proto_id_t::return_type_idx, RZ_LOG_INFO, rz_pvector_at(), rz_pvector_len(), rz_strbuf_append(), rz_strbuf_append_n(), rz_strbuf_drain(), rz_strbuf_free(), rz_strbuf_new(), sb, dex_string_t::size, dex_t::type_ids_size, dex_proto_id_t::type_list, dex_proto_id_t::type_list_size, and dex_t::types.

Referenced by dex_method_to_symbol(), rz_bin_dex_imports(), rz_bin_dex_resolve_method_by_idx(), rz_bin_dex_resolve_proto_by_idx(), and rz_bin_dex_symbols().

◆ dex_resolve_string_id()

static char* dex_resolve_string_id ( RzBinDex dex,
ut32  string_idx 
)
static

Definition at line 774 of file dex.c.

774  {
775  DexString *string = dex_resolve_string_id_native(dex, string_idx);
776  if (!string) {
777  RZ_LOG_INFO("cannot find string with index %u\n", string_idx);
778  return NULL;
779  }
780  return rz_str_ndup(string->data, string->size);
781 }
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006

References dex_string_t::data, dex_resolve_string_id_native(), NULL, RZ_LOG_INFO, rz_str_ndup(), and dex_string_t::size.

Referenced by dex_field_to_bin_field(), dex_field_to_symbol(), dex_method_to_symbol(), dex_resolve_entrypoints_in_class(), dex_resolve_symbol_in_class_methods(), dex_resolve_type_id(), rz_bin_dex_imports(), rz_bin_dex_resolve_field_by_idx(), rz_bin_dex_resolve_method_by_idx(), rz_bin_dex_resolve_string_by_idx(), and rz_bin_dex_symbols().

◆ dex_resolve_string_id_native()

static DexString* dex_resolve_string_id_native ( RzBinDex dex,
ut32  string_idx 
)
inlinestatic

Definition at line 767 of file dex.c.

767  {
768  if (string_idx >= rz_pvector_len(dex->strings)) {
769  return NULL;
770  }
771  return (DexString *)rz_pvector_at(dex->strings, string_idx);
772 }

References NULL, rz_pvector_at(), rz_pvector_len(), and dex_t::strings.

Referenced by dex_resolve_proto_id(), dex_resolve_string_id(), and rz_bin_dex_resolve_string_offset_by_idx().

◆ dex_resolve_symbol_in_class_methods()

static bool dex_resolve_symbol_in_class_methods ( RzBinDex dex,
DexClassDef class_def,
RzBinSpecialSymbol  resolve,
ut64 paddr,
ut64 vaddr 
)
static

Definition at line 1594 of file dex.c.

1594  {
1595  RzListIter *it;
1596  DexEncodedMethod *encoded_method = NULL;
1597 
1598  rz_list_foreach (class_def->direct_methods, it, encoded_method) {
1599  if (encoded_method->method_idx >= rz_pvector_len(dex->method_ids)) {
1600  RZ_LOG_INFO("cannot find virtual method with index %" PFMT64u "\n", encoded_method->method_idx);
1601  continue;
1602  }
1603  DexMethodId *method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
1604 
1605  char *name = dex_resolve_string_id(dex, method_id->name_idx);
1606  if (!name) {
1607  continue;
1608  }
1610  if (strcmp(name, "<init>") != 0 && strcmp(name, "<clinit>") != 0) {
1611  free(name);
1612  continue;
1613  }
1614  } else if (resolve == RZ_BIN_SPECIAL_SYMBOL_MAIN) {
1615  if (strcmp(name, "main") != 0) {
1616  free(name);
1617  continue;
1618  }
1619  }
1620  free(name);
1621  if (method_id->code_offset < RZ_DEX_RELOC_ADDRESS) {
1622  *vaddr = RZ_DEX_VIRT_ADDRESS + encoded_method->code_offset;
1623  *paddr = method_id->code_offset;
1624  } else {
1625  *vaddr = encoded_method->code_offset;
1626  *paddr = 0;
1627  }
1628  return true;
1629  }
1630 
1631  rz_list_foreach (class_def->virtual_methods, it, encoded_method) {
1632  if (encoded_method->method_idx >= rz_pvector_len(dex->method_ids)) {
1633  RZ_LOG_INFO("cannot find direct method with index %" PFMT64u "\n", encoded_method->method_idx);
1634  continue;
1635  }
1636  DexMethodId *method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, encoded_method->method_idx);
1637 
1638  char *name = dex_resolve_string_id(dex, method_id->name_idx);
1639  if (!name) {
1640  continue;
1641  }
1643  if (strcmp(name, "<init>") != 0 && strcmp(name, "<clinit>") != 0) {
1644  free(name);
1645  continue;
1646  }
1647  } else if (resolve == RZ_BIN_SPECIAL_SYMBOL_MAIN) {
1648  if (strcmp(name, "main") != 0) {
1649  free(name);
1650  continue;
1651  }
1652  }
1653  free(name);
1654 
1655  if (method_id->code_offset < RZ_DEX_RELOC_ADDRESS) {
1656  *vaddr = RZ_DEX_VIRT_ADDRESS + encoded_method->code_offset;
1657  *paddr = method_id->code_offset;
1658  } else {
1659  *vaddr = encoded_method->code_offset;
1660  *paddr = 0;
1661  }
1662  return true;
1663  }
1664  return false;
1665 }
@ RZ_BIN_SPECIAL_SYMBOL_ENTRY
Definition: rz_bin.h:137
@ RZ_BIN_SPECIAL_SYMBOL_INIT
Definition: rz_bin.h:138
@ RZ_BIN_SPECIAL_SYMBOL_MAIN
Definition: rz_bin.h:139
static const char * resolve(struct Type *t, const char *foo, const char **bar)
Definition: swift.c:91

References dex_method_id_t::code_offset, dex_encoded_method_t::code_offset, dex_resolve_string_id(), dex_class_def_t::direct_methods, free(), dex_t::method_ids, dex_encoded_method_t::method_idx, dex_method_id_t::name_idx, NULL, PFMT64u, resolve(), RZ_BIN_SPECIAL_SYMBOL_ENTRY, RZ_BIN_SPECIAL_SYMBOL_INIT, RZ_BIN_SPECIAL_SYMBOL_MAIN, RZ_DEX_RELOC_ADDRESS, RZ_DEX_VIRT_ADDRESS, RZ_LOG_INFO, rz_pvector_at(), rz_pvector_len(), and dex_class_def_t::virtual_methods.

Referenced by rz_bin_dex_resolve_symbol().

◆ dex_resolve_type_id()

static char* dex_resolve_type_id ( RzBinDex dex,
ut32  type_idx 
)
static

Definition at line 783 of file dex.c.

783  {
784  if (type_idx >= dex->type_ids_size) {
785  RZ_LOG_INFO("cannot find type_id with index %u\n", type_idx);
786  return NULL;
787  }
788  DexTypeId type_id = dex->types[type_idx];
789  return dex_resolve_string_id(dex, type_id);
790 }

References dex_resolve_string_id(), NULL, RZ_LOG_INFO, dex_t::type_ids_size, and dex_t::types.

Referenced by dex_field_to_bin_field(), dex_field_to_symbol(), dex_method_to_symbol(), rz_bin_dex_classes(), rz_bin_dex_imports(), rz_bin_dex_libraries(), rz_bin_dex_resolve_class_by_idx(), rz_bin_dex_resolve_field_by_idx(), rz_bin_dex_resolve_method_by_idx(), and rz_bin_dex_symbols().

◆ dex_resolve_virtual_method_code()

static void dex_resolve_virtual_method_code ( RzBinDex dex,
DexMethodId to_resolve,
ut32  superclass_idx 
)
static

Definition at line 359 of file dex.c.

359  {
360  DexMethodId *method_id = NULL;
361  void **it;
362 
363  rz_pvector_foreach (dex->method_ids, it) {
364  method_id = (DexMethodId *)*it;
365  if (method_id == to_resolve ||
366  method_id->class_idx != superclass_idx ||
367  method_id->proto_idx != to_resolve->proto_idx ||
368  method_id->name_idx != to_resolve->name_idx) {
369  continue;
370  }
371  to_resolve->code_offset = method_id->code_offset;
372  to_resolve->code_size = method_id->code_size;
373  return;
374  }
375 }

References dex_method_id_t::class_idx, dex_method_id_t::code_offset, dex_method_id_t::code_size, dex_t::method_ids, dex_method_id_t::name_idx, NULL, dex_method_id_t::proto_idx, and rz_pvector_foreach.

Referenced by dex_resolve_all_virtual_methods().

◆ dex_string_free()

static void dex_string_free ( DexString string)
static

Definition at line 69 of file dex.c.

69  {
70  if (!string) {
71  return;
72  }
73  free(string->data);
74  free(string);
75 }

References dex_string_t::data, and free().

Referenced by rz_bin_dex_new().

◆ dex_string_new()

static DexString* dex_string_new ( RzBuffer buf,
ut64  offset,
st64 pread 
)
static

Definition at line 77 of file dex.c.

77  {
78  ut64 size = 0;
79  char *data = NULL;
80  st64 read;
81  DexString *string = NULL;
82 
84  data = malloc(size + 1);
85  if (!data || rz_buf_read(buf, (ut8 *)data, size) != size) {
86  free(data);
87  return NULL;
88  }
89  data[size] = 0;
90 
91  string = RZ_NEW0(DexString);
92  if (!string) {
93  free(data);
94  return NULL;
95  }
96 
97  *pread = read;
98  string->size = size;
99  string->offset = offset;
100  string->data = data;
101  return string;
102 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname pread
Definition: sflib.h:98
voidpf void uLong size
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11

References free(), malloc(), NULL, pread, read(), rz_buf_read(), rz_buf_uleb128(), RZ_NEW0, st64, and ut64().

Referenced by dex_parse().

◆ free_rz_bin_class()

static void free_rz_bin_class ( RzBinClass bclass)
static

Definition at line 1116 of file dex.c.

1116  {
1117  if (!bclass) {
1118  return;
1119  }
1120  rz_list_free(bclass->methods);
1121  rz_list_free(bclass->fields);
1122  free(bclass->name);
1123  free(bclass->super);
1124  free(bclass->visibility_str);
1125  free(bclass);
1126 }
char * super
Definition: rz_bin.h:649
RzList * fields
Definition: rz_bin.h:654
char * name
Definition: rz_bin.h:647
RzList * methods
Definition: rz_bin.h:653
char * visibility_str
Definition: rz_bin.h:650

References rz_bin_class_t::fields, free(), rz_bin_class_t::methods, rz_bin_class_t::name, rz_list_free(), rz_bin_class_t::super, and rz_bin_class_t::visibility_str.

Referenced by rz_bin_dex_classes().

◆ rz_bin_dex_access_flags_readable()

RZ_API RZ_OWN char* rz_bin_dex_access_flags_readable ( ut32  access_flags)

Definition at line 710 of file dex.c.

710  {
711  RzStrBuf *sb = NULL;
712  for (ut32 i = 0; i < CLASS_ACCESS_FLAGS_SIZE; ++i) {
714  if (afr->flag == ACCESS_FLAG_VARARGS) {
715  continue;
716  }
717  if (access_flags & afr->flag) {
718  if (!sb) {
719  sb = rz_strbuf_new(afr->readable);
720  if (!sb) {
721  return NULL;
722  }
723  } else {
724  rz_strbuf_appendf(sb, " %s", afr->readable);
725  }
726  }
727  }
728 
729  return sb ? rz_strbuf_drain(sb) : NULL;
730 }
static const DexAccessFlagsReadable access_flags_list[CLASS_ACCESS_FLAGS_SIZE]
Definition: dex.c:48
#define CLASS_ACCESS_FLAGS_SIZE
Definition: dex.c:47
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
const char * readable
Definition: dex.c:13

References ACCESS_FLAG_VARARGS, access_flags_list, CLASS_ACCESS_FLAGS_SIZE, dex_access_flags_readable_t::flag, i, NULL, dex_access_flags_readable_t::readable, rz_strbuf_appendf(), rz_strbuf_drain(), rz_strbuf_new(), and sb.

Referenced by decode_access_flags(), dex_field_to_bin_field(), dex_field_to_symbol(), dex_method_to_symbol(), and rz_bin_dex_classes().

◆ rz_bin_dex_checksum()

RZ_API void rz_bin_dex_checksum ( RZ_NONNULL RzBinDex dex,
RZ_NONNULL RzBinHash hash 
)

Sets the RzBinHash dex checksum (adler32)

Definition at line 1990 of file dex.c.

1990  {
1991  rz_return_if_fail(dex && hash);
1992  hash->type = "adler32";
1993  hash->len = sizeof(dex->checksum);
1994  hash->addr = dex->checksum_offset;
1995  hash->from = dex->checksum_offset + sizeof(dex->checksum);
1996  hash->to = dex->file_size - hash->from;
1997  rz_write_le32(hash->buf, dex->checksum);
1998 }
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
static void rz_write_le32(void *dest, ut32 val)
Definition: rz_endian.h:256

References rz_return_if_fail, and rz_write_le32().

Referenced by info().

◆ rz_bin_dex_classes()

RZ_API RZ_OWN RzList* rz_bin_dex_classes ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinClass*> containing the dex classes.

Definition at line 1131 of file dex.c.

1131  {
1133 
1134  DexClassDef *class_def;
1135  RzBinClass *bclass = NULL;
1136  RzList *classes = NULL;
1137  void **it;
1138 
1139  ut32 n_methods = rz_pvector_len(dex->method_ids);
1140  ut32 n_fields = rz_pvector_len(dex->field_ids);
1141 
1142  ut8 *inserted_methods = RZ_NEWS0(ut8, n_methods);
1143  ut8 *inserted_fields = RZ_NEWS0(ut8, n_fields);
1144  if ((n_methods > 0 && !inserted_methods) || (n_fields > 0 && !inserted_fields)) {
1145  free(inserted_fields);
1146  free(inserted_methods);
1147  return NULL;
1148  }
1149 
1151  if (!classes) {
1152  free(inserted_fields);
1153  free(inserted_methods);
1154  return NULL;
1155  }
1156 
1157  rz_pvector_foreach (dex->class_defs, it) {
1158  class_def = (DexClassDef *)*it;
1159  bclass = RZ_NEW0(RzBinClass);
1160  if (!bclass) {
1161  break;
1162  }
1163 
1164  bclass->name = dex_resolve_type_id(dex, class_def->class_idx);
1165  bclass->super = dex_resolve_type_id(dex, class_def->superclass_idx);
1166  bclass->visibility = class_def->access_flags;
1168  bclass->index = class_def->class_idx;
1169  bclass->addr = class_def->offset;
1170  bclass->methods = dex_resolve_methods_in_class(dex, class_def, inserted_methods);
1171  bclass->fields = dex_resolve_fields_in_class(dex, class_def, inserted_fields);
1172 
1173  if (!rz_list_append(classes, bclass)) {
1174  free_rz_bin_class(bclass);
1175  break;
1176  }
1177  }
1178  free(inserted_fields);
1179  free(inserted_methods);
1180 
1181  return classes;
1182 }
static RzList * classes(RzBinFile *bf)
Definition: bin_dex.c:71
static RzList * dex_resolve_fields_in_class(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
Definition: dex.c:1008
static RzList * dex_resolve_methods_in_class(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
Definition: dex.c:939
static void free_rz_bin_class(RzBinClass *bclass)
Definition: dex.c:1116
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
int visibility
Definition: rz_bin.h:656

References dex_class_def_t::access_flags, rz_bin_class_t::addr, dex_class_def_t::class_idx, classes(), dex_resolve_fields_in_class(), dex_resolve_methods_in_class(), dex_resolve_type_id(), rz_bin_class_t::fields, free(), free_rz_bin_class(), rz_bin_class_t::index, rz_bin_class_t::methods, rz_bin_class_t::name, NULL, dex_class_def_t::offset, rz_bin_dex_access_flags_readable(), rz_list_append(), rz_list_newf(), RZ_NEW0, RZ_NEWS0, rz_pvector_foreach, rz_pvector_len(), rz_return_val_if_fail, rz_bin_class_t::super, dex_class_def_t::superclass_idx, rz_bin_class_t::visibility, and rz_bin_class_t::visibility_str.

Referenced by classes().

◆ rz_bin_dex_debug_info()

RZ_API ut64 rz_bin_dex_debug_info ( RZ_NONNULL RzBinDex dex)

Returns the dex debug info RzBin values.

Definition at line 2041 of file dex.c.

2041  {
2042  rz_return_val_if_fail(dex, 0);
2043  // TODO
2044  return 0;
2045 }

References rz_return_val_if_fail.

Referenced by info().

◆ rz_bin_dex_entrypoints()

RZ_API RZ_OWN RzList* rz_bin_dex_entrypoints ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinAddr*> containing the dex entripoints.

Definition at line 1792 of file dex.c.

1792  {
1794 
1795  DexClassDef *class_def;
1796  RzList *list = NULL;
1797  RzList *entrypoints = NULL;
1798  void **it;
1799 
1801  if (!entrypoints) {
1802  return NULL;
1803  }
1804 
1805  rz_pvector_foreach (dex->class_defs, it) {
1806  class_def = (DexClassDef *)*it;
1807  list = dex_resolve_entrypoints_in_class(dex, class_def);
1808  if (list) {
1810  rz_list_free(list);
1811  }
1812  }
1813 
1814  return entrypoints;
1815 }
static RzList * dex_resolve_entrypoints_in_class(RzBinDex *dex, DexClassDef *class_def)
Definition: dex.c:1693
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API bool rz_list_join(RZ_NONNULL RzList *list1, RZ_NONNULL RzList *list2)
Joins 2 list into one (list2 pointer needs to be freed by the user)
Definition: list.c:209

References dex_resolve_entrypoints_in_class(), entrypoints(), free(), list(), NULL, rz_list_free(), rz_list_join(), rz_list_newf(), rz_pvector_foreach, and rz_return_val_if_fail.

Referenced by entrypoints().

◆ rz_bin_dex_fields()

RZ_API RZ_OWN RzList* rz_bin_dex_fields ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinField*> containing the dex fields.

Definition at line 1232 of file dex.c.

1232  {
1234 
1235  DexClassDef *class_def;
1236  RzList *fields = NULL;
1237  void **it;
1238  ut32 n_fields = rz_pvector_len(dex->field_ids);
1239  ut8 *inserted = RZ_NEWS0(ut8, n_fields);
1240  if (n_fields > 0 && !inserted) {
1241  free(inserted);
1242  return NULL;
1243  }
1244 
1246  if (!fields) {
1247  free(inserted);
1248  return NULL;
1249  }
1250 
1251  rz_pvector_foreach (dex->class_defs, it) {
1252  class_def = (DexClassDef *)*it;
1253  RzList *class_fields = dex_resolve_fields_in_class(dex, class_def, inserted);
1254  if (class_fields) {
1255  rz_list_join(fields, class_fields);
1256  rz_list_free(class_fields);
1257  }
1258  }
1259  free(inserted);
1260 
1261  return fields;
1262 }

References dex_resolve_fields_in_class(), fields, free(), NULL, rz_bin_field_free(), rz_list_free(), rz_list_join(), rz_list_newf(), RZ_NEWS0, rz_pvector_foreach, rz_pvector_len(), and rz_return_val_if_fail.

Referenced by fields().

◆ rz_bin_dex_free()

RZ_API void rz_bin_dex_free ( RZ_NULLABLE RzBinDex dex)

Frees a RzBinDex struct.

Definition at line 649 of file dex.c.

649  {
650  if (!dex) {
651  return;
652  }
653 
654  rz_pvector_free(dex->strings);
655  rz_pvector_free(dex->proto_ids);
656  rz_pvector_free(dex->field_ids);
657  rz_pvector_free(dex->method_ids);
658  rz_pvector_free(dex->class_defs);
659  rz_buf_free(dex->relocs_buffer);
660 
661  free(dex->types);
662  free(dex->relocs_code);
663  free(dex);
664 }
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336

References free(), rz_buf_free(), and rz_pvector_free().

Referenced by destroy(), dex_parse(), and rz_bin_dex_new().

◆ rz_bin_dex_imports()

RZ_API RZ_OWN RzList* rz_bin_dex_imports ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinImport*> containing the dex imports.

Definition at line 1379 of file dex.c.

1379  {
1381 
1383  DexMethodId *method_id;
1384  DexClassDef *class_def;
1385  RzList *imports = NULL;
1386  ut32 *class_ids = NULL;
1387  void **vit;
1388 
1389  ut32 n_classes = rz_pvector_len(dex->class_defs);
1390  if (n_classes < 1) {
1392  }
1393 
1394  class_ids = RZ_NEWS0(ut32, n_classes);
1395  if (!class_ids) {
1396  return NULL;
1397  }
1398 
1399  ut32 j = 0;
1400  rz_pvector_foreach (dex->class_defs, vit) {
1401  class_def = (DexClassDef *)*vit;
1402  class_ids[j] = class_def->class_idx;
1403  j++;
1404  }
1405 
1407  if (!imports) {
1408  free(class_ids);
1409  return NULL;
1410  }
1411 
1412  ut32 ordinal = 0;
1413  rz_pvector_foreach (dex->field_ids, vit) {
1414  field_id = (DexFieldId *)*vit;
1415  bool class_found = false;
1416  for (ut32 i = 0; i < n_classes; ++i) {
1417  if (field_id->class_idx == class_ids[i]) {
1418  class_found = true;
1419  break;
1420  }
1421  }
1422  if (class_found) {
1423  continue;
1424  }
1425 
1426  RzBinImport *import = RZ_NEW0(RzBinImport);
1427  if (!import) {
1428  break;
1429  }
1430 
1431  char *object = dex_resolve_type_id(dex, field_id->class_idx);
1432  if (!object) {
1433  free(import);
1434  break;
1435  }
1436  rz_str_replace_char(object, ';', 0);
1437 
1438  char *class_name = (char *)rz_str_rchr(object, NULL, '/');
1439  if (class_name) {
1440  class_name[0] = 0;
1441  class_name++;
1442  }
1443  rz_str_replace_ch(object, '/', '.', 1);
1444 
1445  import->name = dex_resolve_string_id(dex, field_id->name_idx);
1446  import->libname = class_name ? strdup(object + 1) : NULL;
1447  import->classname = strdup(class_name ? class_name : object + 1);
1448  import->bind = RZ_BIN_BIND_WEAK_STR;
1449  import->type = RZ_BIN_TYPE_FIELD_STR;
1450  import->ordinal = ordinal;
1451  free(object);
1452 
1453  if (!rz_list_append(imports, import)) {
1454  rz_bin_import_free(import);
1455  break;
1456  }
1457  ordinal++;
1458  }
1459 
1460  rz_pvector_foreach (dex->method_ids, vit) {
1461  method_id = (DexMethodId *)*vit;
1462  bool class_found = false;
1463  for (ut32 i = 0; i < n_classes; ++i) {
1464  if (method_id->class_idx == class_ids[i]) {
1465  class_found = true;
1466  break;
1467  }
1468  }
1469  if (class_found) {
1470  continue;
1471  }
1472 
1473  RzBinImport *import = RZ_NEW0(RzBinImport);
1474  if (!import) {
1475  break;
1476  }
1477 
1478  char *object = dex_resolve_type_id(dex, method_id->class_idx);
1479  if (!object) {
1480  rz_bin_import_free(import);
1481  break;
1482  }
1483  rz_str_replace_char(object, ';', 0);
1484 
1485  char *class_name = (char *)rz_str_rchr(object, NULL, '/');
1486  if (class_name) {
1487  class_name[0] = 0;
1488  class_name++;
1489  }
1490  rz_str_replace_ch(object, '/', '.', 1);
1491 
1492  char *name = dex_resolve_string_id(dex, method_id->name_idx);
1493  import->name = dex_resolve_proto_id(dex, name, method_id->proto_idx, false);
1494  import->libname = class_name ? strdup(object + 1) : NULL;
1495  import->classname = strdup(class_name ? class_name : object + 1);
1496  import->bind = RZ_BIN_BIND_WEAK_STR;
1497  import->type = RZ_BIN_TYPE_FUNC_STR;
1498  import->ordinal = ordinal;
1499  free(name);
1500  free(object);
1501 
1502  if (!rz_list_append(imports, import)) {
1503  rz_bin_import_free(import);
1504  break;
1505  }
1506  ordinal++;
1507  }
1508 
1509  free(class_ids);
1510  return imports;
1511 }
RZ_API void rz_bin_import_free(RzBinImport *imp)
Definition: bin.c:137
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
#define RZ_BIN_BIND_WEAK_STR
Definition: rz_bin.h:108
#define RZ_BIN_TYPE_FUNC_STR
Definition: rz_bin.h:119
RZ_API const char * rz_str_rchr(const char *base, const char *p, int ch)
Definition: str.c:829
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169

References dex_method_id_t::class_idx, dex_class_def_t::class_idx, dex_resolve_proto_id(), dex_resolve_string_id(), dex_resolve_type_id(), field_id, free(), i, imports(), dex_method_id_t::name_idx, NULL, dex_method_id_t::proto_idx, RZ_BIN_BIND_WEAK_STR, rz_bin_import_free(), RZ_BIN_TYPE_FIELD_STR, RZ_BIN_TYPE_FUNC_STR, rz_list_append(), rz_list_newf(), RZ_NEW0, RZ_NEWS0, rz_pvector_foreach, rz_pvector_len(), rz_return_val_if_fail, rz_str_rchr(), rz_str_replace_ch(), rz_str_replace_char(), and strdup().

Referenced by imports().

◆ rz_bin_dex_libraries()

RZ_API RZ_OWN RzList* rz_bin_dex_libraries ( RZ_NONNULL RzBinDex dex)

Returns a RzList<char*> containing the dex libraries.

Definition at line 1520 of file dex.c.

1520  {
1522 
1523  DexMethodId *method_id;
1524  DexClassDef *class_def;
1525  RzList *libraries = NULL;
1526  ut32 *class_ids = NULL;
1527  void **vit;
1528 
1529  ut32 n_classes = rz_pvector_len(dex->class_defs);
1530  if (n_classes < 1) {
1531  return rz_list_newf((RzListFree)free);
1532  }
1533 
1534  class_ids = RZ_NEWS0(ut32, n_classes);
1535  if (!class_ids) {
1536  return NULL;
1537  }
1538 
1539  ut32 j = 0;
1540  rz_pvector_foreach (dex->class_defs, vit) {
1541  class_def = (DexClassDef *)*vit;
1542  class_ids[j] = class_def->class_idx;
1543  j++;
1544  }
1545 
1547  if (!libraries) {
1548  free(class_ids);
1549  return NULL;
1550  }
1551 
1552  rz_pvector_foreach (dex->method_ids, vit) {
1553  method_id = (DexMethodId *)*vit;
1554  bool class_found = false;
1555  for (ut32 i = 0; i < n_classes; ++i) {
1556  if (method_id->class_idx == class_ids[i]) {
1557  class_found = true;
1558  break;
1559  }
1560  }
1561  if (class_found) {
1562  continue;
1563  }
1564 
1565  char *object = dex_resolve_type_id(dex, method_id->class_idx);
1566  if (RZ_STR_ISEMPTY(object) || *object != 'L' || !strncmp(object, "Ljava/", strlen("Ljava/"))) {
1567  free(object);
1568  continue;
1569  }
1570 
1571  char *p = object;
1572  if ((p = strchr(p, '/')) && (p = strchr(p + 1, '/'))) {
1573  *p = 0;
1574  p = rz_str_newf("%s/*;", object);
1575  free(object);
1576  object = p;
1577  }
1578 
1579  if (rz_list_find(libraries, object, compare_strings)) {
1580  free(object);
1581  continue;
1582  }
1583 
1584  if (!rz_list_append(libraries, object)) {
1585  free(object);
1586  break;
1587  }
1588  }
1589 
1590  free(class_ids);
1591  return libraries;
1592 }
static RzList * libraries(RzBinFile *bf)
Definition: bin_dex.c:116
static int compare_strings(const void *a, const void *b)
Definition: dex.c:1513
void * p
Definition: libc.cpp:67
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67

References dex_method_id_t::class_idx, dex_class_def_t::class_idx, compare_strings(), dex_resolve_type_id(), free(), i, libraries(), NULL, p, rz_list_append(), rz_list_find(), rz_list_newf(), RZ_NEWS0, rz_pvector_foreach, rz_pvector_len(), rz_return_val_if_fail, RZ_STR_ISEMPTY, and rz_str_newf().

Referenced by libraries().

◆ rz_bin_dex_new()

RZ_API RZ_OWN RzBinDex* rz_bin_dex_new ( RZ_NONNULL RzBuffer buf,
ut64  base,
RZ_NONNULL Sdb kv 
)

Parses the dex file and returns a RzBinDex struct.

Definition at line 669 of file dex.c.

669  {
671 
672  RzBinDex *dex = (RzBinDex *)RZ_NEW0(RzBinDex);
673  if (!dex) {
674  return NULL;
675  }
676 
678  if (!dex->strings) {
679  rz_bin_dex_free(dex);
680  return NULL;
681  }
683  if (!dex->proto_ids) {
684  rz_bin_dex_free(dex);
685  return NULL;
686  }
688  if (!dex->field_ids) {
689  rz_bin_dex_free(dex);
690  return NULL;
691  }
693  if (!dex->method_ids) {
694  rz_bin_dex_free(dex);
695  return NULL;
696  }
698  if (!dex->class_defs) {
699  rz_bin_dex_free(dex);
700  return NULL;
701  }
702 
703  if (!dex_parse(dex, base, buf)) {
704  return NULL;
705  }
706 
707  return dex;
708 }
#define dex_method_id_free
Definition: dex.c:165
static void dex_proto_id_free(DexProtoId *string)
Definition: dex.c:104
static bool dex_parse(RzBinDex *dex, ut64 base, RzBuffer *buf)
Definition: dex.c:479
static void dex_string_free(DexString *string)
Definition: dex.c:69
#define dex_field_id_free
Definition: dex.c:147
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
Definition: dex.h:160

References dex_t::class_defs, dex_class_def_free(), dex_field_id_free, dex_method_id_free, dex_parse(), dex_proto_id_free(), dex_string_free(), dex_t::field_ids, dex_t::method_ids, NULL, dex_t::proto_ids, rz_bin_dex_free(), RZ_NEW0, rz_pvector_new(), rz_return_val_if_fail, and dex_t::strings.

Referenced by load_buffer().

◆ rz_bin_dex_relocations()

RZ_API RZ_BORROW RzBuffer* rz_bin_dex_relocations ( RZ_NONNULL RzBinDex dex)

This method will create a buffer filled with return-void values to mapped to the imports and allow the code to generate xrefs pointing to the imports

Definition at line 1821 of file dex.c.

1821  {
1823  return dex->relocs_buffer;
1824 }

References NULL, and rz_return_val_if_fail.

Referenced by virtual_files().

◆ rz_bin_dex_resolve_class_by_idx()

RZ_API RZ_OWN char* rz_bin_dex_resolve_class_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  class_idx 
)

Returns the resolved string linked to the given class id.

Definition at line 1972 of file dex.c.

1972  {
1974 
1975  return dex_resolve_type_id(dex, class_idx);
1976 }

References dex_resolve_type_id(), NULL, and rz_return_val_if_fail.

Referenced by get_name().

◆ rz_bin_dex_resolve_field_by_idx()

RZ_API RZ_OWN char* rz_bin_dex_resolve_field_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  field_idx 
)

Returns the resolved string linked to the given field id.

Definition at line 1863 of file dex.c.

1863  {
1865 
1866  if (field_idx >= rz_pvector_len(dex->field_ids)) {
1867  return NULL;
1868  }
1869 
1870  DexFieldId *field_id = (DexFieldId *)rz_pvector_at(dex->field_ids, field_idx);
1871  char *class_name = dex_resolve_type_id(dex, field_id->class_idx);
1872  if (!class_name) {
1873  return NULL;
1874  }
1875 
1876  char *name = dex_resolve_string_id(dex, field_id->name_idx);
1877  if (!name) {
1878  free(class_name);
1879  return NULL;
1880  }
1881 
1882  char *type = dex_resolve_type_id(dex, field_id->type_idx);
1883  if (!type) {
1884  free(class_name);
1885  free(name);
1886  return NULL;
1887  }
1888 
1889  char *method = rz_str_newf("%s->%s %s", class_name, name, type);
1890 
1891  free(type);
1892  free(class_name);
1893  free(name);
1894  return method;
1895 }
int type
Definition: mipsasm.c:17

References dex_resolve_string_id(), dex_resolve_type_id(), field_id, free(), NULL, rz_pvector_at(), rz_pvector_len(), rz_return_val_if_fail, rz_str_newf(), and type.

Referenced by get_name().

◆ rz_bin_dex_resolve_method_by_idx()

RZ_API RZ_OWN char* rz_bin_dex_resolve_method_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  method_idx 
)

Returns the resolved string linked to the given method id.

Definition at line 1829 of file dex.c.

1829  {
1831 
1832  if (method_idx >= rz_pvector_len(dex->method_ids)) {
1833  return NULL;
1834  }
1835 
1836  DexMethodId *method_id = (DexMethodId *)rz_pvector_at(dex->method_ids, method_idx);
1837  char *name = dex_resolve_string_id(dex, method_id->name_idx);
1838  if (!name) {
1839  return NULL;
1840  }
1841 
1842  char *proto = dex_resolve_proto_id(dex, name, method_id->proto_idx, false);
1843  RZ_FREE(name);
1844  if (!proto) {
1845  return NULL;
1846  }
1847 
1848  name = dex_resolve_type_id(dex, method_id->class_idx);
1849  if (!name) {
1850  free(proto);
1851  return NULL;
1852  }
1853 
1854  char *method = rz_str_newf("%s->%s", name, proto);
1855  free(name);
1856  free(proto);
1857  return method;
1858 }
#define RZ_FREE(x)
Definition: rz_types.h:369

References dex_method_id_t::class_idx, dex_resolve_proto_id(), dex_resolve_string_id(), dex_resolve_type_id(), free(), dex_method_id_t::name_idx, NULL, dex_method_id_t::proto_idx, RZ_FREE, rz_pvector_at(), rz_pvector_len(), rz_return_val_if_fail, and rz_str_newf().

Referenced by get_name().

◆ rz_bin_dex_resolve_method_offset_by_idx()

RZ_API ut64 rz_bin_dex_resolve_method_offset_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  method_idx 
)

Returns the resolved offset linked to the given method id.

Definition at line 1928 of file dex.c.

1928  {
1930 
1931  if (method_idx >= rz_pvector_len(dex->method_ids)) {
1932  RZ_LOG_INFO("cannot find method with index %u\n", method_idx);
1933  return UT64_MAX;
1934  }
1935 
1936  DexMethodId *method = (DexMethodId *)rz_pvector_at(dex->method_ids, method_idx);
1937  if (method->code_offset) {
1938  if (method->code_offset < RZ_DEX_RELOC_ADDRESS) {
1939  return RZ_DEX_VIRT_ADDRESS + method->code_offset;
1940  }
1941  return method->code_offset;
1942  }
1943  return UT64_MAX;
1944 }
#define UT64_MAX
Definition: rz_types_base.h:86

References dex_method_id_t::code_offset, RZ_DEX_RELOC_ADDRESS, RZ_DEX_VIRT_ADDRESS, RZ_LOG_INFO, rz_pvector_at(), rz_pvector_len(), rz_return_val_if_fail, and UT64_MAX.

Referenced by get_offset().

◆ rz_bin_dex_resolve_proto_by_idx()

RZ_API RZ_OWN char* rz_bin_dex_resolve_proto_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  proto_idx 
)

Returns the resolved string linked to the given prototype id.

Definition at line 1981 of file dex.c.

1981  {
1983 
1984  return dex_resolve_proto_id(dex, "", proto_idx, false);
1985 }

References dex_resolve_proto_id(), NULL, and rz_return_val_if_fail.

Referenced by dex_print_encoded_method(), and get_name().

◆ rz_bin_dex_resolve_string_by_idx()

RZ_API RZ_OWN char* rz_bin_dex_resolve_string_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  string_idx 
)

Returns the resolved string linked to the given string id.

Definition at line 1963 of file dex.c.

1963  {
1965 
1966  return dex_resolve_string_id(dex, string_idx);
1967 }

References dex_resolve_string_id(), NULL, and rz_return_val_if_fail.

Referenced by dex_print_encoded_field(), dex_print_encoded_method(), get_name(), and rz_bin_dex_resolve_type_id_by_idx().

◆ rz_bin_dex_resolve_string_offset_by_idx()

RZ_API ut64 rz_bin_dex_resolve_string_offset_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  string_idx 
)

Returns the resolved offset linked to the given string id.

Definition at line 1900 of file dex.c.

1900  {
1902 
1903  DexString *string = dex_resolve_string_id_native(dex, string_idx);
1904  if (!string) {
1905  RZ_LOG_INFO("cannot find string with index %u\n", string_idx);
1906  return UT64_MAX;
1907  }
1908  return RZ_DEX_VIRT_ADDRESS + string->offset;
1909 }

References dex_resolve_string_id_native(), RZ_DEX_VIRT_ADDRESS, RZ_LOG_INFO, rz_return_val_if_fail, and UT64_MAX.

Referenced by get_offset(), and rz_bin_dex_resolve_type_id_offset_by_idx().

◆ rz_bin_dex_resolve_symbol()

RZ_API RZ_OWN RzBinAddr* rz_bin_dex_resolve_symbol ( RZ_NONNULL RzBinDex dex,
RzBinSpecialSymbol  resolve 
)

Returns a RzBinAddr pointer containing the resolved RzBinSpecialSymbol.

Definition at line 1670 of file dex.c.

1670  {
1672 
1673  DexClassDef *class_def;
1674  void **it;
1675 
1676  RzBinAddr *ret = RZ_NEW0(RzBinAddr);
1677  if (!ret) {
1678  return NULL;
1679  }
1680  ret->paddr = UT64_MAX;
1681  ret->vaddr = UT64_MAX;
1682 
1683  rz_pvector_foreach (dex->class_defs, it) {
1684  class_def = (DexClassDef *)*it;
1685  if (dex_resolve_symbol_in_class_methods(dex, class_def, resolve, &ret->paddr, &ret->vaddr)) {
1686  break;
1687  }
1688  }
1689 
1690  return ret;
1691 }
static bool dex_resolve_symbol_in_class_methods(RzBinDex *dex, DexClassDef *class_def, RzBinSpecialSymbol resolve, ut64 *paddr, ut64 *vaddr)
Definition: dex.c:1594

References dex_resolve_symbol_in_class_methods(), NULL, rz_bin_addr_t::paddr, resolve(), RZ_NEW0, rz_pvector_foreach, rz_return_val_if_fail, UT64_MAX, and rz_bin_addr_t::vaddr.

Referenced by binsym().

◆ rz_bin_dex_resolve_type_id_by_idx()

RZ_API RZ_OWN char* rz_bin_dex_resolve_type_id_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  type_idx 
)

Returns the resolved string linked to the given type id.

Definition at line 1949 of file dex.c.

1949  {
1951 
1952  if (type_idx >= dex->type_ids_size) {
1953  RZ_LOG_INFO("cannot find type_id with index %u\n", type_idx);
1954  return NULL;
1955  }
1956  DexTypeId type_id = dex->types[type_idx];
1957  return rz_bin_dex_resolve_string_by_idx(dex, type_id);
1958 }
RZ_API RZ_OWN char * rz_bin_dex_resolve_string_by_idx(RZ_NONNULL RzBinDex *dex, ut32 string_idx)
Returns the resolved string linked to the given string id.
Definition: dex.c:1963

References NULL, rz_bin_dex_resolve_string_by_idx(), RZ_LOG_INFO, and rz_return_val_if_fail.

Referenced by dex_print_class_def(), dex_print_class_def_exports(), dex_print_encoded_field(), and dex_print_encoded_method().

◆ rz_bin_dex_resolve_type_id_offset_by_idx()

RZ_API ut64 rz_bin_dex_resolve_type_id_offset_by_idx ( RZ_NONNULL RzBinDex dex,
ut32  type_idx 
)

Returns the resolved offset linked to the given type id.

Definition at line 1914 of file dex.c.

1914  {
1916 
1917  if (type_idx >= dex->type_ids_size) {
1918  RZ_LOG_INFO("cannot find type_id with index %u\n", type_idx);
1919  return UT64_MAX;
1920  }
1921  DexTypeId type_id = dex->types[type_idx];
1922  return rz_bin_dex_resolve_string_offset_by_idx(dex, type_id);
1923 }
RZ_API ut64 rz_bin_dex_resolve_string_offset_by_idx(RZ_NONNULL RzBinDex *dex, ut32 string_idx)
Returns the resolved offset linked to the given string id.
Definition: dex.c:1900

References rz_bin_dex_resolve_string_offset_by_idx(), RZ_LOG_INFO, rz_return_val_if_fail, and UT64_MAX.

Referenced by get_offset().

◆ rz_bin_dex_sections()

RZ_API RZ_OWN RzList* rz_bin_dex_sections ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinSection*> containing the dex sections.

Definition at line 1200 of file dex.c.

1200  {
1202 
1204  RzList *sections = NULL;
1205 
1207  if (!sections) {
1208  return NULL;
1209  }
1210  section = section_new("data", RZ_PERM_RWX, dex->data_size, dex->data_offset, RZ_DEX_VIRT_ADDRESS + dex->data_offset);
1211  if (section && !rz_list_append(sections, section)) {
1213  }
1214  section = section_new("file", RZ_PERM_R, dex->file_size, dex->header_offset, 0);
1215  if (section && !rz_list_append(sections, section)) {
1217  }
1218 
1219  if (dex->relocs_code) {
1220  section = section_new(RZ_DEX_RELOC_TARGETS, RZ_PERM_RWX, dex->relocs_size, 0, dex->relocs_offset);
1221  if (section && !rz_list_append(sections, section)) {
1223  }
1224  }
1225 
1226  return sections;
1227 }
RZ_API void rz_bin_section_free(RzBinSection *bs)
Definition: bin.c:1116
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
static RzBinSection * section_new(const char *name, ut32 perm, ut32 size, ut64 paddr, ut64 vaddr)
Definition: dex.c:1184
#define RZ_DEX_RELOC_TARGETS
Definition: dex.h:12
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_PERM_RWX
Definition: rz_types.h:98

References NULL, rz_bin_section_free(), RZ_DEX_RELOC_TARGETS, RZ_DEX_VIRT_ADDRESS, rz_list_append(), rz_list_newf(), RZ_PERM_R, RZ_PERM_RWX, rz_return_val_if_fail, section_new(), and sections().

Referenced by sections().

◆ rz_bin_dex_sha1()

RZ_API void rz_bin_dex_sha1 ( RZ_NONNULL RzBinDex dex,
RZ_NONNULL RzBinHash hash 
)

Sets the RzBinHash dex digest (sha1)

Definition at line 2003 of file dex.c.

2003  {
2004  rz_return_if_fail(dex && hash);
2005  hash->type = "sha1";
2006  hash->len = 20;
2007  hash->addr = dex->signature_offset;
2008  hash->from = dex->signature_offset + sizeof(dex->signature);
2009  hash->to = dex->file_size - hash->from;
2010  memcpy(hash->buf, dex->signature, sizeof(dex->signature));
2011 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))

References memcpy(), and rz_return_if_fail.

Referenced by info().

◆ rz_bin_dex_strings()

RZ_API RZ_OWN RzList* rz_bin_dex_strings ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinString*> containing the dex strings.

Definition at line 735 of file dex.c.

735  {
737 
738  DexString *string;
739  void **it;
741  if (!strings) {
742  return NULL;
743  }
744 
745  ut32 ordinal = 0;
746  rz_pvector_foreach (dex->strings, it) {
747  string = (DexString *)*it;
749  if (!bstr) {
750  continue;
751  }
752  bstr->paddr = string->offset;
753  bstr->vaddr = RZ_DEX_VIRT_ADDRESS + string->offset;
754  bstr->ordinal = ordinal;
755  bstr->length = string->size;
756  bstr->size = string->size;
757  bstr->string = rz_str_ndup(string->data, string->size);
758  bstr->type = RZ_STRING_ENC_UTF8;
759  if (!rz_list_append(strings, bstr)) {
760  free(bstr);
761  }
762  ordinal++;
763  }
764  return strings;
765 }
RZ_API void rz_bin_string_free(void *_str)
Definition: bin.c:192
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type strings(--mime-type and\n" " --mime-encoding)\n") OPT('s'
@ RZ_STRING_ENC_UTF8
Definition: rz_str.h:21
ut32 ordinal
Definition: rz_bin.h:755
char * string
Definition: rz_bin.h:752

References dex_string_t::data, free(), rz_bin_string_t::length, NULL, rz_bin_string_t::ordinal, rz_bin_string_t::paddr, rz_bin_string_free(), RZ_DEX_VIRT_ADDRESS, rz_list_append(), rz_list_newf(), RZ_NEW0, rz_pvector_foreach, rz_return_val_if_fail, rz_str_ndup(), RZ_STRING_ENC_UTF8, dex_string_t::size, rz_bin_string_t::size, rz_bin_string_t::string, strings(), rz_bin_string_t::type, and rz_bin_string_t::vaddr.

Referenced by strings().

◆ rz_bin_dex_symbols()

RZ_API RZ_OWN RzList* rz_bin_dex_symbols ( RZ_NONNULL RzBinDex dex)

Returns a RzList<RzBinSymbol*> containing the dex symbols.

Definition at line 1267 of file dex.c.

1267  {
1269 
1270  DexClassDef *class_def;
1272  DexMethodId *method_id;
1273  RzList *class_symbols = NULL;
1274  RzList *symbols = NULL;
1275  void **vit;
1276  ut8 *inserted_methods = NULL;
1277  ut8 *inserted_fields = NULL;
1278  ut32 n_methods = rz_pvector_len(dex->method_ids);
1279  ut32 n_fields = rz_pvector_len(dex->field_ids);
1280 
1281  inserted_methods = RZ_NEWS0(ut8, n_methods);
1282  inserted_fields = RZ_NEWS0(ut8, n_fields);
1283  if ((n_methods > 0 && !inserted_methods) || (n_fields > 0 && !inserted_fields)) {
1284  free(inserted_fields);
1285  free(inserted_methods);
1286  return NULL;
1287  }
1288 
1290  if (!symbols) {
1291  free(inserted_fields);
1292  free(inserted_methods);
1293  return NULL;
1294  }
1295 
1296  rz_pvector_foreach (dex->class_defs, vit) {
1297  class_def = (DexClassDef *)*vit;
1298 
1299  class_symbols = dex_resolve_fields_in_class_as_symbols(dex, class_def, inserted_fields);
1300  if (class_symbols) {
1301  rz_list_join(symbols, class_symbols);
1302  rz_list_free(class_symbols);
1303  }
1304 
1305  class_symbols = dex_resolve_methods_in_class(dex, class_def, inserted_methods);
1306  if (class_symbols) {
1307  rz_list_join(symbols, class_symbols);
1308  rz_list_free(class_symbols);
1309  }
1310  }
1311 
1312  ut32 j = 0;
1313  rz_pvector_foreach (dex->field_ids, vit) {
1314  field_id = (DexFieldId *)*vit;
1315  if (inserted_fields[j++]) {
1316  continue;
1317  }
1318 
1319  RzBinSymbol *field = RZ_NEW0(RzBinSymbol);
1320  if (!field) {
1321  break;
1322  }
1323 
1324  field->name = dex_resolve_string_id(dex, field_id->name_idx);
1325  field->classname = dex_resolve_type_id(dex, field_id->class_idx);
1326  field->libname = dex_resolve_library(field->classname);
1327  field->bind = RZ_BIN_BIND_WEAK_STR;
1328  field->type = RZ_BIN_TYPE_FIELD_STR;
1329  field->is_imported = true;
1330 
1331  if (!rz_list_append(symbols, field)) {
1332  rz_bin_symbol_free(field);
1333  break;
1334  }
1335  }
1336 
1337  j = 0;
1338  rz_pvector_foreach (dex->method_ids, vit) {
1339  method_id = (DexMethodId *)*vit;
1340  if (inserted_methods[j++]) {
1341  continue;
1342  }
1343 
1344  RzBinSymbol *method = RZ_NEW0(RzBinSymbol);
1345  if (!method) {
1346  break;
1347  }
1348 
1349  method->name = dex_resolve_string_id(dex, method_id->name_idx);
1350  method->classname = dex_resolve_type_id(dex, method_id->class_idx);
1351  method->libname = dex_resolve_library(method->classname);
1352  method->dname = dex_resolve_proto_id(dex, method->name, method_id->proto_idx, false);
1353  method->bind = RZ_BIN_BIND_WEAK_STR;
1354  method->is_imported = true;
1355  method->type = RZ_BIN_TYPE_METH_STR;
1356  if (method_id->code_offset < RZ_DEX_RELOC_ADDRESS) {
1357  method->vaddr = RZ_DEX_VIRT_ADDRESS + method_id->code_offset;
1358  method->paddr = method_id->code_offset;
1359  } else {
1360  method->vaddr = method_id->code_offset;
1361  method->paddr = 0;
1362  }
1363  method->size = method_id->code_size;
1364 
1365  if (!rz_list_append(symbols, method)) {
1366  rz_bin_symbol_free(method);
1367  break;
1368  }
1369  }
1370 
1371  free(inserted_fields);
1372  free(inserted_methods);
1373  return symbols;
1374 }
RzList * symbols(RzBinFile *bf)
Definition: bin_ne.c:102
static RzList * dex_resolve_fields_in_class_as_symbols(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
Definition: dex.c:1075

References rz_bin_symbol_t::bind, dex_method_id_t::class_idx, rz_bin_symbol_t::classname, dex_method_id_t::code_offset, dex_method_id_t::code_size, dex_resolve_fields_in_class_as_symbols(), dex_resolve_library(), dex_resolve_methods_in_class(), dex_resolve_proto_id(), dex_resolve_string_id(), dex_resolve_type_id(), rz_bin_symbol_t::dname, field_id, free(), rz_bin_symbol_t::is_imported, rz_bin_symbol_t::libname, rz_bin_symbol_t::name, dex_method_id_t::name_idx, NULL, rz_bin_symbol_t::paddr, dex_method_id_t::proto_idx, RZ_BIN_BIND_WEAK_STR, rz_bin_symbol_free(), RZ_BIN_TYPE_FIELD_STR, RZ_BIN_TYPE_METH_STR, RZ_DEX_RELOC_ADDRESS, RZ_DEX_VIRT_ADDRESS, rz_list_append(), rz_list_free(), rz_list_join(), rz_list_newf(), RZ_NEW0, RZ_NEWS0, rz_pvector_foreach, rz_pvector_len(), rz_return_val_if_fail, rz_bin_symbol_t::size, symbols(), rz_bin_symbol_t::type, and rz_bin_symbol_t::vaddr.

Referenced by symbols().

◆ rz_bin_dex_version()

RZ_API RZ_OWN char* rz_bin_dex_version ( RZ_NONNULL RzBinDex dex)

Returns the dex version (string format)

Definition at line 2016 of file dex.c.

2016  {
2018  // https://cs.android.com/android/platform/superproject/+/master:dalvik/dx/src/com/android/dex/DexFormat.java;l=55;bpv=1;bpt=0
2019  // https://developer.android.com/studio/releases/platforms
2020  if (!strncmp((char *)dex->version, "009", 3)) {
2021  return strdup("Android M3 release (Nov-Dec 2007)");
2022  } else if (!strncmp((char *)dex->version, "013", 3)) {
2023  return strdup("Android M5 release (Feb-Mar 2008)");
2024  } else if (!strncmp((char *)dex->version, "035", 3)) {
2025  return strdup("Android 3.2 (API level 13 and earlier)");
2026  } else if (!strncmp((char *)dex->version, "037", 3)) {
2027  return strdup("Android 7 (API level 24 and earlier)");
2028  } else if (!strncmp((char *)dex->version, "038", 3)) {
2029  return strdup("Android 8 (API level 26 and earlier)");
2030  } else if (!strncmp((char *)dex->version, "039", 3)) {
2031  return strdup("Android 9 (API level 28 and earlier)");
2032  } else if (!strncmp((char *)dex->version, "040", 3)) {
2033  return strdup("Android 10+ (Aug 2019)");
2034  }
2035  return NULL;
2036 }

References NULL, rz_return_val_if_fail, and strdup().

Referenced by info(), and rz_cmd_dexs_handler().

◆ section_new()

static RzBinSection* section_new ( const char *  name,
ut32  perm,
ut32  size,
ut64  paddr,
ut64  vaddr 
)
static

Definition at line 1184 of file dex.c.

1184  {
1186  if (!section) {
1187  return NULL;
1188  }
1189  section->name = strdup(name);
1190  section->paddr = paddr;
1191  section->vaddr = vaddr;
1192  section->size = section->vsize = size;
1193  section->perm = perm;
1194  return section;
1195 }
uint32_t size

References NULL, RZ_NEW0, section::size, and strdup().

Referenced by rz_bin_dex_sections().

Variable Documentation

◆ access_flags_list

Initial value:
= {
{ ACCESS_FLAG_PUBLIC , "public" },
{ ACCESS_FLAG_PRIVATE , "private" },
{ ACCESS_FLAG_PROTECTED , "protected" },
{ ACCESS_FLAG_STATIC , "static" },
{ ACCESS_FLAG_FINAL , "final" },
{ ACCESS_FLAG_SYNCHRONIZED , "synchronized" },
{ ACCESS_FLAG_BRIDGE , "bridge" },
{ ACCESS_FLAG_VARARGS , "varargs" },
{ ACCESS_FLAG_NATIVE , "native" },
{ ACCESS_FLAG_INTERFACE , "interface" },
{ ACCESS_FLAG_ABSTRACT , "abstract" },
{ ACCESS_FLAG_STRICT , "strict" },
{ ACCESS_FLAG_SYNTHETIC , "synthetic" },
{ ACCESS_FLAG_ANNOTATION , "annotation" },
{ ACCESS_FLAG_ENUM , "enum" },
{ ACCESS_FLAG_MODULE , "module" },
{ ACCESS_FLAG_CONSTRUCTOR , "constructor" },
{ ACCESS_FLAG_DECLARED_SYNCHRONIZED , "synchronized" },
}
@ ACCESS_FLAG_MODULE
Definition: dex.h:56
@ ACCESS_FLAG_ENUM
Definition: dex.h:55
@ ACCESS_FLAG_ANNOTATION
Definition: dex.h:54
@ ACCESS_FLAG_INTERFACE
Definition: dex.h:50

Definition at line 48 of file dex.c.

Referenced by rz_bin_dex_access_flags_readable().