Coverage Report

Created: 2026-10-17 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yara/libyara/modules/dex/dex.c
Line
Count
Source
1
/*
2
Copyright (c) 2018. The YARA Authors. All Rights Reserved.
3
4
Redistribution and use in source and binary forms, with or without modification,
5
are permitted provided that the following conditions are met:
6
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions and the following disclaimer.
9
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions and the following disclaimer in the documentation and/or
12
other materials provided with the distribution.
13
14
3. Neither the name of the copyright holder nor the names of its contributors
15
may be used to endorse or promote products derived from this software without
16
specific prior written permission.
17
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#include <yara/dex.h>
31
#include <yara/endian.h>
32
#include <yara/mem.h>
33
#include <yara/modules.h>
34
35
#define MODULE_NAME dex
36
37
// DEX File layout information:
38
// https://source.android.com/devices/tech/dalvik/dex-format
39
40
define_function(has_method_string)
41
0
{
42
0
  SIZED_STRING* parsed_name;
43
0
  SIZED_STRING* method_name = sized_string_argument(1);
44
0
  YR_OBJECT* module = yr_module();
45
0
  int64_t number_of_methods = yr_get_integer(module, "number_of_methods");
46
47
0
  if (number_of_methods == YR_UNDEFINED)
48
0
    return_integer(YR_UNDEFINED);
49
50
0
  for (int i = 0; i < number_of_methods; i++)
51
0
  {
52
0
    parsed_name = yr_get_string(module, "method[%i].name", i);
53
0
    if (parsed_name != NULL &&
54
0
        strcmp(parsed_name->c_string, method_name->c_string) == 0)
55
0
    {
56
0
      return_integer(1);
57
0
    }
58
0
  }
59
60
0
  return_integer(0);
61
0
}
62
63
define_function(has_method_and_class_string)
64
0
{
65
0
  SIZED_STRING* parsed_class;
66
0
  SIZED_STRING* parsed_name;
67
0
  SIZED_STRING* class_name = sized_string_argument(1);
68
0
  SIZED_STRING* method_name = sized_string_argument(2);
69
0
  YR_OBJECT* module = yr_module();
70
0
  int64_t number_of_methods = yr_get_integer(module, "number_of_methods");
71
72
0
  if (number_of_methods == YR_UNDEFINED)
73
0
    return_integer(YR_UNDEFINED);
74
75
0
  for (int i = 0; i < number_of_methods; i++)
76
0
  {
77
0
    parsed_class = yr_get_string(module, "method[%i].class_name", i);
78
0
    if (parsed_class != NULL &&
79
0
        strcmp(parsed_class->c_string, class_name->c_string) != 0)
80
0
    {
81
0
      continue;
82
0
    }
83
84
0
    parsed_name = yr_get_string(module, "method[%i].name", i);
85
0
    if (parsed_name != NULL &&
86
0
        strcmp(parsed_name->c_string, method_name->c_string) == 0)
87
0
    {
88
0
      return_integer(1);
89
0
    }
90
0
  }
91
92
0
  return_integer(0);
93
0
}
94
95
define_function(has_method_regexp)
96
0
{
97
0
  SIZED_STRING* parsed_name;
98
0
  RE* regex = regexp_argument(1);
99
0
  YR_OBJECT* module = yr_module();
100
0
  int64_t number_of_methods = yr_get_integer(module, "number_of_methods");
101
102
0
  if (number_of_methods == YR_UNDEFINED)
103
0
    return_integer(YR_UNDEFINED);
104
105
0
  for (int i = 0; i < number_of_methods; i++)
106
0
  {
107
0
    parsed_name = yr_get_string(module, "method[%i].name", i);
108
0
    if (parsed_name != NULL &&
109
0
        yr_re_match(yr_scan_context(), regex, parsed_name->c_string) != -1)
110
0
    {
111
0
      return_integer(1);
112
0
    }
113
0
  }
114
0
  return_integer(0);
115
0
}
116
117
define_function(has_method_and_class_regexp)
118
0
{
119
0
  SIZED_STRING* parsed_class;
120
0
  SIZED_STRING* parsed_name;
121
0
  RE* class_regex = regexp_argument(1);
122
0
  RE* name_regex = regexp_argument(2);
123
0
  YR_OBJECT* module = yr_module();
124
0
  int64_t number_of_methods = yr_get_integer(module, "number_of_methods");
125
126
0
  if (number_of_methods == YR_UNDEFINED)
127
0
    return_integer(YR_UNDEFINED);
128
129
0
  for (int i = 0; i < number_of_methods; i++)
130
0
  {
131
0
    parsed_class = yr_get_string(module, "method[%i].class_name", i);
132
0
    if (parsed_class != NULL &&
133
0
        yr_re_match(yr_scan_context(), class_regex, parsed_class->c_string) == -1)
134
0
    {
135
0
      continue;
136
0
    }
137
138
0
    parsed_name = yr_get_string(module, "method[%i].name", i);
139
0
    if (parsed_name != NULL &&
140
0
        yr_re_match(yr_scan_context(), name_regex, parsed_name->c_string) != -1)
141
0
    {
142
0
      return_integer(1);
143
0
    }
144
0
  }
145
0
  return_integer(0);
146
0
}
147
148
define_function(has_class_string)
149
0
{
150
0
  SIZED_STRING* parsed_class;
151
0
  SIZED_STRING* class_name = sized_string_argument(1);
152
0
  YR_OBJECT* module = yr_module();
153
0
  int64_t number_of_methods = yr_get_integer(module, "number_of_methods");
154
155
0
  if (number_of_methods == YR_UNDEFINED)
156
0
    return_integer(YR_UNDEFINED);
157
158
0
  for (int i = 0; i < number_of_methods; i++)
159
0
  {
160
0
    parsed_class = yr_get_string(module, "method[%i].class_name", i);
161
0
    if (parsed_class != NULL &&
162
0
        strcmp(parsed_class->c_string, class_name->c_string) == 0)
163
0
    {
164
0
      return_integer(1);
165
0
    }
166
0
  }
167
168
0
  return_integer(0);
169
0
}
170
171
define_function(has_class_regexp)
172
0
{
173
0
  SIZED_STRING* parsed_class;
174
0
  RE* regex = regexp_argument(1);
175
0
  YR_OBJECT* module = yr_module();
176
0
  int64_t number_of_methods = yr_get_integer(module, "number_of_methods");
177
178
0
  if (number_of_methods == YR_UNDEFINED)
179
0
    return_integer(YR_UNDEFINED);
180
181
0
  for (int i = 0; i < number_of_methods; i++)
182
0
  {
183
0
    parsed_class = yr_get_string(module, "method[%i].class_name", i);
184
0
    if (parsed_class != NULL &&
185
0
        yr_re_match(yr_scan_context(), regex, parsed_class->c_string) != -1)
186
0
    {
187
0
      return_integer(1);
188
0
    }
189
0
  }
190
0
  return_integer(0);
191
0
}
192
193
0
begin_declarations
194
0
  declare_string("DEX_FILE_MAGIC_035");
195
0
  declare_string("DEX_FILE_MAGIC_036");
196
0
  declare_string("DEX_FILE_MAGIC_037");
197
0
  declare_string("DEX_FILE_MAGIC_038");
198
0
  declare_string("DEX_FILE_MAGIC_039");
199
200
0
  declare_integer("ENDIAN_CONSTANT");
201
0
  declare_integer("REVERSE_ENDIAN_CONSTANT");
202
0
  declare_integer("NO_INDEX");
203
0
  declare_integer("ACC_PUBLIC");
204
0
  declare_integer("ACC_PRIVATE");
205
0
  declare_integer("ACC_PROTECTED");
206
0
  declare_integer("ACC_STATIC");
207
0
  declare_integer("ACC_FINAL");
208
0
  declare_integer("ACC_SYNCHRONIZED");
209
0
  declare_integer("ACC_VOLATILE");
210
0
  declare_integer("ACC_BRIDGE");
211
0
  declare_integer("ACC_TRANSIENT");
212
0
  declare_integer("ACC_VARARGS");
213
0
  declare_integer("ACC_NATIVE");
214
0
  declare_integer("ACC_INTERFACE");
215
0
  declare_integer("ACC_ABSTRACT");
216
0
  declare_integer("ACC_STRICT");
217
0
  declare_integer("ACC_SYNTHETIC");
218
0
  declare_integer("ACC_ANNOTATION");
219
0
  declare_integer("ACC_ENUM");
220
0
  declare_integer("ACC_CONSTRUCTOR");
221
0
  declare_integer("ACC_DECLARED_SYNCHRONIZED");
222
223
0
  declare_integer("TYPE_HEADER_ITEM");
224
0
  declare_integer("TYPE_STRING_ID_ITEM");
225
0
  declare_integer("TYPE_TYPE_ID_ITEM");
226
0
  declare_integer("TYPE_PROTO_ID_ITEM");
227
0
  declare_integer("TYPE_FIELD_ID_ITEM");
228
0
  declare_integer("TYPE_METHOD_ID_ITEM");
229
0
  declare_integer("TYPE_CLASS_DEF_ITEM");
230
0
  declare_integer("TYPE_CALL_SITE_ID_ITEM");
231
0
  declare_integer("TYPE_METHOD_HANDLE_ITEM");
232
0
  declare_integer("TYPE_MAP_LIST");
233
0
  declare_integer("TYPE_TYPE_LIST");
234
0
  declare_integer("TYPE_ANNOTATION_SET_REF_LIST");
235
0
  declare_integer("TYPE_ANNOTATION_SET_ITEM");
236
0
  declare_integer("TYPE_CLASS_DATA_ITEM");
237
0
  declare_integer("TYPE_CODE_ITEM");
238
0
  declare_integer("TYPE_STRING_DATA_ITEM");
239
0
  declare_integer("TYPE_DEBUG_INFO_ITEM");
240
0
  declare_integer("TYPE_ANNOTATION_ITEM");
241
0
  declare_integer("TYPE_ENCODED_ARRAY_ITEM");
242
0
  declare_integer("TYPE_ANNOTATIONS_DIRECTORY_ITEM");
243
244
0
  begin_struct("header")
245
0
    declare_string("magic");
246
0
    declare_integer("checksum");
247
0
    declare_string("signature");
248
0
    declare_integer("file_size");
249
0
    declare_integer("header_size");
250
0
    declare_integer("endian_tag");
251
0
    declare_integer("link_size");
252
0
    declare_integer("link_offset");
253
0
    declare_integer("map_offset");
254
0
    declare_integer("string_ids_size");
255
0
    declare_integer("string_ids_offset");
256
0
    declare_integer("type_ids_size");
257
0
    declare_integer("type_ids_offset");
258
0
    declare_integer("proto_ids_size");
259
0
    declare_integer("proto_ids_offset");
260
0
    declare_integer("field_ids_size");
261
0
    declare_integer("field_ids_offset");
262
0
    declare_integer("method_ids_size");
263
0
    declare_integer("method_ids_offset");
264
0
    declare_integer("class_defs_size");
265
0
    declare_integer("class_defs_offset");
266
0
    declare_integer("data_size");
267
0
    declare_integer("data_offset");
268
0
  end_struct("header")
269
270
0
  begin_struct_array("string_ids")
271
0
    declare_integer("offset");
272
0
    declare_integer("size");
273
0
    declare_string("value");
274
0
  end_struct_array("string_ids")
275
276
0
  begin_struct_array("type_ids")
277
0
    declare_integer("descriptor_idx");
278
0
  end_struct_array("type_ids")
279
280
0
  begin_struct_array("proto_ids")
281
0
    declare_integer("shorty_idx");
282
0
    declare_integer("return_type_idx");
283
0
    declare_integer("parameters_offset");
284
0
  end_struct_array("proto_ids")
285
286
0
  begin_struct_array("field_ids")
287
0
    declare_integer("class_idx");
288
0
    declare_integer("type_idx");
289
0
    declare_integer("name_idx");
290
0
  end_struct_array("field_ids")
291
292
0
  begin_struct_array("method_ids")
293
0
    declare_integer("class_idx");
294
0
    declare_integer("proto_idx");
295
0
    declare_integer("name_idx");
296
0
  end_struct_array("method_ids")
297
298
0
  begin_struct_array("class_defs")
299
0
    declare_integer("class_idx");
300
0
    declare_integer("access_flags");
301
0
    declare_integer("super_class_idx");
302
0
    declare_integer("interfaces_offset");
303
0
    declare_integer("source_file_idx");
304
0
    declare_integer("annotations_offset");
305
0
    declare_integer("class_data_offset");
306
0
    declare_integer("static_values_offset");
307
0
  end_struct_array("class_defs")
308
309
0
  begin_struct_array("class_data_item")
310
0
    declare_integer("static_fields_size");
311
0
    declare_integer("instance_fields_size");
312
0
    declare_integer("direct_methods_size");
313
0
    declare_integer("virtual_methods_size");
314
0
  end_struct_array("class_data_item")
315
316
0
  begin_struct("map_list")
317
0
    declare_integer("size");
318
0
    begin_struct_array("map_item")
319
0
      declare_integer("type");
320
0
      declare_integer("unused");
321
0
      declare_integer("size");
322
0
      declare_integer("offset");
323
0
    end_struct_array("map_item");
324
0
  end_struct("map_list")
325
326
0
  declare_integer("number_of_fields");
327
0
  begin_struct_array("field")
328
0
    declare_string("class_name");
329
0
    declare_string("name");
330
0
    declare_string("proto");
331
0
    declare_integer("static");
332
0
    declare_integer("instance");
333
0
    declare_integer("field_idx_diff");
334
0
    declare_integer("access_flags");
335
0
  end_struct_array("field")
336
337
0
  declare_function("has_method", "s", "i", has_method_string);
338
0
  declare_function("has_method", "ss", "i", has_method_and_class_string);
339
0
  declare_function("has_method", "r", "i", has_method_regexp);
340
0
  declare_function("has_method", "rr", "i", has_method_and_class_regexp);
341
0
  declare_function("has_class", "s", "i", has_class_string);
342
0
  declare_function("has_class", "r", "i", has_class_regexp);
343
344
0
  declare_integer("number_of_methods");
345
0
  begin_struct_array("method")
346
0
    declare_string("class_name");
347
0
    declare_string("name");
348
0
    declare_string("proto");
349
0
    declare_integer("direct");
350
0
    declare_integer("virtual");
351
0
    declare_integer("method_idx_diff");
352
0
    declare_integer("access_flags");
353
0
    declare_integer("code_off");
354
355
0
    begin_struct("code_item")
356
0
      declare_integer("registers_size");
357
0
      declare_integer("ins_size");
358
0
      declare_integer("outs_size");
359
0
      declare_integer("tries_size");
360
0
      declare_integer("debug_info_off");
361
0
      declare_integer("insns_size");
362
0
      declare_string("insns");
363
0
    end_struct("code_item")
364
0
  end_struct_array("method")
365
0
end_declarations
366
367
// https://android.googlesource.com/platform/dalvik/+/android-4.4.2_r2/libdex/Leb128.cpp
368
369
static int32_t read_uleb128_bounded(
370
    const uint8_t* pStream,
371
    const uint8_t* pStreamEnd,
372
    uint32_t* size,
373
    bool* error)
374
0
{
375
0
  const uint8_t* ptr = pStream;
376
0
  int32_t result = 0;
377
378
0
  *error = false;
379
0
  if (ptr == pStreamEnd)
380
0
    goto error;
381
382
0
  result = *(ptr++);
383
0
  *size = *size + 1;
384
385
0
  if (result > 0x7f)
386
0
  {
387
0
    if (ptr == pStreamEnd)
388
0
      goto error;
389
0
    int cur = *(ptr++);
390
0
    *size = *size + 1;
391
0
    result = (result & 0x7f) | ((cur & 0x7f) << 7);
392
393
0
    if (cur > 0x7f)
394
0
    {
395
0
      if (ptr == pStreamEnd)
396
0
        goto error;
397
0
      cur = *(ptr++);
398
0
      *size = *size + 1;
399
0
      result |= (cur & 0x7f) << 14;
400
401
0
      if (cur > 0x7f)
402
0
      {
403
0
        if (ptr == pStreamEnd)
404
0
          goto error;
405
0
        cur = *(ptr++);
406
0
        *size = *size + 1;
407
0
        result |= (cur & 0x7f) << 21;
408
409
0
        if (cur > 0x7f)
410
0
        {
411
0
          if (ptr == pStreamEnd)
412
0
            goto error;
413
          /*
414
           * Note: We don't check to see if cur is out of
415
           * range here, meaning we tolerate garbage in the
416
           * high four-order bits.
417
           */
418
0
          cur = *ptr;
419
0
          *size = *size + 1;
420
0
          result |= cur << 28;
421
0
        }
422
0
      }
423
0
    }
424
0
  }
425
426
0
  return result;
427
428
0
error:
429
0
  *error = true;
430
0
  return result;
431
0
}
432
433
434
static int64_t dex_get_integer(
435
    YR_OBJECT* object,
436
    const char* pattern,
437
    int64_t index)
438
0
{
439
0
  if (index == YR_UNDEFINED || index < 0)
440
0
    return YR_UNDEFINED;
441
442
  // Impose a reasonably large limit to table indexes.
443
0
  if (index > 0x80000)
444
0
    return YR_UNDEFINED;
445
446
0
  return yr_get_integer(object, pattern, (int) index);
447
0
}
448
449
450
static SIZED_STRING* dex_get_string(
451
    YR_OBJECT* object,
452
    const char* pattern,
453
    int64_t index)
454
0
{
455
0
  if (index == YR_UNDEFINED || index < 0)
456
0
    return NULL;
457
458
  // Impose a reasonably large limit to table indexes.
459
0
  if (index > 0x80000)
460
0
    return NULL;
461
462
0
  return yr_get_string(object, pattern, (int) index);
463
0
}
464
465
466
dex_header_t* dex_get_header(const uint8_t* data, size_t data_size)
467
0
{
468
0
  dex_header_t* dex_header;
469
470
0
  if (data_size < sizeof(dex_header_t))
471
0
    return NULL;
472
473
  // Check if we have a valid DEX file
474
0
  dex_header = (dex_header_t*) data;
475
476
0
  if (memcmp(dex_header->magic, DEX_FILE_MAGIC_035, 8) != 0 &&
477
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_036, 8) != 0 &&
478
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_037, 8) != 0 &&
479
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_038, 8) != 0 &&
480
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_039, 8) != 0)
481
0
  {
482
0
    return NULL;
483
0
  }
484
485
0
  return dex_header;
486
0
}
487
488
489
void dex_parse_header(dex_header_t* dex_header, YR_OBJECT* module_object)
490
0
{
491
0
  yr_set_sized_string(
492
0
      (char*) dex_header->magic, 8, module_object, "header.magic");
493
494
0
  yr_set_integer(
495
0
      yr_le32toh(dex_header->checksum), module_object, "header.checksum");
496
497
0
  yr_set_sized_string(
498
0
      (char*) dex_header->signature, 20, module_object, "header.signature");
499
500
0
  yr_set_integer(
501
0
      yr_le32toh(dex_header->file_size), module_object, "header.file_size");
502
0
  yr_set_integer(
503
0
      yr_le32toh(dex_header->header_size), module_object, "header.header_size");
504
0
  yr_set_integer(
505
0
      yr_le32toh(dex_header->endian_tag), module_object, "header.endian_tag");
506
0
  yr_set_integer(
507
0
      yr_le32toh(dex_header->link_size), module_object, "header.link_size");
508
0
  yr_set_integer(
509
0
      yr_le32toh(dex_header->link_offset), module_object, "header.link_offset");
510
0
  yr_set_integer(
511
0
      yr_le32toh(dex_header->map_offset), module_object, "header.map_offset");
512
0
  yr_set_integer(
513
0
      yr_le32toh(dex_header->string_ids_size),
514
0
      module_object,
515
0
      "header.string_ids_size");
516
0
  yr_set_integer(
517
0
      yr_le32toh(dex_header->string_ids_offset),
518
0
      module_object,
519
0
      "header.string_ids_offset");
520
0
  yr_set_integer(
521
0
      yr_le32toh(dex_header->type_ids_size),
522
0
      module_object,
523
0
      "header.type_ids_size");
524
0
  yr_set_integer(
525
0
      yr_le32toh(dex_header->type_ids_offset),
526
0
      module_object,
527
0
      "header.type_ids_offset");
528
0
  yr_set_integer(
529
0
      yr_le32toh(dex_header->proto_ids_size),
530
0
      module_object,
531
0
      "header.proto_ids_size");
532
0
  yr_set_integer(
533
0
      yr_le32toh(dex_header->proto_ids_offset),
534
0
      module_object,
535
0
      "header.proto_ids_offset");
536
0
  yr_set_integer(
537
0
      yr_le32toh(dex_header->field_ids_size),
538
0
      module_object,
539
0
      "header.field_ids_size");
540
0
  yr_set_integer(
541
0
      yr_le32toh(dex_header->field_ids_offset),
542
0
      module_object,
543
0
      "header.field_ids_offset");
544
0
  yr_set_integer(
545
0
      yr_le32toh(dex_header->method_ids_size),
546
0
      module_object,
547
0
      "header.method_ids_size");
548
0
  yr_set_integer(
549
0
      yr_le32toh(dex_header->method_ids_offset),
550
0
      module_object,
551
0
      "header.method_ids_offset");
552
0
  yr_set_integer(
553
0
      yr_le32toh(dex_header->class_defs_size),
554
0
      module_object,
555
0
      "header.class_defs_size");
556
0
  yr_set_integer(
557
0
      yr_le32toh(dex_header->class_defs_offset),
558
0
      module_object,
559
0
      "header.class_defs_offset");
560
0
  yr_set_integer(
561
0
      yr_le32toh(dex_header->data_size), module_object, "header.data_size");
562
0
  yr_set_integer(
563
0
      yr_le32toh(dex_header->data_offset), module_object, "header.data_offset");
564
0
}
565
566
567
uint32_t load_encoded_field(
568
    DEX* dex,
569
    size_t start_offset,
570
    uint32_t* previous_field_idx,
571
    int index_encoded_field,
572
    int static_field,
573
    int instance_field)
574
0
{
575
#ifdef DEBUG_DEX_MODULE
576
  printf("[DEX] Parse encoded field start_offset:0x%zx\n", start_offset);
577
#endif
578
579
0
  const uint8_t* data_cur_start = dex->data + start_offset;
580
0
  if (!fits_in_dex(dex, dex->data + start_offset, sizeof(uint32_t) * 2))
581
0
    return 0;
582
583
0
  const uint8_t* data_end = dex->data + dex->data_size;
584
0
  uint32_t current_size = 0;
585
0
  bool error = false;
586
0
  encoded_field_t encoded_field;
587
588
0
  encoded_field.field_idx_diff =
589
0
      (uint32_t) read_uleb128_bounded((dex->data + start_offset + current_size),
590
0
                                      data_end, &current_size, &error);
591
0
  if (error)
592
0
    return 0;
593
594
0
  encoded_field.access_flags =
595
0
      (uint32_t) read_uleb128_bounded((dex->data + start_offset + current_size),
596
0
                                      data_end, &current_size, &error);
597
0
  if (error)
598
0
    return 0;
599
600
0
  yr_set_integer(
601
0
      encoded_field.field_idx_diff,
602
0
      dex->object,
603
0
      "field[%i].field_idx_diff",
604
0
      index_encoded_field);
605
606
0
  yr_set_integer(
607
0
      encoded_field.access_flags,
608
0
      dex->object,
609
0
      "field[%i].access_flags",
610
0
      index_encoded_field);
611
612
0
  yr_set_integer(
613
0
      static_field, dex->object, "field[%i].static", index_encoded_field);
614
615
0
  yr_set_integer(
616
0
      instance_field, dex->object, "field[%i].instance", index_encoded_field);
617
618
0
  *previous_field_idx = encoded_field.field_idx_diff + *previous_field_idx;
619
620
#ifdef DEBUG_DEX_MODULE
621
  printf(
622
      "[DEX]\tEncoded field field_idx:0x%x field_idx_diff:0x%x "
623
      "access_flags:0x%x\n",
624
      *previous_field_idx,
625
      encoded_field.field_idx_diff,
626
      encoded_field.access_flags);
627
#endif
628
629
0
  int64_t name_idx = dex_get_integer(
630
0
      dex->object, "field_ids[%i].name_idx", *previous_field_idx);
631
632
0
  if (name_idx == YR_UNDEFINED)
633
0
    return 0;
634
635
0
  SIZED_STRING* field_name = dex_get_string(
636
0
      dex->object, "string_ids[%i].value", name_idx);
637
638
0
  if (field_name != NULL)
639
0
  {
640
#ifdef DEBUG_DEX_MODULE
641
    printf(
642
        "[DEX]\tFIELD_NAME %s NAME_IDX 0x%llx\n", field_name->c_string, name_idx);
643
#endif
644
645
0
    yr_set_sized_string(
646
0
        field_name->c_string,
647
0
        field_name->length,
648
0
        dex->object,
649
0
        "field[%i].name",
650
0
        index_encoded_field);
651
0
  }
652
653
0
  int64_t class_idx = dex_get_integer(
654
0
      dex->object, "field_ids[%i].class_idx", *previous_field_idx);
655
656
0
  int64_t descriptor_idx = dex_get_integer(
657
0
      dex->object, "type_ids[%i].descriptor_idx", class_idx);
658
659
0
  SIZED_STRING* class_name = dex_get_string(
660
0
      dex->object, "string_ids[%i].value", descriptor_idx);
661
662
0
  if (class_name != NULL)
663
0
  {
664
#ifdef DEBUG_DEX_MODULE
665
    printf(
666
        "[DEX]\tCLASS_NAME %s CLASS_IDX 0x%llx DESCRIPTOR_IDX 0x%llx\n",
667
        class_name->c_string,
668
        class_idx,
669
        descriptor_idx);
670
#endif
671
672
0
    yr_set_sized_string(
673
0
        class_name->c_string,
674
0
        class_name->length,
675
0
        dex->object,
676
0
        "field[%i].class_name",
677
0
        index_encoded_field);
678
0
  }
679
680
0
  int type_idx = dex_get_integer(
681
0
      dex->object, "field_ids[%i].type_idx", *previous_field_idx);
682
683
0
  int shorty_idx = dex_get_integer(
684
0
      dex->object, "type_ids[%i].descriptor_idx", type_idx);
685
686
0
  SIZED_STRING* proto_name = dex_get_string(
687
0
      dex->object, "string_ids[%i].value", shorty_idx);
688
689
0
  if (proto_name != NULL)
690
0
  {
691
#ifdef DEBUG_DEX_MODULE
692
    printf(
693
        "[DEX]\tPROTO_NAME %s TYPE_IDX 0x%x SHORTY_IDX 0x%x\n",
694
        proto_name->c_string,
695
        type_idx,
696
        shorty_idx);
697
#endif
698
699
0
    yr_set_sized_string(
700
0
        proto_name->c_string,
701
0
        proto_name->length,
702
0
        dex->object,
703
0
        "field[%i].proto",
704
0
        index_encoded_field);
705
0
  }
706
707
0
  return current_size;
708
0
}
709
710
711
uint32_t load_encoded_method(
712
    DEX* dex,
713
    size_t start_offset,
714
    uint32_t* previous_method_idx,
715
    int index_encoded_method,
716
    int direct_method,
717
    int virtual_method)
718
0
{
719
#ifdef DEBUG_DEX_MODULE
720
  printf("[DEX] Parse encoded method start_offset:0x%zx\n", start_offset);
721
#endif
722
723
0
  const uint8_t* data_cur_start = dex->data + start_offset;
724
0
  if (!fits_in_dex(dex, data_cur_start, sizeof(uint32_t) * 3))
725
0
    return 0;
726
727
0
  const uint8_t* data_end = dex->data + dex->data_size;
728
0
  uint32_t current_size = 0;
729
0
  bool error = false;
730
0
  encoded_method_t encoded_method;
731
732
0
  encoded_method.method_idx_diff = (uint32_t) read_uleb128_bounded(
733
0
      (data_cur_start + current_size), data_end, &current_size, &error);
734
0
  if (error)
735
0
    return 0;
736
737
0
  encoded_method.access_flags = (uint32_t) read_uleb128_bounded(
738
0
      (data_cur_start + current_size), data_end, &current_size, &error);
739
0
  if (error)
740
0
    return 0;
741
742
0
  encoded_method.code_off = (uint32_t) read_uleb128_bounded(
743
0
      (data_cur_start + current_size), data_end, &current_size, &error);
744
0
  if (error)
745
0
    return 0;
746
747
0
  yr_set_integer(
748
0
      encoded_method.method_idx_diff,
749
0
      dex->object,
750
0
      "method[%i].method_idx_diff",
751
0
      index_encoded_method);
752
753
0
  yr_set_integer(
754
0
      encoded_method.access_flags,
755
0
      dex->object,
756
0
      "method[%i].access_flags",
757
0
      index_encoded_method);
758
759
0
  yr_set_integer(
760
0
      encoded_method.code_off,
761
0
      dex->object,
762
0
      "method[%i].code_off",
763
0
      index_encoded_method);
764
765
0
  yr_set_integer(
766
0
      direct_method, dex->object, "method[%i].direct", index_encoded_method);
767
768
0
  yr_set_integer(
769
0
      virtual_method, dex->object, "method[%i].virtual", index_encoded_method);
770
771
0
  *previous_method_idx = encoded_method.method_idx_diff + *previous_method_idx;
772
773
0
  int64_t name_idx = dex_get_integer(
774
0
      dex->object, "method_ids[%i].name_idx", *previous_method_idx);
775
776
0
  if (name_idx == YR_UNDEFINED)
777
0
    return 0;
778
779
#ifdef DEBUG_DEX_MODULE
780
  printf("[DEX]\tNAME_IDX 0x%llx\n", name_idx);
781
#endif
782
783
#ifdef DEBUG_DEX_MODULE
784
  printf(
785
      "[DEX]\tEncoded method method_idx:0x%x method_idx_diff:0x%x "
786
      "access_flags:0x%x code_off:0x%x\n",
787
      *previous_method_idx,
788
      encoded_method.method_idx_diff,
789
      encoded_method.access_flags,
790
      encoded_method.code_off);
791
#endif
792
793
0
  SIZED_STRING* method_name = dex_get_string(
794
0
      dex->object, "string_ids[%i].value", name_idx);
795
796
0
  if (method_name != NULL)
797
0
  {
798
#ifdef DEBUG_DEX_MODULE
799
    printf(
800
        "[DEX]\tMETHOD_NAME %s NAME_IDX 0x%llx\n",
801
        method_name->c_string,
802
        name_idx);
803
#endif
804
805
0
    yr_set_sized_string(
806
0
        method_name->c_string,
807
0
        method_name->length,
808
0
        dex->object,
809
0
        "method[%i].name",
810
0
        index_encoded_method);
811
0
  }
812
813
0
  int64_t class_idx = dex_get_integer(
814
0
      dex->object, "method_ids[%i].class_idx", *previous_method_idx);
815
816
0
  int64_t descriptor_idx = dex_get_integer(
817
0
      dex->object, "type_ids[%i].descriptor_idx", class_idx);
818
819
0
  SIZED_STRING* class_name = dex_get_string(
820
0
      dex->object, "string_ids[%i].value", descriptor_idx);
821
822
0
  if (class_name != NULL)
823
0
  {
824
#ifdef DEBUG_DEX_MODULE
825
    printf(
826
        "[DEX]\tCLASS_NAME %s CLASS_IDX 0x%llx DESCRIPTOR_IDX:0x%llx\n",
827
        class_name->c_string,
828
        class_idx,
829
        descriptor_idx);
830
#endif
831
832
0
    yr_set_sized_string(
833
0
        class_name->c_string,
834
0
        class_name->length,
835
0
        dex->object,
836
0
        "method[%i].class_name",
837
0
        index_encoded_method);
838
0
  }
839
840
0
  int64_t proto_idx = dex_get_integer(
841
0
      dex->object, "method_ids[%i].proto_idx", *previous_method_idx);
842
843
0
  int64_t shorty_idx = dex_get_integer(
844
0
      dex->object, "proto_ids[%i].shorty_idx", proto_idx);
845
846
0
  SIZED_STRING* proto_name = dex_get_string(
847
0
      dex->object, "string_ids[%i].value", shorty_idx);
848
849
0
  if (proto_name != NULL)
850
0
  {
851
#ifdef DEBUG_DEX_MODULE
852
    printf(
853
        "[DEX]\tPROTO_NAME %s CLASS_IDX 0x%llx DESCRIPTOR_IDX:0x%llx\n",
854
        proto_name->c_string,
855
        class_idx,
856
        descriptor_idx);
857
#endif
858
859
0
    yr_set_sized_string(
860
0
        proto_name->c_string,
861
0
        proto_name->length,
862
0
        dex->object,
863
0
        "method[%i].proto",
864
0
        index_encoded_method);
865
0
  }
866
867
0
  if (encoded_method.code_off != 0)
868
0
  {
869
#ifdef DEBUG_DEX_MODULE
870
    printf("[DEX]\t\tParse CODE item\n");
871
#endif
872
873
0
    if (struct_fits_in_dex(
874
0
            dex, dex->data + encoded_method.code_off, code_item_t))
875
0
    {
876
0
      code_item_t* code_item =
877
0
          (code_item_t*) (dex->data + encoded_method.code_off);
878
879
0
      yr_set_integer(
880
0
          code_item->registers_size,
881
0
          dex->object,
882
0
          "method[%i].code_item.registers_size",
883
0
          index_encoded_method);
884
0
      yr_set_integer(
885
0
          code_item->ins_size,
886
0
          dex->object,
887
0
          "method[%i].code_item.ins_size",
888
0
          index_encoded_method);
889
0
      yr_set_integer(
890
0
          code_item->outs_size,
891
0
          dex->object,
892
0
          "method[%i].code_item.outs_size",
893
0
          index_encoded_method);
894
0
      yr_set_integer(
895
0
          code_item->tries_size,
896
0
          dex->object,
897
0
          "method[%i].code_item.tries_size",
898
0
          index_encoded_method);
899
0
      yr_set_integer(
900
0
          code_item->debug_info_off,
901
0
          dex->object,
902
0
          "method[%i].code_item.debug_info_off",
903
0
          index_encoded_method);
904
0
      yr_set_integer(
905
0
          code_item->insns_size,
906
0
          dex->object,
907
0
          "method[%i].code_item.insns_size",
908
0
          index_encoded_method);
909
910
0
      if (fits_in_dex(
911
0
              dex,
912
0
              dex->data + encoded_method.code_off + sizeof(code_item_t),
913
0
              code_item->insns_size * 2))
914
0
      {
915
0
        yr_set_sized_string(
916
0
            (const char*) (dex->data + encoded_method.code_off + sizeof(code_item_t)),
917
0
            code_item->insns_size * 2,
918
0
            dex->object,
919
0
            "method[%i].code_item.insns",
920
0
            index_encoded_method);
921
0
      }
922
0
    }
923
0
  }
924
925
0
  return current_size;
926
0
}
927
928
929
void dex_parse(DEX* dex, uint64_t base_address)
930
0
{
931
0
  dex_header_t* dex_header;
932
933
0
  int i, j;
934
935
0
  uint32_t uleb128_size = 0;
936
0
  uint32_t new_size = 0;
937
0
  uint32_t index_class_data_item = 0;
938
0
  uint32_t index_encoded_method = 0;
939
0
  uint32_t index_encoded_field = 0;
940
941
0
  const uint8_t* data_end = dex->data + dex->data_size;
942
943
0
  if (!struct_fits_in_dex(dex, dex->data, dex_header_t))
944
0
    return;
945
946
0
  dex_parse_header(dex->header, dex->object);
947
948
0
  dex_header = dex->header;
949
950
0
  if (!fits_in_dex(
951
0
          dex,
952
0
          dex->data + yr_le32toh(dex_header->string_ids_offset),
953
0
          yr_le32toh(dex_header->string_ids_size) * sizeof(string_id_item_t)))
954
0
    return;
955
956
#ifdef DEBUG_DEX_MODULE
957
  printf("[DEX] Parse STRING ID section\n");
958
#endif
959
960
  // Get information about the String ID section
961
0
  for (i = 0; i < yr_le32toh(dex_header->string_ids_size); i++)
962
0
  {
963
0
    string_id_item_t* string_id_item =
964
0
        (string_id_item_t*) (dex->data + yr_le32toh(dex_header->string_ids_offset) + i * sizeof(string_id_item_t));
965
966
0
    if (!struct_fits_in_dex(dex, string_id_item, string_id_item_t))
967
0
      break;
968
969
#ifdef DEBUG_DEX_MODULE
970
    printf(
971
        "[DEX] STRING ID item data_offset:0x%x\n",
972
        yr_le32toh(string_id_item->string_data_offset));
973
#endif
974
975
0
    if (!fits_in_dex(
976
0
            dex,
977
0
            dex->data + yr_le32toh(string_id_item->string_data_offset),
978
0
            sizeof(uint32_t)))
979
0
      continue;
980
981
0
    bool error = false;
982
0
    uint32_t value = (uint32_t) read_uleb128_bounded(
983
0
        (dex->data + yr_le32toh(string_id_item->string_data_offset)),
984
0
        data_end, &uleb128_size, &error);
985
0
    if (error)
986
0
      continue;
987
988
#ifdef DEBUG_DEX_MODULE
989
    printf("[DEX] STRING ID item size:0x%x\n", value);
990
#endif
991
992
0
    if (!fits_in_dex(
993
0
            dex,
994
0
            dex->data + yr_le32toh(string_id_item->string_data_offset) + 1,
995
0
            value))
996
0
      continue;
997
998
0
    yr_set_integer(
999
0
        yr_le32toh(string_id_item->string_data_offset),
1000
0
        dex->object,
1001
0
        "string_ids[%i].offset",
1002
0
        i);
1003
1004
0
    yr_set_integer(value, dex->object, "string_ids[%i].size", i);
1005
1006
0
    yr_set_sized_string(
1007
0
        (const char*) (
1008
0
            dex->data + yr_le32toh(string_id_item->string_data_offset) + 1),
1009
0
        value,
1010
0
        dex->object,
1011
0
        "string_ids[%i].value",
1012
0
        i);
1013
0
  }
1014
1015
0
  if (!fits_in_dex(
1016
0
          dex,
1017
0
          dex->data + yr_le32toh(dex_header->type_ids_offset),
1018
0
          yr_le32toh(dex_header->type_ids_size) * sizeof(type_id_item_t)))
1019
0
    return;
1020
1021
#ifdef DEBUG_DEX_MODULE
1022
  printf("[DEX] Parse TYPE ID section\n");
1023
#endif
1024
1025
  // Get information about the Type ID section
1026
0
  for (i = 0; i < yr_le32toh(dex_header->type_ids_size); i++)
1027
0
  {
1028
0
    type_id_item_t* type_id_item =
1029
0
        (type_id_item_t*) (dex->data + yr_le32toh(dex_header->type_ids_offset) + i * sizeof(type_id_item_t));
1030
1031
0
    if (!struct_fits_in_dex(dex, type_id_item, type_id_item_t))
1032
0
      break;
1033
1034
0
    yr_set_integer(
1035
0
        yr_le32toh(type_id_item->descriptor_idx),
1036
0
        dex->object,
1037
0
        "type_ids[%i].descriptor_idx",
1038
0
        i);
1039
0
  }
1040
1041
0
  if (!fits_in_dex(
1042
0
          dex,
1043
0
          dex->data + yr_le32toh(dex_header->proto_ids_offset),
1044
0
          yr_le32toh(dex_header->proto_ids_size) * sizeof(proto_id_item_t)))
1045
0
    return;
1046
1047
#ifdef DEBUG_DEX_MODULE
1048
  printf("[DEX] Parse PROTO ID section\n");
1049
#endif
1050
1051
  // Get information about the Proto ID section
1052
0
  for (i = 0; i < yr_le32toh(dex_header->proto_ids_size); i++)
1053
0
  {
1054
0
    proto_id_item_t* proto_id_item =
1055
0
        (proto_id_item_t*) (dex->data + yr_le32toh(dex_header->proto_ids_offset) + i * sizeof(proto_id_item_t));
1056
1057
0
    if (!struct_fits_in_dex(dex, proto_id_item, proto_id_item_t))
1058
0
      break;
1059
1060
0
    yr_set_integer(
1061
0
        yr_le32toh(proto_id_item->shorty_idx),
1062
0
        dex->object,
1063
0
        "proto_ids[%i].shorty_idx",
1064
0
        i);
1065
0
    yr_set_integer(
1066
0
        yr_le32toh(proto_id_item->return_type_idx),
1067
0
        dex->object,
1068
0
        "proto_ids[%i].return_type_idx",
1069
0
        i);
1070
0
    yr_set_integer(
1071
0
        yr_le32toh(proto_id_item->parameters_offset),
1072
0
        dex->object,
1073
0
        "proto_ids[%i].parameters_offset",
1074
0
        i);
1075
0
  }
1076
1077
0
  if (!fits_in_dex(
1078
0
          dex,
1079
0
          dex->data + yr_le32toh(dex_header->field_ids_offset),
1080
0
          yr_le32toh(dex_header->field_ids_size) * sizeof(field_id_item_t)))
1081
0
    return;
1082
1083
#ifdef DEBUG_DEX_MODULE
1084
  printf("[DEX] Parse FIELD ID section\n");
1085
#endif
1086
1087
  // Get information about the Field ID section
1088
0
  for (i = 0; i < yr_le32toh(dex_header->field_ids_size); i++)
1089
0
  {
1090
0
    field_id_item_t* field_id_item =
1091
0
        (field_id_item_t*) (dex->data + yr_le32toh(dex_header->field_ids_offset) + i * sizeof(field_id_item_t));
1092
1093
0
    if (!struct_fits_in_dex(dex, field_id_item, field_id_item_t))
1094
0
      break;
1095
1096
0
    yr_set_integer(
1097
0
        yr_le16toh(field_id_item->class_idx),
1098
0
        dex->object,
1099
0
        "field_ids[%i].class_idx",
1100
0
        i);
1101
0
    yr_set_integer(
1102
0
        yr_le16toh(field_id_item->type_idx),
1103
0
        dex->object,
1104
0
        "field_ids[%i].type_idx",
1105
0
        i);
1106
0
    yr_set_integer(
1107
0
        yr_le32toh(field_id_item->name_idx),
1108
0
        dex->object,
1109
0
        "field_ids[%i].name_idx",
1110
0
        i);
1111
0
  }
1112
1113
0
  if (!fits_in_dex(
1114
0
          dex,
1115
0
          dex->data + yr_le32toh(dex_header->method_ids_offset),
1116
0
          yr_le32toh(dex_header->method_ids_size) * sizeof(method_id_item_t)))
1117
0
    return;
1118
1119
#ifdef DEBUG_DEX_MODULE
1120
  printf("[DEX] Parse METHOD ID section\n");
1121
#endif
1122
1123
  // Get information about the Method ID section
1124
0
  for (i = 0; i < yr_le32toh(dex_header->method_ids_size); i++)
1125
0
  {
1126
0
    method_id_item_t* method_id_item =
1127
0
        (method_id_item_t*) (dex->data + yr_le32toh(dex_header->method_ids_offset) + i * sizeof(method_id_item_t));
1128
1129
0
    if (!struct_fits_in_dex(dex, method_id_item, method_id_item_t))
1130
0
      break;
1131
1132
0
    yr_set_integer(
1133
0
        yr_le16toh(method_id_item->class_idx),
1134
0
        dex->object,
1135
0
        "method_ids[%i].class_idx",
1136
0
        i);
1137
0
    yr_set_integer(
1138
0
        yr_le16toh(method_id_item->proto_idx),
1139
0
        dex->object,
1140
0
        "method_ids[%i].proto_idx",
1141
0
        i);
1142
0
    yr_set_integer(
1143
0
        yr_le32toh(method_id_item->name_idx),
1144
0
        dex->object,
1145
0
        "method_ids[%i].name_idx",
1146
0
        i);
1147
0
  }
1148
1149
#ifdef DEBUG_DEX_MODULE
1150
  printf("[DEX] Parse MAP List ID section\n");
1151
#endif
1152
1153
  // Get information about the Map List ID section
1154
0
  if (yr_le32toh(dex_header->map_offset) != 0 &&
1155
0
      fits_in_dex(
1156
0
          dex,
1157
0
          dex->data + yr_le32toh(dex_header->map_offset),
1158
0
          sizeof(uint32_t)))
1159
0
  {
1160
0
    uint32_t map_list_size;
1161
1162
    // map_offset comes from the DEX file and is not necessarily 4-byte
1163
    // aligned. Read it through memcpy so the load is defined regardless of
1164
    // the offset's alignment instead of dereferencing a uint32_t* that UBSan
1165
    // rejects on misaligned input.
1166
0
    memcpy(
1167
0
        &map_list_size,
1168
0
        dex->data + yr_le32toh(dex_header->map_offset),
1169
0
        sizeof(uint32_t));
1170
0
    map_list_size = yr_le32toh(map_list_size);
1171
1172
0
    yr_set_integer(map_list_size, dex->object, "map_list.size");
1173
1174
0
    if (!fits_in_dex(
1175
0
            dex,
1176
0
            dex->data + yr_le32toh(dex_header->map_offset),
1177
0
            sizeof(uint32_t) + (size_t) map_list_size * sizeof(map_item_t)))
1178
0
      return;
1179
1180
0
    for (i = 0; i < map_list_size; i++)
1181
0
    {
1182
0
      map_item_t* map_item =
1183
0
          (map_item_t*) (dex->data + yr_le32toh(dex_header->map_offset) + sizeof(uint32_t) + i * sizeof(map_item_t));
1184
1185
0
      if (!struct_fits_in_dex(dex, map_item, map_item_t))
1186
0
        return;
1187
1188
0
      yr_set_integer(
1189
0
          yr_le16toh(map_item->type),
1190
0
          dex->object,
1191
0
          "map_list.map_item[%i].type",
1192
0
          i);
1193
0
      yr_set_integer(
1194
0
          yr_le16toh(map_item->unused),
1195
0
          dex->object,
1196
0
          "map_list.map_item[%i].unused",
1197
0
          i);
1198
0
      yr_set_integer(
1199
0
          yr_le32toh(map_item->size),
1200
0
          dex->object,
1201
0
          "map_list.map_item[%i].size",
1202
0
          i);
1203
0
      yr_set_integer(
1204
0
          yr_le32toh(map_item->offset),
1205
0
          dex->object,
1206
0
          "map_list.map_item[%i].offset",
1207
0
          i);
1208
0
    }
1209
0
  }
1210
1211
0
  if (!fits_in_dex(
1212
0
          dex,
1213
0
          dex->data + yr_le32toh(dex_header->class_defs_offset),
1214
0
          yr_le32toh(dex_header->class_defs_size) * sizeof(class_id_item_t)))
1215
0
    return;
1216
1217
#ifdef DEBUG_DEX_MODULE
1218
  printf("[DEX] Parse CLASS ID section\n");
1219
#endif
1220
1221
  // Get information about the Class ID section
1222
0
  for (i = 0; i < yr_le32toh(dex_header->class_defs_size); i++)
1223
0
  {
1224
0
    class_id_item_t* class_id_item =
1225
0
        (class_id_item_t*) (dex->data + yr_le32toh(dex_header->class_defs_offset) + i * sizeof(class_id_item_t));
1226
1227
0
    if (!struct_fits_in_dex(dex, class_id_item, class_id_item_t))
1228
0
      break;
1229
1230
#ifdef DEBUG_DEX_MODULE
1231
    printf(
1232
        "[DEX] CLASS ID item class_idx:0x%x access_flags:0x%x "
1233
        "super_class_idx:0x%x interfaces_offset:0x%x source_file_idx:0x%x "
1234
        "annotations_offset:0x%x class_data_offset:0x%x "
1235
        "static_values_offset:0x%x\n",
1236
        yr_le32toh(class_id_item->class_idx),
1237
        yr_le32toh(class_id_item->access_flags),
1238
        yr_le32toh(class_id_item->super_class_idx),
1239
        yr_le32toh(class_id_item->interfaces_offset),
1240
        yr_le32toh(class_id_item->source_file_idx),
1241
        yr_le32toh(class_id_item->annotations_offset),
1242
        yr_le32toh(class_id_item->class_data_offset),
1243
        yr_le32toh(class_id_item->static_values_offset));
1244
#endif
1245
1246
0
    yr_set_integer(
1247
0
        yr_le32toh(class_id_item->class_idx),
1248
0
        dex->object,
1249
0
        "class_defs[%i].class_idx",
1250
0
        i);
1251
0
    yr_set_integer(
1252
0
        yr_le32toh(class_id_item->access_flags),
1253
0
        dex->object,
1254
0
        "class_defs[%i].access_flags",
1255
0
        i);
1256
0
    yr_set_integer(
1257
0
        yr_le32toh(class_id_item->super_class_idx),
1258
0
        dex->object,
1259
0
        "class_defs[%i].super_class_idx",
1260
0
        i);
1261
0
    yr_set_integer(
1262
0
        yr_le32toh(class_id_item->interfaces_offset),
1263
0
        dex->object,
1264
0
        "class_defs[%i].interfaces_offset",
1265
0
        i);
1266
0
    yr_set_integer(
1267
0
        yr_le32toh(class_id_item->source_file_idx),
1268
0
        dex->object,
1269
0
        "class_defs[%i].source_file_idx",
1270
0
        i);
1271
0
    yr_set_integer(
1272
0
        yr_le32toh(class_id_item->annotations_offset),
1273
0
        dex->object,
1274
0
        "class_defs[%i].annotations_offset",
1275
0
        i);
1276
0
    yr_set_integer(
1277
0
        yr_le32toh(class_id_item->class_data_offset),
1278
0
        dex->object,
1279
0
        "class_defs[%i].class_data_offset",
1280
0
        i);
1281
0
    yr_set_integer(
1282
0
        yr_le32toh(class_id_item->static_values_offset),
1283
0
        dex->object,
1284
0
        "class_defs[%i].static_values_offset",
1285
0
        i);
1286
1287
0
    if (yr_le32toh(class_id_item->class_data_offset) != 0)
1288
0
    {
1289
0
      class_data_item_t class_data_item;
1290
1291
0
      if (!fits_in_dex(
1292
0
              dex,
1293
0
              dex->data + yr_le32toh(class_id_item->class_data_offset),
1294
0
              4 * sizeof(uint32_t)))
1295
0
        return;
1296
1297
0
      uleb128_size = 0;
1298
0
      bool error = false;
1299
1300
0
      class_data_item.static_fields_size = (uint32_t) read_uleb128_bounded(
1301
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset)),
1302
0
          data_end, &uleb128_size, &error);
1303
0
      if (error)
1304
0
        return;
1305
1306
0
      class_data_item.instance_fields_size = (uint32_t) read_uleb128_bounded(
1307
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1308
0
           uleb128_size),
1309
0
          data_end, &uleb128_size, &error);
1310
0
      if (error)
1311
0
        return;
1312
1313
0
      class_data_item.direct_methods_size = (uint32_t) read_uleb128_bounded(
1314
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1315
0
           uleb128_size),
1316
0
          data_end, &uleb128_size, &error);
1317
0
      if (error)
1318
0
        return;
1319
1320
0
      class_data_item.virtual_methods_size = (uint32_t) read_uleb128_bounded(
1321
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1322
0
           uleb128_size),
1323
0
          data_end, &uleb128_size, &error);
1324
0
      if (error)
1325
0
        return;
1326
1327
0
      yr_set_integer(
1328
0
          class_data_item.static_fields_size,
1329
0
          dex->object,
1330
0
          "class_data_item[%i].static_fields_size",
1331
0
          index_class_data_item);
1332
1333
0
      yr_set_integer(
1334
0
          class_data_item.instance_fields_size,
1335
0
          dex->object,
1336
0
          "class_data_item[%i].instance_fields_size",
1337
0
          index_class_data_item);
1338
1339
0
      yr_set_integer(
1340
0
          class_data_item.direct_methods_size,
1341
0
          dex->object,
1342
0
          "class_data_item[%i].direct_methods_size",
1343
0
          index_class_data_item);
1344
1345
0
      yr_set_integer(
1346
0
          class_data_item.virtual_methods_size,
1347
0
          dex->object,
1348
0
          "class_data_item[%i].virtual_methods_size",
1349
0
          index_class_data_item);
1350
1351
#ifdef DEBUG_DEX_MODULE
1352
      printf("[DEX] CLASS DATA item static fields\n");
1353
#endif
1354
1355
0
      uint32_t previous_field_idx = 0;
1356
0
      for (j = 0; j < class_data_item.static_fields_size; j++)
1357
0
      {
1358
0
        new_size = load_encoded_field(
1359
0
            dex,
1360
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1361
0
            &previous_field_idx,
1362
0
            index_encoded_field,
1363
0
            1,
1364
0
            0);
1365
1366
        // If the current field isn't parsed the other fields aren't likely to
1367
        // parse.
1368
0
        if (new_size == 0)
1369
0
          break;
1370
1371
0
        uleb128_size += new_size;
1372
0
        index_encoded_field += 1;
1373
0
      }
1374
1375
#ifdef DEBUG_DEX_MODULE
1376
      printf("[DEX] CLASS DATA item instance fields\n");
1377
#endif
1378
1379
0
      previous_field_idx = 0;
1380
1381
0
      for (j = 0; j < class_data_item.instance_fields_size; j++)
1382
0
      {
1383
0
        new_size = load_encoded_field(
1384
0
            dex,
1385
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1386
0
            &previous_field_idx,
1387
0
            index_encoded_field,
1388
0
            0,
1389
0
            1);
1390
1391
        // If the current field isn't parsed the other fields aren't likely to
1392
        // parse.
1393
0
        if (new_size == 0)
1394
0
          break;
1395
1396
0
        uleb128_size += new_size;
1397
0
        index_encoded_field += 1;
1398
0
      }
1399
1400
#ifdef DEBUG_DEX_MODULE
1401
      printf("[DEX] CLASS DATA item direct methods\n");
1402
#endif
1403
1404
0
      uint32_t previous_method_idx = 0;
1405
1406
0
      for (j = 0; j < class_data_item.direct_methods_size; j++)
1407
0
      {
1408
0
        new_size = load_encoded_method(
1409
0
            dex,
1410
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1411
0
            &previous_method_idx,
1412
0
            index_encoded_method,
1413
0
            1,
1414
0
            0);
1415
1416
        // If the current field isn't parsed the other fields aren't likely to
1417
        // parse.
1418
0
        if (new_size == 0)
1419
0
          break;
1420
1421
0
        uleb128_size += new_size;
1422
0
        index_encoded_method += 1;
1423
0
      }
1424
1425
#ifdef DEBUG_DEX_MODULE
1426
      printf("[DEX] CLASS DATA item virtual methods\n");
1427
#endif
1428
1429
0
      previous_method_idx = 0;
1430
1431
0
      for (j = 0; j < class_data_item.virtual_methods_size; j++)
1432
0
      {
1433
0
        new_size = load_encoded_method(
1434
0
            dex,
1435
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1436
0
            &previous_method_idx,
1437
0
            index_encoded_method,
1438
0
            0,
1439
0
            1);
1440
1441
        // If the current field isn't parsed the other fields aren't likely to
1442
        // parse.
1443
0
        if (new_size == 0)
1444
0
          break;
1445
1446
0
        uleb128_size += new_size;
1447
0
        index_encoded_method += 1;
1448
0
      }
1449
1450
0
      index_class_data_item++;
1451
0
    }
1452
0
  }
1453
1454
0
  yr_set_integer(index_encoded_method, dex->object, "number_of_methods");
1455
0
  yr_set_integer(index_encoded_field, dex->object, "number_of_fields");
1456
0
}
1457
1458
1459
int module_initialize(YR_MODULE* module)
1460
2
{
1461
2
  return ERROR_SUCCESS;
1462
2
}
1463
1464
1465
int module_finalize(YR_MODULE* module)
1466
0
{
1467
0
  return ERROR_SUCCESS;
1468
0
}
1469
1470
1471
int module_load(
1472
    YR_SCAN_CONTEXT* context,
1473
    YR_OBJECT* module_object,
1474
    void* module_data,
1475
    size_t module_data_size)
1476
0
{
1477
0
  YR_MEMORY_BLOCK* block;
1478
0
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1479
1480
0
  dex_header_t* dex_header;
1481
1482
0
  yr_set_sized_string(
1483
0
      DEX_FILE_MAGIC_035, 8, module_object, "DEX_FILE_MAGIC_035");
1484
0
  yr_set_sized_string(
1485
0
      DEX_FILE_MAGIC_036, 8, module_object, "DEX_FILE_MAGIC_036");
1486
0
  yr_set_sized_string(
1487
0
      DEX_FILE_MAGIC_037, 8, module_object, "DEX_FILE_MAGIC_037");
1488
0
  yr_set_sized_string(
1489
0
      DEX_FILE_MAGIC_038, 8, module_object, "DEX_FILE_MAGIC_038");
1490
0
  yr_set_sized_string(
1491
0
      DEX_FILE_MAGIC_039, 8, module_object, "DEX_FILE_MAGIC_039");
1492
1493
0
  yr_set_integer(0x12345678, module_object, "ENDIAN_CONSTANT");
1494
0
  yr_set_integer(0x78563412, module_object, "REVERSE_ENDIAN_CONSTANT");
1495
1496
0
  yr_set_integer(0xffffffff, module_object, "NO_INDEX");
1497
0
  yr_set_integer(0x1, module_object, "ACC_PUBLIC");
1498
0
  yr_set_integer(0x2, module_object, "ACC_PRIVATE");
1499
0
  yr_set_integer(0x4, module_object, "ACC_PROTECTED");
1500
0
  yr_set_integer(0x8, module_object, "ACC_STATIC");
1501
0
  yr_set_integer(0x10, module_object, "ACC_FINAL");
1502
0
  yr_set_integer(0x20, module_object, "ACC_SYNCHRONIZED");
1503
0
  yr_set_integer(0x40, module_object, "ACC_VOLATILE");
1504
0
  yr_set_integer(0x40, module_object, "ACC_BRIDGE");
1505
0
  yr_set_integer(0x80, module_object, "ACC_TRANSIENT");
1506
0
  yr_set_integer(0x80, module_object, "ACC_VARARGS");
1507
0
  yr_set_integer(0x100, module_object, "ACC_NATIVE");
1508
0
  yr_set_integer(0x200, module_object, "ACC_INTERFACE");
1509
0
  yr_set_integer(0x400, module_object, "ACC_ABSTRACT");
1510
0
  yr_set_integer(0x800, module_object, "ACC_STRICT");
1511
0
  yr_set_integer(0x1000, module_object, "ACC_SYNTHETIC");
1512
0
  yr_set_integer(0x2000, module_object, "ACC_ANNOTATION");
1513
0
  yr_set_integer(0x4000, module_object, "ACC_ENUM");
1514
0
  yr_set_integer(0x10000, module_object, "ACC_CONSTRUCTOR");
1515
0
  yr_set_integer(0x20000, module_object, "ACC_DECLARED_SYNCHRONIZED");
1516
1517
0
  yr_set_integer(0x0000, module_object, "TYPE_HEADER_ITEM");
1518
0
  yr_set_integer(0x0001, module_object, "TYPE_STRING_ID_ITEM");
1519
0
  yr_set_integer(0x0002, module_object, "TYPE_TYPE_ID_ITEM");
1520
0
  yr_set_integer(0x0003, module_object, "TYPE_PROTO_ID_ITEM");
1521
0
  yr_set_integer(0x0004, module_object, "TYPE_FIELD_ID_ITEM");
1522
0
  yr_set_integer(0x0005, module_object, "TYPE_METHOD_ID_ITEM");
1523
0
  yr_set_integer(0x0006, module_object, "TYPE_CLASS_DEF_ITEM");
1524
0
  yr_set_integer(0x0007, module_object, "TYPE_CALL_SITE_ID_ITEM");
1525
0
  yr_set_integer(0x0008, module_object, "TYPE_METHOD_HANDLE_ITEM");
1526
0
  yr_set_integer(0x1000, module_object, "TYPE_MAP_LIST");
1527
0
  yr_set_integer(0x1001, module_object, "TYPE_TYPE_LIST");
1528
0
  yr_set_integer(0x1002, module_object, "TYPE_ANNOTATION_SET_REF_LIST");
1529
0
  yr_set_integer(0x1003, module_object, "TYPE_ANNOTATION_SET_ITEM");
1530
0
  yr_set_integer(0x2000, module_object, "TYPE_CLASS_DATA_ITEM");
1531
0
  yr_set_integer(0x2001, module_object, "TYPE_CODE_ITEM");
1532
0
  yr_set_integer(0x2002, module_object, "TYPE_STRING_DATA_ITEM");
1533
0
  yr_set_integer(0x2003, module_object, "TYPE_DEBUG_INFO_ITEM");
1534
0
  yr_set_integer(0x2004, module_object, "TYPE_ANNOTATION_ITEM");
1535
0
  yr_set_integer(0x2005, module_object, "TYPE_ENCODED_ARRAY_ITEM");
1536
0
  yr_set_integer(0x2006, module_object, "TYPE_ANNOTATIONS_DIRECTORY_ITEM");
1537
1538
0
  foreach_memory_block(iterator, block)
1539
0
  {
1540
0
    const uint8_t* block_data = yr_fetch_block_data(block);
1541
1542
0
    if (block_data == NULL)
1543
0
      continue;
1544
1545
0
    dex_header = dex_get_header(block_data, block->size);
1546
1547
0
    if (dex_header != NULL)
1548
0
    {
1549
0
      DEX* dex = (DEX*) yr_malloc(sizeof(DEX));
1550
1551
0
      if (dex == NULL)
1552
0
        return ERROR_INSUFFICIENT_MEMORY;
1553
1554
0
      dex->data = block_data;
1555
0
      dex->data_size = block->size;
1556
0
      dex->object = module_object;
1557
0
      dex->header = dex_header;
1558
1559
0
      module_object->data = dex;
1560
1561
0
      dex_parse(dex, block->base);
1562
0
      break;
1563
0
    }
1564
0
  }
1565
1566
0
  return ERROR_SUCCESS;
1567
0
}
1568
1569
1570
int module_unload(YR_OBJECT* module_object)
1571
0
{
1572
0
  DEX* dex = (DEX*) module_object->data;
1573
1574
0
  if (dex == NULL)
1575
0
    return ERROR_SUCCESS;
1576
1577
0
  yr_free(dex);
1578
1579
0
  return ERROR_SUCCESS;
1580
0
}
1581
1582
#undef MODULE_NAME