Coverage Report

Created: 2025-04-24 06:32

/src/yara/libyara/modules/dex/dex.c
Line
Count
Source (jump to first uncovered line)
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
3
begin_declarations
194
3
  declare_string("DEX_FILE_MAGIC_035");
195
3
  declare_string("DEX_FILE_MAGIC_036");
196
3
  declare_string("DEX_FILE_MAGIC_037");
197
3
  declare_string("DEX_FILE_MAGIC_038");
198
3
  declare_string("DEX_FILE_MAGIC_039");
199
200
3
  declare_integer("ENDIAN_CONSTANT");
201
3
  declare_integer("REVERSE_ENDIAN_CONSTANT");
202
3
  declare_integer("NO_INDEX");
203
3
  declare_integer("ACC_PUBLIC");
204
3
  declare_integer("ACC_PRIVATE");
205
3
  declare_integer("ACC_PROTECTED");
206
3
  declare_integer("ACC_STATIC");
207
3
  declare_integer("ACC_FINAL");
208
3
  declare_integer("ACC_SYNCHRONIZED");
209
3
  declare_integer("ACC_VOLATILE");
210
3
  declare_integer("ACC_BRIDGE");
211
3
  declare_integer("ACC_TRANSIENT");
212
3
  declare_integer("ACC_VARARGS");
213
3
  declare_integer("ACC_NATIVE");
214
3
  declare_integer("ACC_INTERFACE");
215
3
  declare_integer("ACC_ABSTRACT");
216
3
  declare_integer("ACC_STRICT");
217
3
  declare_integer("ACC_SYNTHETIC");
218
3
  declare_integer("ACC_ANNOTATION");
219
3
  declare_integer("ACC_ENUM");
220
3
  declare_integer("ACC_CONSTRUCTOR");
221
3
  declare_integer("ACC_DECLARED_SYNCHRONIZED");
222
223
3
  declare_integer("TYPE_HEADER_ITEM");
224
3
  declare_integer("TYPE_STRING_ID_ITEM");
225
3
  declare_integer("TYPE_TYPE_ID_ITEM");
226
3
  declare_integer("TYPE_PROTO_ID_ITEM");
227
3
  declare_integer("TYPE_FIELD_ID_ITEM");
228
3
  declare_integer("TYPE_METHOD_ID_ITEM");
229
3
  declare_integer("TYPE_CLASS_DEF_ITEM");
230
3
  declare_integer("TYPE_CALL_SITE_ID_ITEM");
231
3
  declare_integer("TYPE_METHOD_HANDLE_ITEM");
232
3
  declare_integer("TYPE_MAP_LIST");
233
3
  declare_integer("TYPE_TYPE_LIST");
234
3
  declare_integer("TYPE_ANNOTATION_SET_REF_LIST");
235
3
  declare_integer("TYPE_ANNOTATION_SET_ITEM");
236
3
  declare_integer("TYPE_CLASS_DATA_ITEM");
237
3
  declare_integer("TYPE_CODE_ITEM");
238
3
  declare_integer("TYPE_STRING_DATA_ITEM");
239
3
  declare_integer("TYPE_DEBUG_INFO_ITEM");
240
3
  declare_integer("TYPE_ANNOTATION_ITEM");
241
3
  declare_integer("TYPE_ENCODED_ARRAY_ITEM");
242
3
  declare_integer("TYPE_ANNOTATIONS_DIRECTORY_ITEM");
243
244
6
  begin_struct("header")
245
3
    declare_string("magic");
246
3
    declare_integer("checksum");
247
3
    declare_string("signature");
248
3
    declare_integer("file_size");
249
3
    declare_integer("header_size");
250
3
    declare_integer("endian_tag");
251
3
    declare_integer("link_size");
252
3
    declare_integer("link_offset");
253
3
    declare_integer("map_offset");
254
3
    declare_integer("string_ids_size");
255
3
    declare_integer("string_ids_offset");
256
3
    declare_integer("type_ids_size");
257
3
    declare_integer("type_ids_offset");
258
3
    declare_integer("proto_ids_size");
259
3
    declare_integer("proto_ids_offset");
260
3
    declare_integer("field_ids_size");
261
3
    declare_integer("field_ids_offset");
262
3
    declare_integer("method_ids_size");
263
3
    declare_integer("method_ids_offset");
264
3
    declare_integer("class_defs_size");
265
3
    declare_integer("class_defs_offset");
266
3
    declare_integer("data_size");
267
3
    declare_integer("data_offset");
268
6
  end_struct("header")
269
270
9
  begin_struct_array("string_ids")
271
3
    declare_integer("offset");
272
3
    declare_integer("size");
273
3
    declare_string("value");
274
6
  end_struct_array("string_ids")
275
276
9
  begin_struct_array("type_ids")
277
3
    declare_integer("descriptor_idx");
278
6
  end_struct_array("type_ids")
279
280
9
  begin_struct_array("proto_ids")
281
3
    declare_integer("shorty_idx");
282
3
    declare_integer("return_type_idx");
283
3
    declare_integer("parameters_offset");
284
6
  end_struct_array("proto_ids")
285
286
9
  begin_struct_array("field_ids")
287
3
    declare_integer("class_idx");
288
3
    declare_integer("type_idx");
289
3
    declare_integer("name_idx");
290
6
  end_struct_array("field_ids")
291
292
9
  begin_struct_array("method_ids")
293
3
    declare_integer("class_idx");
294
3
    declare_integer("proto_idx");
295
3
    declare_integer("name_idx");
296
6
  end_struct_array("method_ids")
297
298
9
  begin_struct_array("class_defs")
299
3
    declare_integer("class_idx");
300
3
    declare_integer("access_flags");
301
3
    declare_integer("super_class_idx");
302
3
    declare_integer("interfaces_offset");
303
3
    declare_integer("source_file_idx");
304
3
    declare_integer("annotations_offset");
305
3
    declare_integer("class_data_offset");
306
3
    declare_integer("static_values_offset");
307
6
  end_struct_array("class_defs")
308
309
9
  begin_struct_array("class_data_item")
310
3
    declare_integer("static_fields_size");
311
3
    declare_integer("instance_fields_size");
312
3
    declare_integer("direct_methods_size");
313
3
    declare_integer("virtual_methods_size");
314
6
  end_struct_array("class_data_item")
315
316
6
  begin_struct("map_list")
317
3
    declare_integer("size");
318
9
    begin_struct_array("map_item")
319
3
      declare_integer("type");
320
3
      declare_integer("unused");
321
3
      declare_integer("size");
322
3
      declare_integer("offset");
323
6
    end_struct_array("map_item");
324
6
  end_struct("map_list")
325
326
3
  declare_integer("number_of_fields");
327
9
  begin_struct_array("field")
328
3
    declare_string("class_name");
329
3
    declare_string("name");
330
3
    declare_string("proto");
331
3
    declare_integer("static");
332
3
    declare_integer("instance");
333
3
    declare_integer("field_idx_diff");
334
3
    declare_integer("access_flags");
335
6
  end_struct_array("field")
336
337
3
  declare_function("has_method", "s", "i", has_method_string);
338
3
  declare_function("has_method", "ss", "i", has_method_and_class_string);
339
3
  declare_function("has_method", "r", "i", has_method_regexp);
340
3
  declare_function("has_method", "rr", "i", has_method_and_class_regexp);
341
3
  declare_function("has_class", "s", "i", has_class_string);
342
3
  declare_function("has_class", "r", "i", has_class_regexp);
343
344
3
  declare_integer("number_of_methods");
345
9
  begin_struct_array("method")
346
3
    declare_string("class_name");
347
3
    declare_string("name");
348
3
    declare_string("proto");
349
3
    declare_integer("direct");
350
3
    declare_integer("virtual");
351
3
    declare_integer("method_idx_diff");
352
3
    declare_integer("access_flags");
353
3
    declare_integer("code_off");
354
355
6
    begin_struct("code_item")
356
3
      declare_integer("registers_size");
357
3
      declare_integer("ins_size");
358
3
      declare_integer("outs_size");
359
3
      declare_integer("tries_size");
360
3
      declare_integer("debug_info_off");
361
3
      declare_integer("insns_size");
362
3
      declare_string("insns");
363
6
    end_struct("code_item")
364
6
  end_struct_array("method")
365
3
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
#ifdef DEBUG_DEX_MODULE
967
    printf(
968
        "[DEX] STRING ID item data_offset:0x%x\n",
969
        yr_le32toh(string_id_item->string_data_offset));
970
#endif
971
972
0
    if (!fits_in_dex(
973
0
            dex,
974
0
            dex->data + yr_le32toh(string_id_item->string_data_offset),
975
0
            sizeof(uint32_t)))
976
0
      continue;
977
978
0
    bool error = false;
979
0
    uint32_t value = (uint32_t) read_uleb128_bounded(
980
0
        (dex->data + yr_le32toh(string_id_item->string_data_offset)),
981
0
        data_end, &uleb128_size, &error);
982
0
    if (error)
983
0
      continue;
984
985
#ifdef DEBUG_DEX_MODULE
986
    printf("[DEX] STRING ID item size:0x%x\n", value);
987
#endif
988
989
0
    if (!fits_in_dex(
990
0
            dex,
991
0
            dex->data + yr_le32toh(string_id_item->string_data_offset) + 1,
992
0
            value))
993
0
      continue;
994
995
0
    yr_set_integer(
996
0
        yr_le32toh(string_id_item->string_data_offset),
997
0
        dex->object,
998
0
        "string_ids[%i].offset",
999
0
        i);
1000
1001
0
    yr_set_integer(value, dex->object, "string_ids[%i].size", i);
1002
1003
0
    yr_set_sized_string(
1004
0
        (const char*) (
1005
0
            dex->data + yr_le32toh(string_id_item->string_data_offset) + 1),
1006
0
        value,
1007
0
        dex->object,
1008
0
        "string_ids[%i].value",
1009
0
        i);
1010
0
  }
1011
1012
0
  if (!fits_in_dex(
1013
0
          dex,
1014
0
          dex->data + yr_le32toh(dex_header->type_ids_offset),
1015
0
          yr_le32toh(dex_header->type_ids_size) * sizeof(type_id_item_t)))
1016
0
    return;
1017
1018
#ifdef DEBUG_DEX_MODULE
1019
  printf("[DEX] Parse TYPE ID section\n");
1020
#endif
1021
1022
  // Get information about the Type ID section
1023
0
  for (i = 0; i < yr_le32toh(dex_header->type_ids_size); i++)
1024
0
  {
1025
0
    type_id_item_t* type_id_item =
1026
0
        (type_id_item_t*) (dex->data + yr_le32toh(dex_header->type_ids_offset) + i * sizeof(type_id_item_t));
1027
1028
0
    yr_set_integer(
1029
0
        yr_le32toh(type_id_item->descriptor_idx),
1030
0
        dex->object,
1031
0
        "type_ids[%i].descriptor_idx",
1032
0
        i);
1033
0
  }
1034
1035
0
  if (!fits_in_dex(
1036
0
          dex,
1037
0
          dex->data + yr_le32toh(dex_header->proto_ids_offset),
1038
0
          yr_le32toh(dex_header->proto_ids_size) * sizeof(proto_id_item_t)))
1039
0
    return;
1040
1041
#ifdef DEBUG_DEX_MODULE
1042
  printf("[DEX] Parse PROTO ID section\n");
1043
#endif
1044
1045
  // Get information about the Proto ID section
1046
0
  for (i = 0; i < yr_le32toh(dex_header->proto_ids_size); i++)
1047
0
  {
1048
0
    proto_id_item_t* proto_id_item =
1049
0
        (proto_id_item_t*) (dex->data + yr_le32toh(dex_header->proto_ids_offset) + i * sizeof(proto_id_item_t));
1050
1051
0
    yr_set_integer(
1052
0
        yr_le32toh(proto_id_item->shorty_idx),
1053
0
        dex->object,
1054
0
        "proto_ids[%i].shorty_idx",
1055
0
        i);
1056
0
    yr_set_integer(
1057
0
        yr_le32toh(proto_id_item->return_type_idx),
1058
0
        dex->object,
1059
0
        "proto_ids[%i].return_type_idx",
1060
0
        i);
1061
0
    yr_set_integer(
1062
0
        yr_le32toh(proto_id_item->parameters_offset),
1063
0
        dex->object,
1064
0
        "proto_ids[%i].parameters_offset",
1065
0
        i);
1066
0
  }
1067
1068
0
  if (!fits_in_dex(
1069
0
          dex,
1070
0
          dex->data + yr_le32toh(dex_header->field_ids_offset),
1071
0
          yr_le32toh(dex_header->field_ids_size) * sizeof(field_id_item_t)))
1072
0
    return;
1073
1074
#ifdef DEBUG_DEX_MODULE
1075
  printf("[DEX] Parse FIELD ID section\n");
1076
#endif
1077
1078
  // Get information about the Field ID section
1079
0
  for (i = 0; i < yr_le32toh(dex_header->field_ids_size); i++)
1080
0
  {
1081
0
    field_id_item_t* field_id_item =
1082
0
        (field_id_item_t*) (dex->data + yr_le32toh(dex_header->field_ids_offset) + i * sizeof(field_id_item_t));
1083
1084
0
    yr_set_integer(
1085
0
        yr_le16toh(field_id_item->class_idx),
1086
0
        dex->object,
1087
0
        "field_ids[%i].class_idx",
1088
0
        i);
1089
0
    yr_set_integer(
1090
0
        yr_le16toh(field_id_item->type_idx),
1091
0
        dex->object,
1092
0
        "field_ids[%i].type_idx",
1093
0
        i);
1094
0
    yr_set_integer(
1095
0
        yr_le32toh(field_id_item->name_idx),
1096
0
        dex->object,
1097
0
        "field_ids[%i].name_idx",
1098
0
        i);
1099
0
  }
1100
1101
0
  if (!fits_in_dex(
1102
0
          dex,
1103
0
          dex->data + yr_le32toh(dex_header->method_ids_offset),
1104
0
          yr_le32toh(dex_header->method_ids_size) * sizeof(method_id_item_t)))
1105
0
    return;
1106
1107
#ifdef DEBUG_DEX_MODULE
1108
  printf("[DEX] Parse METHOD ID section\n");
1109
#endif
1110
1111
  // Get information about the Method ID section
1112
0
  for (i = 0; i < yr_le32toh(dex_header->method_ids_size); i++)
1113
0
  {
1114
0
    method_id_item_t* method_id_item =
1115
0
        (method_id_item_t*) (dex->data + yr_le32toh(dex_header->method_ids_offset) + i * sizeof(method_id_item_t));
1116
1117
0
    yr_set_integer(
1118
0
        yr_le16toh(method_id_item->class_idx),
1119
0
        dex->object,
1120
0
        "method_ids[%i].class_idx",
1121
0
        i);
1122
0
    yr_set_integer(
1123
0
        yr_le16toh(method_id_item->proto_idx),
1124
0
        dex->object,
1125
0
        "method_ids[%i].proto_idx",
1126
0
        i);
1127
0
    yr_set_integer(
1128
0
        yr_le32toh(method_id_item->name_idx),
1129
0
        dex->object,
1130
0
        "method_ids[%i].name_idx",
1131
0
        i);
1132
0
  }
1133
1134
#ifdef DEBUG_DEX_MODULE
1135
  printf("[DEX] Parse MAP List ID section\n");
1136
#endif
1137
1138
  // Get information about the Map List ID section
1139
0
  if (yr_le32toh(dex_header->map_offset) != 0 &&
1140
0
      fits_in_dex(
1141
0
          dex,
1142
0
          dex->data + yr_le32toh(dex_header->map_offset),
1143
0
          sizeof(uint32_t)))
1144
0
  {
1145
0
    uint32_t* map_list_size =
1146
0
        (uint32_t*) (dex->data + yr_le32toh(dex_header->map_offset));
1147
1148
0
    yr_set_integer(yr_le32toh(*map_list_size), dex->object, "map_list.size");
1149
1150
0
    if (!fits_in_dex(
1151
0
            dex,
1152
0
            dex->data + yr_le32toh(dex_header->map_offset),
1153
0
            sizeof(uint32_t) + yr_le32toh(*map_list_size) * sizeof(map_item_t)))
1154
0
      return;
1155
1156
0
    for (i = 0; i < yr_le32toh(*map_list_size); i++)
1157
0
    {
1158
0
      map_item_t* map_item =
1159
0
          (map_item_t*) (dex->data + yr_le32toh(dex_header->map_offset) + sizeof(uint32_t) + i * sizeof(map_item_t));
1160
1161
0
      if (!struct_fits_in_dex(dex, map_item, map_item_t))
1162
0
        return;
1163
1164
0
      yr_set_integer(
1165
0
          yr_le16toh(map_item->type),
1166
0
          dex->object,
1167
0
          "map_list.map_item[%i].type",
1168
0
          i);
1169
0
      yr_set_integer(
1170
0
          yr_le16toh(map_item->unused),
1171
0
          dex->object,
1172
0
          "map_list.map_item[%i].unused",
1173
0
          i);
1174
0
      yr_set_integer(
1175
0
          yr_le32toh(map_item->size),
1176
0
          dex->object,
1177
0
          "map_list.map_item[%i].size",
1178
0
          i);
1179
0
      yr_set_integer(
1180
0
          yr_le32toh(map_item->offset),
1181
0
          dex->object,
1182
0
          "map_list.map_item[%i].offset",
1183
0
          i);
1184
0
    }
1185
0
  }
1186
1187
0
  if (!fits_in_dex(
1188
0
          dex,
1189
0
          dex->data + yr_le32toh(dex_header->class_defs_offset),
1190
0
          yr_le32toh(dex_header->class_defs_size) * sizeof(class_id_item_t)))
1191
0
    return;
1192
1193
#ifdef DEBUG_DEX_MODULE
1194
  printf("[DEX] Parse CLASS ID section\n");
1195
#endif
1196
1197
  // Get information about the Class ID section
1198
0
  for (i = 0; i < yr_le32toh(dex_header->class_defs_size); i++)
1199
0
  {
1200
0
    class_id_item_t* class_id_item =
1201
0
        (class_id_item_t*) (dex->data + yr_le32toh(dex_header->class_defs_offset) + i * sizeof(class_id_item_t));
1202
1203
#ifdef DEBUG_DEX_MODULE
1204
    printf(
1205
        "[DEX] CLASS ID item class_idx:0x%x access_flags:0x%x "
1206
        "super_class_idx:0x%x interfaces_offset:0x%x source_file_idx:0x%x "
1207
        "annotations_offset:0x%x class_data_offset:0x%x "
1208
        "static_values_offset:0x%x\n",
1209
        yr_le32toh(class_id_item->class_idx),
1210
        yr_le32toh(class_id_item->access_flags),
1211
        yr_le32toh(class_id_item->super_class_idx),
1212
        yr_le32toh(class_id_item->interfaces_offset),
1213
        yr_le32toh(class_id_item->source_file_idx),
1214
        yr_le32toh(class_id_item->annotations_offset),
1215
        yr_le32toh(class_id_item->class_data_offset),
1216
        yr_le32toh(class_id_item->static_values_offset));
1217
#endif
1218
1219
0
    yr_set_integer(
1220
0
        yr_le32toh(class_id_item->class_idx),
1221
0
        dex->object,
1222
0
        "class_defs[%i].class_idx",
1223
0
        i);
1224
0
    yr_set_integer(
1225
0
        yr_le32toh(class_id_item->access_flags),
1226
0
        dex->object,
1227
0
        "class_defs[%i].access_flags",
1228
0
        i);
1229
0
    yr_set_integer(
1230
0
        yr_le32toh(class_id_item->super_class_idx),
1231
0
        dex->object,
1232
0
        "class_defs[%i].super_class_idx",
1233
0
        i);
1234
0
    yr_set_integer(
1235
0
        yr_le32toh(class_id_item->interfaces_offset),
1236
0
        dex->object,
1237
0
        "class_defs[%i].interfaces_offset",
1238
0
        i);
1239
0
    yr_set_integer(
1240
0
        yr_le32toh(class_id_item->source_file_idx),
1241
0
        dex->object,
1242
0
        "class_defs[%i].source_file_idx",
1243
0
        i);
1244
0
    yr_set_integer(
1245
0
        yr_le32toh(class_id_item->annotations_offset),
1246
0
        dex->object,
1247
0
        "class_defs[%i].annotations_offset",
1248
0
        i);
1249
0
    yr_set_integer(
1250
0
        yr_le32toh(class_id_item->class_data_offset),
1251
0
        dex->object,
1252
0
        "class_defs[%i].class_data_offset",
1253
0
        i);
1254
0
    yr_set_integer(
1255
0
        yr_le32toh(class_id_item->static_values_offset),
1256
0
        dex->object,
1257
0
        "class_defs[%i].static_values_offset",
1258
0
        i);
1259
1260
0
    if (yr_le32toh(class_id_item->class_data_offset) != 0)
1261
0
    {
1262
0
      class_data_item_t class_data_item;
1263
1264
0
      if (!fits_in_dex(
1265
0
              dex,
1266
0
              dex->data + yr_le32toh(class_id_item->class_data_offset),
1267
0
              4 * sizeof(uint32_t)))
1268
0
        return;
1269
1270
0
      uleb128_size = 0;
1271
0
      bool error = false;
1272
1273
0
      class_data_item.static_fields_size = (uint32_t) read_uleb128_bounded(
1274
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset)),
1275
0
          data_end, &uleb128_size, &error);
1276
0
      if (error)
1277
0
        return;
1278
1279
0
      class_data_item.instance_fields_size = (uint32_t) read_uleb128_bounded(
1280
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1281
0
           uleb128_size),
1282
0
          data_end, &uleb128_size, &error);
1283
0
      if (error)
1284
0
        return;
1285
1286
0
      class_data_item.direct_methods_size = (uint32_t) read_uleb128_bounded(
1287
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1288
0
           uleb128_size),
1289
0
          data_end, &uleb128_size, &error);
1290
0
      if (error)
1291
0
        return;
1292
1293
0
      class_data_item.virtual_methods_size = (uint32_t) read_uleb128_bounded(
1294
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1295
0
           uleb128_size),
1296
0
          data_end, &uleb128_size, &error);
1297
0
      if (error)
1298
0
        return;
1299
1300
0
      yr_set_integer(
1301
0
          class_data_item.static_fields_size,
1302
0
          dex->object,
1303
0
          "class_data_item[%i].static_fields_size",
1304
0
          index_class_data_item);
1305
1306
0
      yr_set_integer(
1307
0
          class_data_item.instance_fields_size,
1308
0
          dex->object,
1309
0
          "class_data_item[%i].instance_fields_size",
1310
0
          index_class_data_item);
1311
1312
0
      yr_set_integer(
1313
0
          class_data_item.direct_methods_size,
1314
0
          dex->object,
1315
0
          "class_data_item[%i].direct_methods_size",
1316
0
          index_class_data_item);
1317
1318
0
      yr_set_integer(
1319
0
          class_data_item.virtual_methods_size,
1320
0
          dex->object,
1321
0
          "class_data_item[%i].virtual_methods_size",
1322
0
          index_class_data_item);
1323
1324
#ifdef DEBUG_DEX_MODULE
1325
      printf("[DEX] CLASS DATA item static fields\n");
1326
#endif
1327
1328
0
      uint32_t previous_field_idx = 0;
1329
0
      for (j = 0; j < class_data_item.static_fields_size; j++)
1330
0
      {
1331
0
        new_size = load_encoded_field(
1332
0
            dex,
1333
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1334
0
            &previous_field_idx,
1335
0
            index_encoded_field,
1336
0
            1,
1337
0
            0);
1338
1339
        // If the current field isn't parsed the other fields aren't likely to
1340
        // parse.
1341
0
        if (new_size == 0)
1342
0
          break;
1343
1344
0
        uleb128_size += new_size;
1345
0
        index_encoded_field += 1;
1346
0
      }
1347
1348
#ifdef DEBUG_DEX_MODULE
1349
      printf("[DEX] CLASS DATA item instance fields\n");
1350
#endif
1351
1352
0
      previous_field_idx = 0;
1353
1354
0
      for (j = 0; j < class_data_item.instance_fields_size; j++)
1355
0
      {
1356
0
        new_size = load_encoded_field(
1357
0
            dex,
1358
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1359
0
            &previous_field_idx,
1360
0
            index_encoded_field,
1361
0
            0,
1362
0
            1);
1363
1364
        // If the current field isn't parsed the other fields aren't likely to
1365
        // parse.
1366
0
        if (new_size == 0)
1367
0
          break;
1368
1369
0
        uleb128_size += new_size;
1370
0
        index_encoded_field += 1;
1371
0
      }
1372
1373
#ifdef DEBUG_DEX_MODULE
1374
      printf("[DEX] CLASS DATA item direct methods\n");
1375
#endif
1376
1377
0
      uint32_t previous_method_idx = 0;
1378
1379
0
      for (j = 0; j < class_data_item.direct_methods_size; j++)
1380
0
      {
1381
0
        new_size = load_encoded_method(
1382
0
            dex,
1383
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1384
0
            &previous_method_idx,
1385
0
            index_encoded_method,
1386
0
            1,
1387
0
            0);
1388
1389
        // If the current field isn't parsed the other fields aren't likely to
1390
        // parse.
1391
0
        if (new_size == 0)
1392
0
          break;
1393
1394
0
        uleb128_size += new_size;
1395
0
        index_encoded_method += 1;
1396
0
      }
1397
1398
#ifdef DEBUG_DEX_MODULE
1399
      printf("[DEX] CLASS DATA item virtual methods\n");
1400
#endif
1401
1402
0
      previous_method_idx = 0;
1403
1404
0
      for (j = 0; j < class_data_item.virtual_methods_size; j++)
1405
0
      {
1406
0
        new_size = load_encoded_method(
1407
0
            dex,
1408
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1409
0
            &previous_method_idx,
1410
0
            index_encoded_method,
1411
0
            0,
1412
0
            1);
1413
1414
        // If the current field isn't parsed the other fields aren't likely to
1415
        // parse.
1416
0
        if (new_size == 0)
1417
0
          break;
1418
1419
0
        uleb128_size += new_size;
1420
0
        index_encoded_method += 1;
1421
0
      }
1422
1423
0
      index_class_data_item++;
1424
0
    }
1425
0
  }
1426
1427
0
  yr_set_integer(index_encoded_method, dex->object, "number_of_methods");
1428
0
  yr_set_integer(index_encoded_field, dex->object, "number_of_fields");
1429
0
}
1430
1431
1432
int module_initialize(YR_MODULE* module)
1433
11
{
1434
11
  return ERROR_SUCCESS;
1435
11
}
1436
1437
1438
int module_finalize(YR_MODULE* module)
1439
0
{
1440
0
  return ERROR_SUCCESS;
1441
0
}
1442
1443
1444
int module_load(
1445
    YR_SCAN_CONTEXT* context,
1446
    YR_OBJECT* module_object,
1447
    void* module_data,
1448
    size_t module_data_size)
1449
0
{
1450
0
  YR_MEMORY_BLOCK* block;
1451
0
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1452
1453
0
  dex_header_t* dex_header;
1454
1455
0
  yr_set_sized_string(
1456
0
      DEX_FILE_MAGIC_035, 8, module_object, "DEX_FILE_MAGIC_035");
1457
0
  yr_set_sized_string(
1458
0
      DEX_FILE_MAGIC_036, 8, module_object, "DEX_FILE_MAGIC_036");
1459
0
  yr_set_sized_string(
1460
0
      DEX_FILE_MAGIC_037, 8, module_object, "DEX_FILE_MAGIC_037");
1461
0
  yr_set_sized_string(
1462
0
      DEX_FILE_MAGIC_038, 8, module_object, "DEX_FILE_MAGIC_038");
1463
0
  yr_set_sized_string(
1464
0
      DEX_FILE_MAGIC_039, 8, module_object, "DEX_FILE_MAGIC_039");
1465
1466
0
  yr_set_integer(0x12345678, module_object, "ENDIAN_CONSTANT");
1467
0
  yr_set_integer(0x78563412, module_object, "REVERSE_ENDIAN_CONSTANT");
1468
1469
0
  yr_set_integer(0xffffffff, module_object, "NO_INDEX");
1470
0
  yr_set_integer(0x1, module_object, "ACC_PUBLIC");
1471
0
  yr_set_integer(0x2, module_object, "ACC_PRIVATE");
1472
0
  yr_set_integer(0x4, module_object, "ACC_PROTECTED");
1473
0
  yr_set_integer(0x8, module_object, "ACC_STATIC");
1474
0
  yr_set_integer(0x10, module_object, "ACC_FINAL");
1475
0
  yr_set_integer(0x20, module_object, "ACC_SYNCHRONIZED");
1476
0
  yr_set_integer(0x40, module_object, "ACC_VOLATILE");
1477
0
  yr_set_integer(0x40, module_object, "ACC_BRIDGE");
1478
0
  yr_set_integer(0x80, module_object, "ACC_TRANSIENT");
1479
0
  yr_set_integer(0x80, module_object, "ACC_VARARGS");
1480
0
  yr_set_integer(0x100, module_object, "ACC_NATIVE");
1481
0
  yr_set_integer(0x200, module_object, "ACC_INTERFACE");
1482
0
  yr_set_integer(0x400, module_object, "ACC_ABSTRACT");
1483
0
  yr_set_integer(0x800, module_object, "ACC_STRICT");
1484
0
  yr_set_integer(0x1000, module_object, "ACC_SYNTHETIC");
1485
0
  yr_set_integer(0x2000, module_object, "ACC_ANNOTATION");
1486
0
  yr_set_integer(0x4000, module_object, "ACC_ENUM");
1487
0
  yr_set_integer(0x10000, module_object, "ACC_CONSTRUCTOR");
1488
0
  yr_set_integer(0x20000, module_object, "ACC_DECLARED_SYNCHRONIZED");
1489
1490
0
  yr_set_integer(0x0000, module_object, "TYPE_HEADER_ITEM");
1491
0
  yr_set_integer(0x0001, module_object, "TYPE_STRING_ID_ITEM");
1492
0
  yr_set_integer(0x0002, module_object, "TYPE_TYPE_ID_ITEM");
1493
0
  yr_set_integer(0x0003, module_object, "TYPE_PROTO_ID_ITEM");
1494
0
  yr_set_integer(0x0004, module_object, "TYPE_FIELD_ID_ITEM");
1495
0
  yr_set_integer(0x0005, module_object, "TYPE_METHOD_ID_ITEM");
1496
0
  yr_set_integer(0x0006, module_object, "TYPE_CLASS_DEF_ITEM");
1497
0
  yr_set_integer(0x0007, module_object, "TYPE_CALL_SITE_ID_ITEM");
1498
0
  yr_set_integer(0x0008, module_object, "TYPE_METHOD_HANDLE_ITEM");
1499
0
  yr_set_integer(0x1000, module_object, "TYPE_MAP_LIST");
1500
0
  yr_set_integer(0x1001, module_object, "TYPE_TYPE_LIST");
1501
0
  yr_set_integer(0x1002, module_object, "TYPE_ANNOTATION_SET_REF_LIST");
1502
0
  yr_set_integer(0x1003, module_object, "TYPE_ANNOTATION_SET_ITEM");
1503
0
  yr_set_integer(0x2000, module_object, "TYPE_CLASS_DATA_ITEM");
1504
0
  yr_set_integer(0x2001, module_object, "TYPE_CODE_ITEM");
1505
0
  yr_set_integer(0x2002, module_object, "TYPE_STRING_DATA_ITEM");
1506
0
  yr_set_integer(0x2003, module_object, "TYPE_DEBUG_INFO_ITEM");
1507
0
  yr_set_integer(0x2004, module_object, "TYPE_ANNOTATION_ITEM");
1508
0
  yr_set_integer(0x2005, module_object, "TYPE_ENCODED_ARRAY_ITEM");
1509
0
  yr_set_integer(0x2006, module_object, "TYPE_ANNOTATIONS_DIRECTORY_ITEM");
1510
1511
0
  foreach_memory_block(iterator, block)
1512
0
  {
1513
0
    const uint8_t* block_data = yr_fetch_block_data(block);
1514
1515
0
    if (block_data == NULL)
1516
0
      continue;
1517
1518
0
    dex_header = dex_get_header(block_data, block->size);
1519
1520
0
    if (dex_header != NULL)
1521
0
    {
1522
0
      DEX* dex = (DEX*) yr_malloc(sizeof(DEX));
1523
1524
0
      if (dex == NULL)
1525
0
        return ERROR_INSUFFICIENT_MEMORY;
1526
1527
0
      dex->data = block_data;
1528
0
      dex->data_size = block->size;
1529
0
      dex->object = module_object;
1530
0
      dex->header = dex_header;
1531
1532
0
      module_object->data = dex;
1533
1534
0
      dex_parse(dex, block->base);
1535
0
      break;
1536
0
    }
1537
0
  }
1538
1539
0
  return ERROR_SUCCESS;
1540
0
}
1541
1542
1543
int module_unload(YR_OBJECT* module_object)
1544
0
{
1545
0
  DEX* dex = (DEX*) module_object->data;
1546
1547
0
  if (dex == NULL)
1548
0
    return ERROR_SUCCESS;
1549
1550
0
  yr_free(dex);
1551
1552
0
  return ERROR_SUCCESS;
1553
0
}
1554
1555
#undef MODULE_NAME