Coverage Report

Created: 2026-07-10 06:40

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
0
        (uint32_t*) (dex->data + yr_le32toh(dex_header->map_offset));
1162
1163
0
    yr_set_integer(yr_le32toh(*map_list_size), dex->object, "map_list.size");
1164
1165
0
    if (!fits_in_dex(
1166
0
            dex,
1167
0
            dex->data + yr_le32toh(dex_header->map_offset),
1168
0
            sizeof(uint32_t) + yr_le32toh(*map_list_size) * sizeof(map_item_t)))
1169
0
      return;
1170
1171
0
    for (i = 0; i < yr_le32toh(*map_list_size); i++)
1172
0
    {
1173
0
      map_item_t* map_item =
1174
0
          (map_item_t*) (dex->data + yr_le32toh(dex_header->map_offset) + sizeof(uint32_t) + i * sizeof(map_item_t));
1175
1176
0
      if (!struct_fits_in_dex(dex, map_item, map_item_t))
1177
0
        return;
1178
1179
0
      yr_set_integer(
1180
0
          yr_le16toh(map_item->type),
1181
0
          dex->object,
1182
0
          "map_list.map_item[%i].type",
1183
0
          i);
1184
0
      yr_set_integer(
1185
0
          yr_le16toh(map_item->unused),
1186
0
          dex->object,
1187
0
          "map_list.map_item[%i].unused",
1188
0
          i);
1189
0
      yr_set_integer(
1190
0
          yr_le32toh(map_item->size),
1191
0
          dex->object,
1192
0
          "map_list.map_item[%i].size",
1193
0
          i);
1194
0
      yr_set_integer(
1195
0
          yr_le32toh(map_item->offset),
1196
0
          dex->object,
1197
0
          "map_list.map_item[%i].offset",
1198
0
          i);
1199
0
    }
1200
0
  }
1201
1202
0
  if (!fits_in_dex(
1203
0
          dex,
1204
0
          dex->data + yr_le32toh(dex_header->class_defs_offset),
1205
0
          yr_le32toh(dex_header->class_defs_size) * sizeof(class_id_item_t)))
1206
0
    return;
1207
1208
#ifdef DEBUG_DEX_MODULE
1209
  printf("[DEX] Parse CLASS ID section\n");
1210
#endif
1211
1212
  // Get information about the Class ID section
1213
0
  for (i = 0; i < yr_le32toh(dex_header->class_defs_size); i++)
1214
0
  {
1215
0
    class_id_item_t* class_id_item =
1216
0
        (class_id_item_t*) (dex->data + yr_le32toh(dex_header->class_defs_offset) + i * sizeof(class_id_item_t));
1217
1218
0
    if (!struct_fits_in_dex(dex, class_id_item, class_id_item_t))
1219
0
      break;
1220
1221
#ifdef DEBUG_DEX_MODULE
1222
    printf(
1223
        "[DEX] CLASS ID item class_idx:0x%x access_flags:0x%x "
1224
        "super_class_idx:0x%x interfaces_offset:0x%x source_file_idx:0x%x "
1225
        "annotations_offset:0x%x class_data_offset:0x%x "
1226
        "static_values_offset:0x%x\n",
1227
        yr_le32toh(class_id_item->class_idx),
1228
        yr_le32toh(class_id_item->access_flags),
1229
        yr_le32toh(class_id_item->super_class_idx),
1230
        yr_le32toh(class_id_item->interfaces_offset),
1231
        yr_le32toh(class_id_item->source_file_idx),
1232
        yr_le32toh(class_id_item->annotations_offset),
1233
        yr_le32toh(class_id_item->class_data_offset),
1234
        yr_le32toh(class_id_item->static_values_offset));
1235
#endif
1236
1237
0
    yr_set_integer(
1238
0
        yr_le32toh(class_id_item->class_idx),
1239
0
        dex->object,
1240
0
        "class_defs[%i].class_idx",
1241
0
        i);
1242
0
    yr_set_integer(
1243
0
        yr_le32toh(class_id_item->access_flags),
1244
0
        dex->object,
1245
0
        "class_defs[%i].access_flags",
1246
0
        i);
1247
0
    yr_set_integer(
1248
0
        yr_le32toh(class_id_item->super_class_idx),
1249
0
        dex->object,
1250
0
        "class_defs[%i].super_class_idx",
1251
0
        i);
1252
0
    yr_set_integer(
1253
0
        yr_le32toh(class_id_item->interfaces_offset),
1254
0
        dex->object,
1255
0
        "class_defs[%i].interfaces_offset",
1256
0
        i);
1257
0
    yr_set_integer(
1258
0
        yr_le32toh(class_id_item->source_file_idx),
1259
0
        dex->object,
1260
0
        "class_defs[%i].source_file_idx",
1261
0
        i);
1262
0
    yr_set_integer(
1263
0
        yr_le32toh(class_id_item->annotations_offset),
1264
0
        dex->object,
1265
0
        "class_defs[%i].annotations_offset",
1266
0
        i);
1267
0
    yr_set_integer(
1268
0
        yr_le32toh(class_id_item->class_data_offset),
1269
0
        dex->object,
1270
0
        "class_defs[%i].class_data_offset",
1271
0
        i);
1272
0
    yr_set_integer(
1273
0
        yr_le32toh(class_id_item->static_values_offset),
1274
0
        dex->object,
1275
0
        "class_defs[%i].static_values_offset",
1276
0
        i);
1277
1278
0
    if (yr_le32toh(class_id_item->class_data_offset) != 0)
1279
0
    {
1280
0
      class_data_item_t class_data_item;
1281
1282
0
      if (!fits_in_dex(
1283
0
              dex,
1284
0
              dex->data + yr_le32toh(class_id_item->class_data_offset),
1285
0
              4 * sizeof(uint32_t)))
1286
0
        return;
1287
1288
0
      uleb128_size = 0;
1289
0
      bool error = false;
1290
1291
0
      class_data_item.static_fields_size = (uint32_t) read_uleb128_bounded(
1292
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset)),
1293
0
          data_end, &uleb128_size, &error);
1294
0
      if (error)
1295
0
        return;
1296
1297
0
      class_data_item.instance_fields_size = (uint32_t) read_uleb128_bounded(
1298
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1299
0
           uleb128_size),
1300
0
          data_end, &uleb128_size, &error);
1301
0
      if (error)
1302
0
        return;
1303
1304
0
      class_data_item.direct_methods_size = (uint32_t) read_uleb128_bounded(
1305
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1306
0
           uleb128_size),
1307
0
          data_end, &uleb128_size, &error);
1308
0
      if (error)
1309
0
        return;
1310
1311
0
      class_data_item.virtual_methods_size = (uint32_t) read_uleb128_bounded(
1312
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1313
0
           uleb128_size),
1314
0
          data_end, &uleb128_size, &error);
1315
0
      if (error)
1316
0
        return;
1317
1318
0
      yr_set_integer(
1319
0
          class_data_item.static_fields_size,
1320
0
          dex->object,
1321
0
          "class_data_item[%i].static_fields_size",
1322
0
          index_class_data_item);
1323
1324
0
      yr_set_integer(
1325
0
          class_data_item.instance_fields_size,
1326
0
          dex->object,
1327
0
          "class_data_item[%i].instance_fields_size",
1328
0
          index_class_data_item);
1329
1330
0
      yr_set_integer(
1331
0
          class_data_item.direct_methods_size,
1332
0
          dex->object,
1333
0
          "class_data_item[%i].direct_methods_size",
1334
0
          index_class_data_item);
1335
1336
0
      yr_set_integer(
1337
0
          class_data_item.virtual_methods_size,
1338
0
          dex->object,
1339
0
          "class_data_item[%i].virtual_methods_size",
1340
0
          index_class_data_item);
1341
1342
#ifdef DEBUG_DEX_MODULE
1343
      printf("[DEX] CLASS DATA item static fields\n");
1344
#endif
1345
1346
0
      uint32_t previous_field_idx = 0;
1347
0
      for (j = 0; j < class_data_item.static_fields_size; j++)
1348
0
      {
1349
0
        new_size = load_encoded_field(
1350
0
            dex,
1351
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1352
0
            &previous_field_idx,
1353
0
            index_encoded_field,
1354
0
            1,
1355
0
            0);
1356
1357
        // If the current field isn't parsed the other fields aren't likely to
1358
        // parse.
1359
0
        if (new_size == 0)
1360
0
          break;
1361
1362
0
        uleb128_size += new_size;
1363
0
        index_encoded_field += 1;
1364
0
      }
1365
1366
#ifdef DEBUG_DEX_MODULE
1367
      printf("[DEX] CLASS DATA item instance fields\n");
1368
#endif
1369
1370
0
      previous_field_idx = 0;
1371
1372
0
      for (j = 0; j < class_data_item.instance_fields_size; j++)
1373
0
      {
1374
0
        new_size = load_encoded_field(
1375
0
            dex,
1376
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1377
0
            &previous_field_idx,
1378
0
            index_encoded_field,
1379
0
            0,
1380
0
            1);
1381
1382
        // If the current field isn't parsed the other fields aren't likely to
1383
        // parse.
1384
0
        if (new_size == 0)
1385
0
          break;
1386
1387
0
        uleb128_size += new_size;
1388
0
        index_encoded_field += 1;
1389
0
      }
1390
1391
#ifdef DEBUG_DEX_MODULE
1392
      printf("[DEX] CLASS DATA item direct methods\n");
1393
#endif
1394
1395
0
      uint32_t previous_method_idx = 0;
1396
1397
0
      for (j = 0; j < class_data_item.direct_methods_size; j++)
1398
0
      {
1399
0
        new_size = load_encoded_method(
1400
0
            dex,
1401
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1402
0
            &previous_method_idx,
1403
0
            index_encoded_method,
1404
0
            1,
1405
0
            0);
1406
1407
        // If the current field isn't parsed the other fields aren't likely to
1408
        // parse.
1409
0
        if (new_size == 0)
1410
0
          break;
1411
1412
0
        uleb128_size += new_size;
1413
0
        index_encoded_method += 1;
1414
0
      }
1415
1416
#ifdef DEBUG_DEX_MODULE
1417
      printf("[DEX] CLASS DATA item virtual methods\n");
1418
#endif
1419
1420
0
      previous_method_idx = 0;
1421
1422
0
      for (j = 0; j < class_data_item.virtual_methods_size; j++)
1423
0
      {
1424
0
        new_size = load_encoded_method(
1425
0
            dex,
1426
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1427
0
            &previous_method_idx,
1428
0
            index_encoded_method,
1429
0
            0,
1430
0
            1);
1431
1432
        // If the current field isn't parsed the other fields aren't likely to
1433
        // parse.
1434
0
        if (new_size == 0)
1435
0
          break;
1436
1437
0
        uleb128_size += new_size;
1438
0
        index_encoded_method += 1;
1439
0
      }
1440
1441
0
      index_class_data_item++;
1442
0
    }
1443
0
  }
1444
1445
0
  yr_set_integer(index_encoded_method, dex->object, "number_of_methods");
1446
0
  yr_set_integer(index_encoded_field, dex->object, "number_of_fields");
1447
0
}
1448
1449
1450
int module_initialize(YR_MODULE* module)
1451
2
{
1452
2
  return ERROR_SUCCESS;
1453
2
}
1454
1455
1456
int module_finalize(YR_MODULE* module)
1457
0
{
1458
0
  return ERROR_SUCCESS;
1459
0
}
1460
1461
1462
int module_load(
1463
    YR_SCAN_CONTEXT* context,
1464
    YR_OBJECT* module_object,
1465
    void* module_data,
1466
    size_t module_data_size)
1467
0
{
1468
0
  YR_MEMORY_BLOCK* block;
1469
0
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1470
1471
0
  dex_header_t* dex_header;
1472
1473
0
  yr_set_sized_string(
1474
0
      DEX_FILE_MAGIC_035, 8, module_object, "DEX_FILE_MAGIC_035");
1475
0
  yr_set_sized_string(
1476
0
      DEX_FILE_MAGIC_036, 8, module_object, "DEX_FILE_MAGIC_036");
1477
0
  yr_set_sized_string(
1478
0
      DEX_FILE_MAGIC_037, 8, module_object, "DEX_FILE_MAGIC_037");
1479
0
  yr_set_sized_string(
1480
0
      DEX_FILE_MAGIC_038, 8, module_object, "DEX_FILE_MAGIC_038");
1481
0
  yr_set_sized_string(
1482
0
      DEX_FILE_MAGIC_039, 8, module_object, "DEX_FILE_MAGIC_039");
1483
1484
0
  yr_set_integer(0x12345678, module_object, "ENDIAN_CONSTANT");
1485
0
  yr_set_integer(0x78563412, module_object, "REVERSE_ENDIAN_CONSTANT");
1486
1487
0
  yr_set_integer(0xffffffff, module_object, "NO_INDEX");
1488
0
  yr_set_integer(0x1, module_object, "ACC_PUBLIC");
1489
0
  yr_set_integer(0x2, module_object, "ACC_PRIVATE");
1490
0
  yr_set_integer(0x4, module_object, "ACC_PROTECTED");
1491
0
  yr_set_integer(0x8, module_object, "ACC_STATIC");
1492
0
  yr_set_integer(0x10, module_object, "ACC_FINAL");
1493
0
  yr_set_integer(0x20, module_object, "ACC_SYNCHRONIZED");
1494
0
  yr_set_integer(0x40, module_object, "ACC_VOLATILE");
1495
0
  yr_set_integer(0x40, module_object, "ACC_BRIDGE");
1496
0
  yr_set_integer(0x80, module_object, "ACC_TRANSIENT");
1497
0
  yr_set_integer(0x80, module_object, "ACC_VARARGS");
1498
0
  yr_set_integer(0x100, module_object, "ACC_NATIVE");
1499
0
  yr_set_integer(0x200, module_object, "ACC_INTERFACE");
1500
0
  yr_set_integer(0x400, module_object, "ACC_ABSTRACT");
1501
0
  yr_set_integer(0x800, module_object, "ACC_STRICT");
1502
0
  yr_set_integer(0x1000, module_object, "ACC_SYNTHETIC");
1503
0
  yr_set_integer(0x2000, module_object, "ACC_ANNOTATION");
1504
0
  yr_set_integer(0x4000, module_object, "ACC_ENUM");
1505
0
  yr_set_integer(0x10000, module_object, "ACC_CONSTRUCTOR");
1506
0
  yr_set_integer(0x20000, module_object, "ACC_DECLARED_SYNCHRONIZED");
1507
1508
0
  yr_set_integer(0x0000, module_object, "TYPE_HEADER_ITEM");
1509
0
  yr_set_integer(0x0001, module_object, "TYPE_STRING_ID_ITEM");
1510
0
  yr_set_integer(0x0002, module_object, "TYPE_TYPE_ID_ITEM");
1511
0
  yr_set_integer(0x0003, module_object, "TYPE_PROTO_ID_ITEM");
1512
0
  yr_set_integer(0x0004, module_object, "TYPE_FIELD_ID_ITEM");
1513
0
  yr_set_integer(0x0005, module_object, "TYPE_METHOD_ID_ITEM");
1514
0
  yr_set_integer(0x0006, module_object, "TYPE_CLASS_DEF_ITEM");
1515
0
  yr_set_integer(0x0007, module_object, "TYPE_CALL_SITE_ID_ITEM");
1516
0
  yr_set_integer(0x0008, module_object, "TYPE_METHOD_HANDLE_ITEM");
1517
0
  yr_set_integer(0x1000, module_object, "TYPE_MAP_LIST");
1518
0
  yr_set_integer(0x1001, module_object, "TYPE_TYPE_LIST");
1519
0
  yr_set_integer(0x1002, module_object, "TYPE_ANNOTATION_SET_REF_LIST");
1520
0
  yr_set_integer(0x1003, module_object, "TYPE_ANNOTATION_SET_ITEM");
1521
0
  yr_set_integer(0x2000, module_object, "TYPE_CLASS_DATA_ITEM");
1522
0
  yr_set_integer(0x2001, module_object, "TYPE_CODE_ITEM");
1523
0
  yr_set_integer(0x2002, module_object, "TYPE_STRING_DATA_ITEM");
1524
0
  yr_set_integer(0x2003, module_object, "TYPE_DEBUG_INFO_ITEM");
1525
0
  yr_set_integer(0x2004, module_object, "TYPE_ANNOTATION_ITEM");
1526
0
  yr_set_integer(0x2005, module_object, "TYPE_ENCODED_ARRAY_ITEM");
1527
0
  yr_set_integer(0x2006, module_object, "TYPE_ANNOTATIONS_DIRECTORY_ITEM");
1528
1529
0
  foreach_memory_block(iterator, block)
1530
0
  {
1531
0
    const uint8_t* block_data = yr_fetch_block_data(block);
1532
1533
0
    if (block_data == NULL)
1534
0
      continue;
1535
1536
0
    dex_header = dex_get_header(block_data, block->size);
1537
1538
0
    if (dex_header != NULL)
1539
0
    {
1540
0
      DEX* dex = (DEX*) yr_malloc(sizeof(DEX));
1541
1542
0
      if (dex == NULL)
1543
0
        return ERROR_INSUFFICIENT_MEMORY;
1544
1545
0
      dex->data = block_data;
1546
0
      dex->data_size = block->size;
1547
0
      dex->object = module_object;
1548
0
      dex->header = dex_header;
1549
1550
0
      module_object->data = dex;
1551
1552
0
      dex_parse(dex, block->base);
1553
0
      break;
1554
0
    }
1555
0
  }
1556
1557
0
  return ERROR_SUCCESS;
1558
0
}
1559
1560
1561
int module_unload(YR_OBJECT* module_object)
1562
0
{
1563
0
  DEX* dex = (DEX*) module_object->data;
1564
1565
0
  if (dex == NULL)
1566
0
    return ERROR_SUCCESS;
1567
1568
0
  yr_free(dex);
1569
1570
0
  return ERROR_SUCCESS;
1571
0
}
1572
1573
#undef MODULE_NAME