Rizin
unix-like reverse engineering framework and cli tools
dex.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
2 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include "dex.h"
6 #include <rz_util.h>
7 
8 #define DEX_INVALID_CLASS "Lunknown_class;"
9 #define DEX_INVALID_METHOD "unknown_method"
10 
13  const char *readable;
15 
16 #define read_le_bits_or_fail(bits, buf, val, fail) \
17  do { \
18  if (!rz_buf_read_le##bits(buf, &val)) { \
19  goto fail; \
20  } \
21  } while (0)
22 
23 #define read_le_at_bits_or_fail(bits, buf, val, offset, fail) \
24  do { \
25  if (!rz_buf_read_le##bits##_at(buf, offset, &val)) { \
26  goto fail; \
27  } \
28  } while (0)
29 
30 #define read_le32_or_fail(buf, val, fail) read_le_bits_or_fail(32, buf, val, fail)
31 #define read_le16_or_fail(buf, val, fail) read_le_bits_or_fail(16, buf, val, fail)
32 #define read_le32_at_or_fail(buf, val, offset, fail) read_le_at_bits_or_fail(32, buf, val, offset, fail)
33 #define read_le16_at_or_fail(buf, val, offset, fail) read_le_at_bits_or_fail(16, buf, val, offset, fail)
34 
35 #define dex_is_static(a) (a & ACCESS_FLAG_STATIC)
36 #define dex_is_varargs(a) (a & ACCESS_FLAG_VARARGS)
37 
38 #define dex_fail_if_bad_ids(name, z, s, g) \
39  do { \
40  ut64 end = name##_offset; \
41  end += name##_size * (z); \
42  if (end >= (s)) { \
43  goto g; \
44  } \
45  } while (0)
46 
47 #define CLASS_ACCESS_FLAGS_SIZE 18
49  { ACCESS_FLAG_PUBLIC /* */, "public" },
50  { ACCESS_FLAG_PRIVATE /* */, "private" },
51  { ACCESS_FLAG_PROTECTED /* */, "protected" },
52  { ACCESS_FLAG_STATIC /* */, "static" },
53  { ACCESS_FLAG_FINAL /* */, "final" },
54  { ACCESS_FLAG_SYNCHRONIZED /* */, "synchronized" },
55  { ACCESS_FLAG_BRIDGE /* */, "bridge" },
56  { ACCESS_FLAG_VARARGS /* */, "varargs" },
57  { ACCESS_FLAG_NATIVE /* */, "native" },
58  { ACCESS_FLAG_INTERFACE /* */, "interface" },
59  { ACCESS_FLAG_ABSTRACT /* */, "abstract" },
60  { ACCESS_FLAG_STRICT /* */, "strict" },
61  { ACCESS_FLAG_SYNTHETIC /* */, "synthetic" },
62  { ACCESS_FLAG_ANNOTATION /* */, "annotation" },
63  { ACCESS_FLAG_ENUM /* */, "enum" },
64  { ACCESS_FLAG_MODULE /* */, "module" },
65  { ACCESS_FLAG_CONSTRUCTOR /* */, "constructor" },
66  { ACCESS_FLAG_DECLARED_SYNCHRONIZED , "synchronized" },
67 };
68 
69 static void dex_string_free(DexString *string) {
70  if (!string) {
71  return;
72  }
73  free(string->data);
74  free(string);
75 }
76 
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 }
103 
104 static void dex_proto_id_free(DexProtoId *string) {
105  if (!string) {
106  return;
107  }
108  free(string->type_list);
109  free(string);
110 }
111 
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 }
146 
147 #define dex_field_id_free free
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 }
164 
165 #define dex_method_id_free free
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 }
182 
183 static void dex_class_def_free(DexClassDef *class_def) {
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 }
194 
195 static DexEncodedField *dex_new_encoded_field(RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first) {
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 }
215 
216 static DexEncodedMethod *dex_new_encoded_method(RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first, RzPVector *method_ids) {
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 }
261 
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 }
358 
359 static void dex_resolve_virtual_method_code(RzBinDex *dex, DexMethodId *to_resolve, ut32 superclass_idx) {
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 }
376 
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 }
392 
393 static bool dex_create_relocations(RzBinDex *dex) {
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 }
478 
479 static bool dex_parse(RzBinDex *dex, ut64 base, RzBuffer *buf) {
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 }
645 
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 }
665 
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 }
709 
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 }
731 
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 }
766 
767 static inline DexString *dex_resolve_string_id_native(RzBinDex *dex, ut32 string_idx) {
768  if (string_idx >= rz_pvector_len(dex->strings)) {
769  return NULL;
770  }
771  return (DexString *)rz_pvector_at(dex->strings, string_idx);
772 }
773 
774 static char *dex_resolve_string_id(RzBinDex *dex, ut32 string_idx) {
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 }
782 
783 static char *dex_resolve_type_id(RzBinDex *dex, ut32 type_idx) {
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 }
791 
792 static char *dex_resolve_proto_id(RzBinDex *dex, const char *name, ut32 proto_idx, bool varargs) {
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 }
835 
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 }
898 
899 static char *dex_resolve_library(const char *library) {
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 }
908 
909 static RzBinSymbol *dex_method_to_symbol(RzBinDex *dex, DexEncodedMethod *encoded_method, DexMethodId *method_id, bool is_imported) {
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 }
938 
939 static RzList /*<RzBinSymbol *>*/ *dex_resolve_methods_in_class(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted) {
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 }
985 
986 static RzBinField *dex_field_to_bin_field(RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_static) {
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 }
1007 
1008 static RzList /*<RzBinField *>*/ *dex_resolve_fields_in_class(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted) {
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 }
1052 
1053 static RzBinSymbol *dex_field_to_symbol(RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_imported) {
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 }
1074 
1075 static RzList /*<RzBinSymbol *>*/ *dex_resolve_fields_in_class_as_symbols(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted) {
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 }
1115 
1116 static void free_rz_bin_class(RzBinClass *bclass) {
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 }
1127 
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 }
1183 
1184 static RzBinSection *section_new(const char *name, ut32 perm, ut32 size, ut64 paddr, ut64 vaddr) {
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 }
1196 
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 }
1228 
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 }
1263 
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 }
1375 
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 }
1512 
1513 static int compare_strings(const void *a, const void *b) {
1514  return strcmp((const char *)a, (const char *)b);
1515 }
1516 
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 }
1593 
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 }
1666 
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 }
1692 
1693 static RzList /*<RzBinAddr *>*/ *dex_resolve_entrypoints_in_class(RzBinDex *dex, DexClassDef *class_def) {
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 }
1788 
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 }
1816 
1823  return dex->relocs_buffer;
1824 }
1825 
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 }
1859 
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 }
1896 
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 }
1910 
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 }
1924 
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 }
1945 
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 }
1959 
1965 
1966  return dex_resolve_string_id(dex, string_idx);
1967 }
1968 
1974 
1975  return dex_resolve_type_id(dex, class_idx);
1976 }
1977 
1983 
1984  return dex_resolve_proto_id(dex, "", proto_idx, false);
1985 }
1986 
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 }
1999 
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 }
2012 
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 }
2037 
2042  rz_return_val_if_fail(dex, 0);
2043  // TODO
2044  return 0;
2045 }
const aarch64_field fields[]
Definition: aarch64-opc.c:205
lzma_index ** i
Definition: index.h:629
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
RZ_API void rz_bin_string_free(void *_str)
Definition: bin.c:192
RZ_API void rz_bin_field_free(RzBinField *field)
Definition: bin.c:950
RZ_API void rz_bin_import_free(RzBinImport *imp)
Definition: bin.c:137
RZ_API void rz_bin_section_free(RzBinSection *bs)
Definition: bin.c:1116
static RzList * classes(RzBinFile *bf)
Definition: bin_dex.c:71
static RzList * libraries(RzBinFile *bf)
Definition: bin_dex.c:116
static RzList * entrypoints(RzBinFile *bf)
Definition: bin_dex.c:134
static SblHeader sb
Definition: bin_mbn.c:26
RzList * symbols(RzBinFile *bf)
Definition: bin_ne.c:102
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
#define RZ_API
#define NULL
Definition: cris-opc.c:27
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
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
uint16_t ut16
uint32_t ut32
RZ_API RZ_OWN RzList * rz_bin_dex_symbols(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinSymbol*> containing the dex symbols.
Definition: dex.c:1267
RZ_API RZ_OWN RzList * rz_bin_dex_libraries(RZ_NONNULL RzBinDex *dex)
Returns a RzList<char*> containing the dex libraries.
Definition: dex.c:1520
#define dex_method_id_free
Definition: dex.c:165
static RzList * dex_resolve_fields_in_class(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
Definition: dex.c:1008
static RzBinSection * section_new(const char *name, ut32 perm, ut32 size, ut64 paddr, ut64 vaddr)
Definition: dex.c:1184
static RzBinField * dex_field_to_bin_field(RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_static)
Definition: dex.c:986
static RzBinSymbol * dex_field_to_symbol(RzBinDex *dex, DexEncodedField *encoded_field, DexFieldId *field_id, bool is_imported)
Definition: dex.c:1053
#define read_le32_at_or_fail(buf, val, offset, fail)
Definition: dex.c:32
static const DexAccessFlagsReadable access_flags_list[CLASS_ACCESS_FLAGS_SIZE]
Definition: dex.c:48
RZ_API void rz_bin_dex_checksum(RZ_NONNULL RzBinDex *dex, RZ_NONNULL RzBinHash *hash)
Sets the RzBinHash dex checksum (adler32)
Definition: dex.c:1990
static void dex_proto_id_free(DexProtoId *string)
Definition: dex.c:104
struct dex_access_flags_readable_t DexAccessFlagsReadable
static RzList * dex_resolve_fields_in_class_as_symbols(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
Definition: dex.c:1075
RZ_API void rz_bin_dex_free(RZ_NULLABLE RzBinDex *dex)
Frees a RzBinDex struct.
Definition: dex.c:649
static RzList * dex_resolve_methods_in_class(RzBinDex *dex, DexClassDef *class_def, ut8 *inserted)
Definition: dex.c:939
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: dex.c:1972
static char * dex_resolve_string_id(RzBinDex *dex, ut32 string_idx)
Definition: dex.c:774
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
static DexEncodedField * dex_new_encoded_field(RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first)
Definition: dex.c:195
#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
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: dex.c:1928
#define read_le16_at_or_fail(buf, val, offset, fail)
Definition: dex.c:33
static ut64 dex_access_flags_to_bin_flags(ut64 access_flags)
Definition: dex.c:836
static void free_rz_bin_class(RzBinClass *bclass)
Definition: dex.c:1116
static bool dex_parse(RzBinDex *dex, ut64 base, RzBuffer *buf)
Definition: dex.c:479
static DexMethodId * dex_method_id_new(RzBuffer *buf, ut64 offset)
Definition: dex.c:166
#define read_le32_or_fail(buf, val, fail)
Definition: dex.c:30
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: dex.c:1829
static bool dex_resolve_symbol_in_class_methods(RzBinDex *dex, DexClassDef *class_def, RzBinSpecialSymbol resolve, ut64 *paddr, ut64 *vaddr)
Definition: dex.c:1594
static char * dex_resolve_type_id(RzBinDex *dex, ut32 type_idx)
Definition: dex.c:783
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: dex.c:1670
#define dex_is_varargs(a)
Definition: dex.c:36
RZ_API RZ_BORROW RzBuffer * rz_bin_dex_relocations(RZ_NONNULL RzBinDex *dex)
Definition: dex.c:1821
RZ_API RZ_OWN RzList * rz_bin_dex_fields(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinField*> containing the dex fields.
Definition: dex.c:1232
static DexString * dex_resolve_string_id_native(RzBinDex *dex, ut32 string_idx)
Definition: dex.c:767
static RzList * dex_resolve_entrypoints_in_class(RzBinDex *dex, DexClassDef *class_def)
Definition: dex.c:1693
static void dex_string_free(DexString *string)
Definition: dex.c:69
RZ_API RZ_OWN RzList * rz_bin_dex_sections(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinSection*> containing the dex sections.
Definition: dex.c:1200
static void dex_resolve_virtual_method_code(RzBinDex *dex, DexMethodId *to_resolve, ut32 superclass_idx)
Definition: dex.c:359
RZ_API ut64 rz_bin_dex_debug_info(RZ_NONNULL RzBinDex *dex)
Returns the dex debug info RzBin values.
Definition: dex.c:2041
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: dex.c:669
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
static DexClassDef * dex_class_def_new(RzBuffer *buf, ut64 offset, ut64 base, RzPVector *method_ids)
Definition: dex.c:262
#define dex_is_static(a)
Definition: dex.c:35
static char * dex_resolve_library(const char *library)
Definition: dex.c:899
RZ_API RZ_OWN RzList * rz_bin_dex_classes(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinClass*> containing the dex classes.
Definition: dex.c:1131
RZ_API RZ_OWN RzList * rz_bin_dex_entrypoints(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinAddr*> containing the dex entripoints.
Definition: dex.c:1792
static DexString * dex_string_new(RzBuffer *buf, ut64 offset, st64 *pread)
Definition: dex.c:77
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: dex.c:1949
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: dex.c:1863
RZ_API RZ_OWN RzList * rz_bin_dex_imports(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinImport*> containing the dex imports.
Definition: dex.c:1379
static DexEncodedMethod * dex_new_encoded_method(RzBuffer *buf, ut64 base, ut64 *diff_value_prev, bool first, RzPVector *method_ids)
Definition: dex.c:216
RZ_API RZ_OWN char * rz_bin_dex_version(RZ_NONNULL RzBinDex *dex)
Returns the dex version (string format)
Definition: dex.c:2016
RZ_API RZ_OWN char * rz_bin_dex_access_flags_readable(ut32 access_flags)
Definition: dex.c:710
static void dex_class_def_free(DexClassDef *class_def)
Definition: dex.c:183
static DexProtoId * dex_proto_id_new(RzBuffer *buf, ut64 offset)
Definition: dex.c:112
#define read_le16_or_fail(buf, val, fail)
Definition: dex.c:31
static bool dex_create_relocations(RzBinDex *dex)
Definition: dex.c:393
RZ_API RZ_OWN RzList * rz_bin_dex_strings(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinString*> containing the dex strings.
Definition: dex.c:735
static char * dex_resolve_proto_id(RzBinDex *dex, const char *name, ut32 proto_idx, bool varargs)
Definition: dex.c:792
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: dex.c:1914
static int compare_strings(const void *a, const void *b)
Definition: dex.c:1513
RZ_API void rz_bin_dex_sha1(RZ_NONNULL RzBinDex *dex, RZ_NONNULL RzBinHash *hash)
Sets the RzBinHash dex digest (sha1)
Definition: dex.c:2003
static RzBinSymbol * dex_method_to_symbol(RzBinDex *dex, DexEncodedMethod *encoded_method, DexMethodId *method_id, bool is_imported)
Definition: dex.c:909
#define dex_field_id_free
Definition: dex.c:147
#define CLASS_ACCESS_FLAGS_SIZE
Definition: dex.c:47
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: dex.c:1981
static void dex_resolve_all_virtual_methods(RzBinDex *dex)
Definition: dex.c:377
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'
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 RZ_DEX_RELOC_ADDRESS
Definition: dex.h:14
#define DEX_TYPE_ID_SIZE
Definition: dex.h:78
@ ACCESS_FLAG_MODULE
Definition: dex.h:56
@ 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_ENUM
Definition: dex.h:55
@ ACCESS_FLAG_PROTECTED
Definition: dex.h:43
@ ACCESS_FLAG_STATIC
Definition: dex.h:44
@ ACCESS_FLAG_ANNOTATION
Definition: dex.h:54
@ 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_INTERFACE
Definition: dex.h:50
@ ACCESS_FLAG_PUBLIC
Definition: dex.h:41
#define RZ_DEX_VIRT_ADDRESS
Definition: dex.h:13
#define DEX_FIELD_ID_SIZE
Definition: dex.h:95
#define RZ_DEX_RELOC_TARGETS
Definition: dex.h:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static void list(RzEgg *egg)
Definition: rz-gg.c:52
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 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 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
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 void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * malloc(size_t size)
Definition: malloc.c:123
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")
int type
Definition: mipsasm.c:17
@ field_id
Definition: parser.c:1736
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_BIN_BIND_WEAK_STR
Definition: rz_bin.h:108
#define RZ_BIN_TYPE_FIELD_STR
Definition: rz_bin.h:120
#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_TYPE_METH_STR
Definition: rz_bin.h:122
#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
RzBinSpecialSymbol
Definition: rz_bin.h:136
@ 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
#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_BIND_LOCAL_STR
Definition: rz_bin.h:106
#define RZ_BIN_BIND_GLOBAL_STR
Definition: rz_bin.h:107
#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_TYPE_FUNC_STR
Definition: rz_bin.h:119
#define RZ_BIN_METH_NATIVE
Definition: rz_bin.h:97
RZ_API ut64 rz_buf_tell(RZ_NONNULL RzBuffer *b)
Return the current cursor position.
Definition: buf.c:1238
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
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 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
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
static void rz_write_le32(void *dest, ut32 val)
Definition: rz_endian.h:256
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
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
RZ_API const char * rz_str_rchr(const char *base, const char *p, int ch)
Definition: str.c:829
@ RZ_STRING_ENC_UTF8
Definition: rz_str.h:21
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API int rz_str_replace_ch(char *s, char a, char b, bool g)
Definition: str.c:139
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
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_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l)
Definition: strbuf.c:229
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define PFMT64u
Definition: rz_types.h:395
#define RZ_PERM_RWX
Definition: rz_types.h:98
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_BORROW
Definition: rz_types.h:63
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT64_MAX
Definition: rz_types_base.h:86
static void ** rz_pvector_reserve(RzPVector *vec, size_t capacity)
Definition: rz_vector.h:312
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
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
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
const char * readable
Definition: dex.c:13
RzList * instance_fields
Definition: dex.h:154
RzList * direct_methods
Definition: dex.h:155
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
ut16 * interfaces
Definition: dex.h:151
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
RzList * virtual_methods
Definition: dex.h:156
RzList * static_fields
Definition: dex.h:153
ut64 field_idx
Definition: dex.h:110
ut64 access_flags
Definition: dex.h:111
ut16 registers_size
Definition: dex.h:120
ut64 code_offset
Definition: dex.h:126
ut32 debug_info_offset
Definition: dex.h:124
ut64 access_flags
Definition: dex.h:117
ut64 code_size
Definition: dex.h:104
ut32 name_idx
Definition: dex.h:100
ut16 class_idx
Definition: dex.h:98
ut64 code_offset
Definition: dex.h:103
ut16 proto_idx
Definition: dex.h:99
ut64 offset
Definition: dex.h:101
ut32 shorty_idx
Definition: dex.h:81
ut64 offset
Definition: dex.h:85
ut32 return_type_idx
Definition: dex.h:82
ut16 * type_list
Definition: dex.h:84
ut32 type_list_size
Definition: dex.h:83
char * data
Definition: dex.h:73
ut64 size
Definition: dex.h:71
Definition: dex.h:160
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
ut64 relocs_offset
Definition: dex.h:198
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 relocs_size
Definition: dex.h:199
ut8 * relocs_code
Definition: dex.h:200
RzPVector * method_ids
Definition: dex.h:193
ut32 header_size
Definition: dex.h:169
RzPVector * field_ids
Definition: dex.h:192
ut32 data_offset
Definition: dex.h:187
RzPVector * class_defs
Definition: dex.h:194
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
RzBuffer * relocs_buffer
Definition: dex.h:201
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
Definition: z80asm.h:102
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
char * super
Definition: rz_bin.h:649
RzList * fields
Definition: rz_bin.h:654
char * name
Definition: rz_bin.h:647
int visibility
Definition: rz_bin.h:656
RzList * methods
Definition: rz_bin.h:653
char * visibility_str
Definition: rz_bin.h:650
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
ut32 ordinal
Definition: rz_bin.h:755
char * string
Definition: rz_bin.h:752
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
char * dname
Definition: rz_bin.h:676
ut64 method_flags
Definition: rz_bin.h:696
ut32 visibility
Definition: rz_bin.h:693
char * libname
Definition: rz_bin.h:677
Definition: sdb.h:63
uint32_t size
static const char * resolve(struct Type *t, const char *foo, const char **bar)
Definition: swift.c:91
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
#define buffer_size(buffer)
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115