Rizin
unix-like reverse engineering framework and cli tools
bin_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 <rz_bin.h>
6 #include "dex/dex.h"
7 
8 #define rz_bin_file_get_dex(bf) ((RzBinDex *)bf->o->bin_obj)
9 
10 static RzBinInfo *info(RzBinFile *bf) {
11  RzBinDex *dex = rz_bin_file_get_dex(bf);
12  if (!dex) {
13  return NULL;
14  }
15 
16  RzBinInfo *binfo = RZ_NEW0(RzBinInfo);
17  if (!binfo) {
18  return NULL;
19  }
20 
21  binfo->lang = "java";
22  binfo->file = strdup(bf->file);
23  binfo->type = strdup("DEX CLASS");
24  binfo->bclass = rz_bin_dex_version(dex);
25  binfo->has_va = true;
26  binfo->rclass = strdup("class");
27  binfo->os = strdup("linux");
28  binfo->subsystem = strdup("any");
29  binfo->machine = strdup("Dalvik VM");
30  binfo->arch = strdup("dalvik");
31  binfo->bits = 32;
32  binfo->big_endian = false;
33  binfo->dbg_info = rz_bin_dex_debug_info(dex);
34 
35  rz_bin_dex_checksum(dex, &binfo->sum[0]);
36  rz_bin_dex_sha1(dex, &binfo->sum[1]);
37 
38  return binfo;
39 }
40 
41 static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
42  RzBinDex *dex = rz_bin_dex_new(buf, obj->opts.loadaddr, sdb);
43  if (!dex) {
44  return false;
45  }
46  obj->bin_obj = dex;
47  return true;
48 }
49 
50 static void destroy(RzBinFile *bf) {
52 }
53 
54 static bool check_buffer(RzBuffer *b) {
55  if (rz_buf_size(b) > 32) {
56  ut8 buf[4] = { 0 };
57  rz_buf_read_at(b, 0, buf, sizeof(buf));
58  return !memcmp(buf, "dex\n", 4);
59  }
60  return false;
61 }
62 
63 static ut64 baddr(RzBinFile *bf) {
64  return 0;
65 }
66 
67 static Sdb *get_sdb(RzBinFile *bf) {
68  return bf->sdb;
69 }
70 
71 static RzList *classes(RzBinFile *bf) {
72  RzBinDex *dex = rz_bin_file_get_dex(bf);
73  if (!dex) {
74  return NULL;
75  }
76 
77  return rz_bin_dex_classes(dex);
78 }
79 
80 static RzList *imports(RzBinFile *bf) {
81  RzBinDex *dex = rz_bin_file_get_dex(bf);
82  if (!dex) {
83  return NULL;
84  }
85 
86  return rz_bin_dex_imports(dex);
87 }
88 
89 static RzList *sections(RzBinFile *bf) {
90  RzBinDex *dex = rz_bin_file_get_dex(bf);
91  if (!dex) {
92  return NULL;
93  }
94 
95  return rz_bin_dex_sections(dex);
96 }
97 
98 static RzList *symbols(RzBinFile *bf) {
99  RzBinDex *dex = rz_bin_file_get_dex(bf);
100  if (!dex) {
101  return NULL;
102  }
103 
104  return rz_bin_dex_symbols(dex);
105 }
106 
107 static RzList *fields(RzBinFile *bf) {
108  RzBinDex *dex = rz_bin_file_get_dex(bf);
109  if (!dex) {
110  return NULL;
111  }
112 
113  return rz_bin_dex_fields(dex);
114 }
115 
116 static RzList *libraries(RzBinFile *bf) {
117  RzBinDex *dex = rz_bin_file_get_dex(bf);
118  if (!dex) {
119  return NULL;
120  }
121 
122  return rz_bin_dex_libraries(dex);
123 }
124 
126  RzBinDex *dex = rz_bin_file_get_dex(bf);
127  if (!dex) {
128  return NULL;
129  }
130 
131  return rz_bin_dex_resolve_symbol(dex, sym);
132 }
133 
135  RzBinDex *dex = rz_bin_file_get_dex(bf);
136  if (!dex) {
137  return NULL;
138  }
139 
140  return rz_bin_dex_entrypoints(dex);
141 }
142 
143 static RzList *strings(RzBinFile *bf) {
144  RzBinDex *dex = rz_bin_file_get_dex(bf);
145  if (!dex) {
146  return NULL;
147  }
148 
149  return rz_bin_dex_strings(dex);
150 }
151 
153  RzBinDex *dex = rz_bin_file_get_dex(bf);
154  if (!dex) {
155  return NULL;
156  }
157 
159  if (!buffer) {
160  return NULL;
161  }
162 
164  if (!vfiles) {
165  return NULL;
166  }
167 
169  if (!vf) {
171  return vfiles;
172  }
173  vf->buf = buffer;
174  vf->buf_owned = false;
176 
177  rz_list_push(vfiles, vf);
178  return vfiles;
179 }
180 
181 static int demangle_type(const char *str) {
182  return RZ_BIN_LANGUAGE_JAVA;
183 }
184 
185 static char *get_name(RzBinFile *bf, int type, int index) {
186  RzBinDex *dex = rz_bin_file_get_dex(bf);
187  if (!dex) {
188  return NULL;
189  }
190  switch (type) {
191  case 'm': // method
192  return rz_bin_dex_resolve_method_by_idx(dex, index);
193  case 'f': // field
194  return rz_bin_dex_resolve_field_by_idx(dex, index);
195  case 's': // string
196  return rz_bin_dex_resolve_string_by_idx(dex, index);
197  case 'c': // class
198  return rz_bin_dex_resolve_class_by_idx(dex, index);
199  case 'p': // proto
200  return rz_bin_dex_resolve_proto_by_idx(dex, index);
201  default:
202  return NULL;
203  }
204 }
205 
206 static ut64 get_offset(RzBinFile *bf, int type, int index) {
207  RzBinDex *dex = rz_bin_file_get_dex(bf);
208  if (!dex) {
209  return -1;
210  }
211  switch (type) {
212  case 'm': // method
213  return rz_bin_dex_resolve_method_offset_by_idx(dex, index);
214  case 's': // strings
215  return rz_bin_dex_resolve_string_offset_by_idx(dex, index);
216  case 't': // type
217  return rz_bin_dex_resolve_type_id_offset_by_idx(dex, index);
218  case 'c': // class
219  return rz_bin_dex_resolve_type_id_offset_by_idx(dex, index);
220  case 'o': // objects
221  default:
222  return -1;
223  }
224 }
225 
226 static RzList *maps(RzBinFile *bf) {
228  RzListIter *iter;
229  RzBinMap *map;
230 
231  rz_list_foreach (maps, iter, map) {
232  if (strcmp(map->name, RZ_DEX_RELOC_TARGETS)) {
233  continue;
234  }
235  map->vfile_name = strdup(RZ_DEX_RELOC_TARGETS);
236  }
237  return maps;
238 }
239 
241  .name = "dex",
242  .desc = "dex bin plugin",
243  .license = "LGPL3",
244  .get_sdb = &get_sdb,
245  .load_buffer = &load_buffer,
246  .destroy = &destroy,
247  .check_buffer = &check_buffer,
248  .baddr = &baddr,
249  .binsym = &binsym,
250  .entries = &entrypoints,
251  .virtual_files = &virtual_files,
252  .maps = &maps,
253  .sections = sections,
254  .symbols = symbols,
255  .imports = &imports,
256  .strings = &strings,
257  .get_name = &get_name,
258  .get_offset = &get_offset,
259  .info = &info,
260  .fields = fields,
261  .libs = libraries,
262  .classes = classes,
263  .demangle_type = demangle_type,
264  .minstrlen = 0,
265 };
266 
267 #ifndef RZ_PLUGIN_INCORE
270  .data = &rz_bin_plugin_dex,
272 };
273 #endif
RZ_API RZ_OWN RzList * rz_bin_maps_of_file_sections(RZ_NONNULL RzBinFile *binfile)
Create a list of RzBinMap from RzBinSections queried from the given file.
Definition: bin.c:1040
RZ_API void rz_bin_virtual_file_free(RzBinVirtualFile *vfile)
Definition: bin.c:1012
static RzBinAddr * binsym(RzBinFile *bf, RzBinSpecialSymbol sym)
Definition: bin_dex.c:125
static Sdb * get_sdb(RzBinFile *bf)
Definition: bin_dex.c:67
static RzList * classes(RzBinFile *bf)
Definition: bin_dex.c:71
RzBinPlugin rz_bin_plugin_dex
Definition: bin_dex.c:240
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
Definition: bin_dex.c:41
static RzList * symbols(RzBinFile *bf)
Definition: bin_dex.c:98
static RzList * strings(RzBinFile *bf)
Definition: bin_dex.c:143
static RzList * fields(RzBinFile *bf)
Definition: bin_dex.c:107
static void destroy(RzBinFile *bf)
Definition: bin_dex.c:50
RZ_API RzLibStruct rizin_plugin
Definition: bin_dex.c:268
static ut64 get_offset(RzBinFile *bf, int type, int index)
Definition: bin_dex.c:206
static bool check_buffer(RzBuffer *b)
Definition: bin_dex.c:54
static RzList * virtual_files(RzBinFile *bf)
Definition: bin_dex.c:152
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_dex.c:10
static ut64 baddr(RzBinFile *bf)
Definition: bin_dex.c:63
static RzList * maps(RzBinFile *bf)
Definition: bin_dex.c:226
static char * get_name(RzBinFile *bf, int type, int index)
Definition: bin_dex.c:185
static RzList * sections(RzBinFile *bf)
Definition: bin_dex.c:89
static RzList * imports(RzBinFile *bf)
Definition: bin_dex.c:80
static RzList * libraries(RzBinFile *bf)
Definition: bin_dex.c:116
static int demangle_type(const char *str)
Definition: bin_dex.c:181
static RzList * entrypoints(RzBinFile *bf)
Definition: bin_dex.c:134
#define rz_bin_file_get_dex(bf)
Definition: bin_dex.c:8
struct buffer buffer
#define RZ_API
#define NULL
Definition: cris-opc.c:27
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
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
RZ_API void rz_bin_dex_free(RZ_NULLABLE RzBinDex *dex)
Frees a RzBinDex struct.
Definition: dex.c:649
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
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
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
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
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
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
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
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
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
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
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 RzList * rz_bin_dex_strings(RZ_NONNULL RzBinDex *dex)
Returns a RzList<RzBinString*> containing the dex strings.
Definition: dex.c:735
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
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
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
size_t map(int syms, int left, int len)
Definition: enough.c:237
#define RZ_DEX_RELOC_TARGETS
Definition: dex.h:12
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
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_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
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
@ RZ_BIN_LANGUAGE_JAVA
Definition: rz_bin.h:147
RzBinSpecialSymbol
Definition: rz_bin.h:136
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
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 ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
@ RZ_LIB_TYPE_BIN
Definition: rz_lib.h:75
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_VERSION
Definition: rz_version.h:8
#define b(i)
Definition: sha256.c:42
Definition: buffer.h:15
Definition: dex.h:160
ut64 loadaddr
starting physical address to read from the target file
Definition: rz_bin.h:249
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RZ_DEPRECATE Sdb * sdb
deprecated, put info in C structures instead of this
Definition: rz_bin.h:315
char * file
Definition: rz_bin.h:299
int has_va
Definition: rz_bin.h:228
char * type
Definition: rz_bin.h:211
char * os
Definition: rz_bin.h:219
char * subsystem
Definition: rz_bin.h:220
char * machine
Definition: rz_bin.h:216
const char * lang
Definition: rz_bin.h:224
char * bclass
Definition: rz_bin.h:212
char * file
Definition: rz_bin.h:210
ut64 dbg_info
Definition: rz_bin.h:240
RzBinHash sum[3]
Definition: rz_bin.h:241
char * rclass
Definition: rz_bin.h:213
char * arch
Definition: rz_bin.h:214
int big_endian
Definition: rz_bin.h:235
Description of a single memory mapping into virtual memory from a binary.
Definition: rz_bin.h:602
RzBinObjectLoadOptions opts
Definition: rz_bin.h:260
void * bin_obj
Definition: rz_bin.h:293
char * name
Definition: rz_bin.h:509
char * version
Definition: rz_bin.h:512
RZ_NONNULL RzBuffer * buf
Definition: rz_bin.h:597
bool buf_owned
whether buf is owned and freed by this RzBinVirtualFile
Definition: rz_bin.h:598
RZ_OWN RZ_NONNULL char * name
Definition: rz_bin.h:596
Definition: sdb.h:63
ut64(WINAPI *w32_GetEnabledXStateFeatures)()