Rizin
unix-like reverse engineering framework and cli tools
bin_art.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Florian Märkl <info@florianmaerkl.de>
2 // SPDX-FileCopyrightText: 2015-2018 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_types.h>
6 #include <rz_util.h>
7 #include <rz_lib.h>
8 #include <rz_bin.h>
9 
10 #ifdef _MSC_VER
11 typedef struct art_header_t {
12 #else
13 typedef struct __packed art_header_t {
14 #endif
15  ut8 magic[4];
21  ut32 checksum; /* adler32 */
22  ut32 oat_file_begin; // oat_file_begin
26  /* patch_delta is the amount of the base address the image is relocated */
28  /* image_roots: address of an array of objects needed to initialize */
32 
33 typedef struct {
34  Sdb *kv;
37 } ArtObj;
38 
39 static int art_header_load(ArtObj *ao, Sdb *db) {
40  /* TODO: handle read errors here */
41  if (rz_buf_size(ao->buf) < sizeof(ARTHeader)) {
42  return false;
43  }
44  ARTHeader *art = &ao->art;
45  (void)rz_buf_fread_at(ao->buf, 0, (ut8 *)art, "IIiiiiiiiiiiii", 1);
46  sdb_set(db, "img.base", sdb_fmt("0x%x", art->image_base), 0);
47  sdb_set(db, "img.size", sdb_fmt("0x%x", art->image_size), 0);
48  sdb_set(db, "art.checksum", sdb_fmt("0x%x", art->checksum), 0);
49  sdb_set(db, "art.version", sdb_fmt("%c%c%c", art->version[0], art->version[1], art->version[2]), 0);
50  sdb_set(db, "oat.begin", sdb_fmt("0x%x", art->oat_file_begin), 0);
51  sdb_set(db, "oat.end", sdb_fmt("0x%x", art->oat_file_end), 0);
52  sdb_set(db, "oat_data.begin", sdb_fmt("0x%x", art->oat_data_begin), 0);
53  sdb_set(db, "oat_data.end", sdb_fmt("0x%x", art->oat_data_end), 0);
54  sdb_set(db, "patch_delta", sdb_fmt("0x%x", art->patch_delta), 0);
55  sdb_set(db, "image_roots", sdb_fmt("0x%x", art->image_roots), 0);
56  sdb_set(db, "compile_pic", sdb_fmt("0x%x", art->compile_pic), 0);
57  return true;
58 }
59 
60 static Sdb *get_sdb(RzBinFile *bf) {
61  RzBinObject *o = bf->o;
62  if (!o) {
63  return NULL;
64  }
65  ArtObj *ao = o->bin_obj;
66  return ao ? ao->kv : NULL;
67 }
68 
69 static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
70  ArtObj *ao = RZ_NEW0(ArtObj);
71  if (ao) {
72  ao->kv = sdb_new0();
73  if (!ao->kv) {
74  free(ao);
75  return false;
76  }
77  ao->buf = rz_buf_ref(buf);
78  art_header_load(ao, ao->kv);
79  sdb_ns_set(sdb, "info", ao->kv);
80  obj->bin_obj = ao;
81  return true;
82  }
83  return false;
84 }
85 
86 static void destroy(RzBinFile *bf) {
87  ArtObj *obj = bf->o->bin_obj;
88  rz_buf_free(obj->buf);
89  free(obj);
90 }
91 
92 static ut64 baddr(RzBinFile *bf) {
93  ArtObj *ao = bf->o->bin_obj;
94  return ao ? ao->art.image_base : 0;
95 }
96 
97 static RzList *strings(RzBinFile *bf) {
98  return NULL;
99 }
100 
101 static RzBinInfo *info(RzBinFile *bf) {
102  rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
103  RzBinInfo *ret = RZ_NEW0(RzBinInfo);
104  if (!ret) {
105  return NULL;
106  }
107  ArtObj *ao = bf->o->bin_obj;
108  ret->lang = NULL;
109  ret->file = bf->file ? strdup(bf->file) : NULL;
110  ret->type = strdup("ART");
111 
112  ret->bclass = malloc(5);
113  memcpy(ret->bclass, &ao->art.version, 4);
114  ret->bclass[3] = 0;
115 
116  ret->rclass = strdup("program");
117  ret->os = strdup("android");
118  ret->subsystem = strdup("unknown");
119  ret->machine = strdup("arm");
120  ret->arch = strdup("arm");
121  ret->has_va = 1;
122  ret->has_pi = ao->art.compile_pic;
123  ret->bits = 16; // 32? 64?
124  ret->big_endian = 0;
125  ret->dbg_info = 0;
126  return ret;
127 }
128 
129 static bool check_buffer(RzBuffer *buf) {
130  char tmp[4];
131  int r = rz_buf_read_at(buf, 0, (ut8 *)tmp, sizeof(tmp));
132  return r == 4 && !strncmp(tmp, "art\n", 4);
133 }
134 
135 static RzList *entries(RzBinFile *bf) {
136  RzList *ret = rz_list_newf(free);
137  if (ret) {
138  RzBinAddr *ptr = RZ_NEW0(RzBinAddr);
139  if (ptr) {
140  ptr->paddr = ptr->vaddr = 0;
141  rz_list_append(ret, ptr);
142  }
143  }
144  return ret;
145 }
146 
147 static RzList *sections(RzBinFile *bf) {
148  ArtObj *ao = bf->o->bin_obj;
149  if (!ao) {
150  return NULL;
151  }
152  ARTHeader art = ao->art;
153  RzList *ret = NULL;
154  RzBinSection *ptr = NULL;
155 
156  if (!(ret = rz_list_new())) {
157  return NULL;
158  }
159  ret->free = free;
160 
161  if (!(ptr = RZ_NEW0(RzBinSection))) {
162  return ret;
163  }
164  ptr->name = strdup("load");
165  ptr->size = rz_buf_size(bf->buf);
166  ptr->vsize = art.image_size; // TODO: align?
167  ptr->paddr = 0;
168  ptr->vaddr = art.image_base;
169  ptr->perm = RZ_PERM_R; // r--
170  rz_list_append(ret, ptr);
171 
172  if (!(ptr = RZ_NEW0(RzBinSection))) {
173  return ret;
174  }
175  ptr->name = strdup("bitmap");
176  ptr->size = art.bitmap_size;
177  ptr->vsize = art.bitmap_size;
178  ptr->paddr = art.bitmap_offset;
179  ptr->vaddr = art.image_base + art.bitmap_offset;
180  ptr->perm = RZ_PERM_RX; // r-x
181  rz_list_append(ret, ptr);
182 
183  if (!(ptr = RZ_NEW0(RzBinSection))) {
184  return ret;
185  }
186  ptr->name = strdup("oat");
187  ptr->paddr = art.bitmap_offset;
188  ptr->vaddr = art.oat_file_begin;
189  ptr->size = art.oat_file_end - art.oat_file_begin;
190  ptr->vsize = ptr->size;
191  ptr->perm = RZ_PERM_RX; // r-x
192  rz_list_append(ret, ptr);
193 
194  if (!(ptr = RZ_NEW0(RzBinSection))) {
195  return ret;
196  }
197  ptr->name = strdup("oat_data");
198  ptr->paddr = art.bitmap_offset;
199  ptr->vaddr = art.oat_data_begin;
200  ptr->size = art.oat_data_end - art.oat_data_begin;
201  ptr->vsize = ptr->size;
202  ptr->perm = RZ_PERM_R; // r--
203  rz_list_append(ret, ptr);
204 
205  return ret;
206 }
207 
209  .name = "art",
210  .desc = "Android Runtime",
211  .license = "LGPL3",
212  .get_sdb = &get_sdb,
213  .load_buffer = &load_buffer,
214  .destroy = &destroy,
215  .check_buffer = &check_buffer,
216  .baddr = &baddr,
218  .sections = &sections,
219  .entries = entries,
220  .strings = &strings,
221  .info = &info,
222 };
223 
224 #ifndef RZ_PLUGIN_INCORE
227  .data = &rz_bin_plugin_art,
229 };
230 #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
static Sdb * get_sdb(RzBinFile *bf)
Definition: bin_art.c:60
static bool check_buffer(RzBuffer *buf)
Definition: bin_art.c:129
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
Definition: bin_art.c:69
struct __packed art_header_t ARTHeader
static RzList * strings(RzBinFile *bf)
Definition: bin_art.c:97
static void destroy(RzBinFile *bf)
Definition: bin_art.c:86
RZ_API RzLibStruct rizin_plugin
Definition: bin_art.c:225
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_art.c:101
static ut64 baddr(RzBinFile *bf)
Definition: bin_art.c:92
RzBinPlugin rz_bin_plugin_art
Definition: bin_art.c:208
static RzList * entries(RzBinFile *bf)
Definition: bin_art.c:135
static RzList * sections(RzBinFile *bf)
Definition: bin_art.c:147
static int art_header_load(ArtObj *ao, Sdb *db)
Definition: bin_art.c:39
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
uint32_t ut32
struct instruction __packed
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
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_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
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
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")
RZ_API int sdb_ns_set(Sdb *s, const char *name, Sdb *r)
Definition: ns.c:156
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API RzBuffer * rz_buf_ref(RzBuffer *b)
Increment the reference count of the buffer.
Definition: buf.c:668
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 st64 rz_buf_fread_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL ut8 *buf, RZ_NONNULL const char *fmt, int n)
...
Definition: buf.c:1001
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
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RX
Definition: rz_types.h:97
#define st32
Definition: rz_types_base.h:12
#define RZ_VERSION
Definition: rz_version.h:8
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
Definition: bin_art.c:33
Sdb * kv
Definition: bin_art.c:34
RzBuffer * buf
Definition: bin_art.c:36
ARTHeader art
Definition: bin_art.c:35
ut32 image_base
Definition: bin_art.c:17
ut32 oat_file_end
Definition: bin_art.c:25
ut32 checksum
Definition: bin_art.c:21
ut32 oat_data_begin
Definition: bin_art.c:23
st32 patch_delta
Definition: bin_art.c:27
ut32 oat_file_begin
Definition: bin_art.c:22
ut32 bitmap_size
Definition: bin_art.c:20
ut32 image_roots
Definition: bin_art.c:29
ut32 compile_pic
Definition: bin_art.c:30
ut32 image_size
Definition: bin_art.c:18
ut8 magic[4]
Definition: bin_art.c:15
ut32 bitmap_offset
Definition: bin_art.c:19
ut32 oat_data_end
Definition: bin_art.c:24
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RzBinObject * o
Definition: rz_bin.h:305
char * file
Definition: rz_bin.h:299
RzBuffer * buf
Definition: rz_bin.h:303
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
int has_pi
Definition: rz_bin.h:229
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
char * rclass
Definition: rz_bin.h:213
char * arch
Definition: rz_bin.h:214
int big_endian
Definition: rz_bin.h:235
void * bin_obj
Definition: rz_bin.h:293
char * name
Definition: rz_bin.h:509
char * version
Definition: rz_bin.h:512
char * name
Definition: rz_bin.h:619
RzListFree free
Definition: rz_list.h:21
Definition: sdb.h:63
ut64(WINAPI *w32_GetEnabledXStateFeatures)()