Coverage Report

Created: 2023-06-07 07:18

/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
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("field_idx_diff");
332
0
    declare_integer("access_flags");
333
0
  end_struct_array("field")
334
335
0
  declare_function("has_method", "s", "i", has_method_string);
336
0
  declare_function("has_method", "ss", "i", has_method_and_class_string);
337
0
  declare_function("has_method", "r", "i", has_method_regexp);
338
0
  declare_function("has_method", "rr", "i", has_method_and_class_regexp);
339
0
  declare_function("has_class", "s", "i", has_class_string);
340
0
  declare_function("has_class", "r", "i", has_class_regexp);
341
342
0
  declare_integer("number_of_methods");
343
0
  begin_struct_array("method")
344
0
    declare_string("class_name");
345
0
    declare_string("name");
346
0
    declare_string("proto");
347
0
    declare_integer("direct");
348
0
    declare_integer("virtual");
349
0
    declare_integer("method_idx_diff");
350
0
    declare_integer("access_flags");
351
0
    declare_integer("code_off");
352
353
0
    begin_struct("code_item")
354
0
      declare_integer("registers_size");
355
0
      declare_integer("ins_size");
356
0
      declare_integer("outs_size");
357
0
      declare_integer("tries_size");
358
0
      declare_integer("debug_info_off");
359
0
      declare_integer("insns_size");
360
0
      declare_string("insns");
361
0
      declare_integer("padding");
362
0
      begin_struct("tries")
363
0
      end_struct("tries");
364
0
      begin_struct_array("handlers")
365
0
      end_struct_array("handlers");
366
0
    end_struct("code_item")
367
0
  end_struct_array("method")
368
0
end_declarations
369
370
// https://android.googlesource.com/platform/dalvik/+/android-4.4.2_r2/libdex/Leb128.cpp
371
372
static int32_t read_uleb128(const uint8_t* pStream, uint32_t* size)
373
0
{
374
0
  const uint8_t* ptr = pStream;
375
376
0
  int32_t result = *(ptr++);
377
0
  *size = *size + 1;
378
379
0
  if (result > 0x7f)
380
0
  {
381
0
    int cur = *(ptr++);
382
0
    *size = *size + 1;
383
0
    result = (result & 0x7f) | ((cur & 0x7f) << 7);
384
385
0
    if (cur > 0x7f)
386
0
    {
387
0
      cur = *(ptr++);
388
0
      *size = *size + 1;
389
0
      result |= (cur & 0x7f) << 14;
390
391
0
      if (cur > 0x7f)
392
0
      {
393
0
        cur = *(ptr++);
394
0
        *size = *size + 1;
395
0
        result |= (cur & 0x7f) << 21;
396
397
0
        if (cur > 0x7f)
398
0
        {
399
          /*
400
           * Note: We don't check to see if cur is out of
401
           * range here, meaning we tolerate garbage in the
402
           * high four-order bits.
403
           */
404
0
          cur = *(ptr++);
405
0
          *size = *size + 1;
406
0
          result |= cur << 28;
407
0
        }
408
0
      }
409
0
    }
410
0
  }
411
412
0
  return result;
413
0
}
414
415
416
static int64_t dex_get_integer(
417
    YR_OBJECT* object,
418
    const char* pattern,
419
    int64_t index)
420
0
{
421
0
  if (index == YR_UNDEFINED || index < 0)
422
0
    return YR_UNDEFINED;
423
424
  // Impose a reasonably large limit to table indexes.
425
0
  if (index > 0x80000)
426
0
    return YR_UNDEFINED;
427
428
0
  return yr_get_integer(object, pattern, (int) index);
429
0
}
430
431
432
static SIZED_STRING* dex_get_string(
433
    YR_OBJECT* object,
434
    const char* pattern,
435
    int64_t index)
436
0
{
437
0
  if (index == YR_UNDEFINED || index < 0)
438
0
    return NULL;
439
440
  // Impose a reasonably large limit to table indexes.
441
0
  if (index > 0x80000)
442
0
    return NULL;
443
444
0
  return yr_get_string(object, pattern, (int) index);
445
0
}
446
447
448
dex_header_t* dex_get_header(const uint8_t* data, size_t data_size)
449
0
{
450
0
  dex_header_t* dex_header;
451
452
0
  if (data_size < sizeof(dex_header_t))
453
0
    return NULL;
454
455
  // Check if we have a valid DEX file
456
0
  dex_header = (dex_header_t*) data;
457
458
0
  if (memcmp(dex_header->magic, DEX_FILE_MAGIC_035, 8) != 0 &&
459
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_036, 8) != 0 &&
460
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_037, 8) != 0 &&
461
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_038, 8) != 0 &&
462
0
      memcmp(dex_header->magic, DEX_FILE_MAGIC_039, 8) != 0)
463
0
  {
464
0
    return NULL;
465
0
  }
466
467
0
  return dex_header;
468
0
}
469
470
471
void dex_parse_header(dex_header_t* dex_header, YR_OBJECT* module_object)
472
0
{
473
0
  yr_set_sized_string(
474
0
      (char*) dex_header->magic,
475
0
      strnlen((char*) dex_header->magic, 8 * sizeof(char)),
476
0
      module_object,
477
0
      "header.magic");
478
479
0
  yr_set_integer(
480
0
      yr_le32toh(dex_header->checksum), module_object, "header.checksum");
481
482
0
  yr_set_sized_string(
483
0
      (char*) dex_header->signature,
484
0
      strnlen((char*) dex_header->signature, 20 * sizeof(char)),
485
0
      module_object,
486
0
      "header.signature");
487
488
0
  yr_set_integer(
489
0
      yr_le32toh(dex_header->file_size), module_object, "header.file_size");
490
0
  yr_set_integer(
491
0
      yr_le32toh(dex_header->header_size), module_object, "header.header_size");
492
0
  yr_set_integer(
493
0
      yr_le32toh(dex_header->endian_tag), module_object, "header.endian_tag");
494
0
  yr_set_integer(
495
0
      yr_le32toh(dex_header->link_size), module_object, "header.link_size");
496
0
  yr_set_integer(
497
0
      yr_le32toh(dex_header->link_offset), module_object, "header.link_offset");
498
0
  yr_set_integer(
499
0
      yr_le32toh(dex_header->map_offset), module_object, "header.map_offset");
500
0
  yr_set_integer(
501
0
      yr_le32toh(dex_header->string_ids_size),
502
0
      module_object,
503
0
      "header.string_ids_size");
504
0
  yr_set_integer(
505
0
      yr_le32toh(dex_header->string_ids_offset),
506
0
      module_object,
507
0
      "header.string_ids_offset");
508
0
  yr_set_integer(
509
0
      yr_le32toh(dex_header->type_ids_size),
510
0
      module_object,
511
0
      "header.type_ids_size");
512
0
  yr_set_integer(
513
0
      yr_le32toh(dex_header->type_ids_offset),
514
0
      module_object,
515
0
      "header.type_ids_offset");
516
0
  yr_set_integer(
517
0
      yr_le32toh(dex_header->proto_ids_size),
518
0
      module_object,
519
0
      "header.proto_ids_size");
520
0
  yr_set_integer(
521
0
      yr_le32toh(dex_header->proto_ids_offset),
522
0
      module_object,
523
0
      "header.proto_ids_offset");
524
0
  yr_set_integer(
525
0
      yr_le32toh(dex_header->field_ids_size),
526
0
      module_object,
527
0
      "header.field_ids_size");
528
0
  yr_set_integer(
529
0
      yr_le32toh(dex_header->field_ids_offset),
530
0
      module_object,
531
0
      "header.field_ids_offset");
532
0
  yr_set_integer(
533
0
      yr_le32toh(dex_header->method_ids_size),
534
0
      module_object,
535
0
      "header.method_ids_size");
536
0
  yr_set_integer(
537
0
      yr_le32toh(dex_header->method_ids_offset),
538
0
      module_object,
539
0
      "header.method_ids_offset");
540
0
  yr_set_integer(
541
0
      yr_le32toh(dex_header->class_defs_size),
542
0
      module_object,
543
0
      "header.class_defs_size");
544
0
  yr_set_integer(
545
0
      yr_le32toh(dex_header->class_defs_offset),
546
0
      module_object,
547
0
      "header.class_defs_offset");
548
0
  yr_set_integer(
549
0
      yr_le32toh(dex_header->data_size), module_object, "header.data_size");
550
0
  yr_set_integer(
551
0
      yr_le32toh(dex_header->data_offset), module_object, "header.data_offset");
552
0
}
553
554
555
uint32_t load_encoded_field(
556
    DEX* dex,
557
    size_t start_offset,
558
    uint32_t* previous_field_idx,
559
    int index_encoded_field,
560
    int static_field,
561
    int instance_field)
562
0
{
563
#ifdef DEBUG_DEX_MODULE
564
  printf("[DEX] Parse encoded field start_offset:0x%zx\n", start_offset);
565
#endif
566
567
0
  if (!fits_in_dex(dex, dex->data + start_offset, sizeof(uint32_t) * 2))
568
0
    return 0;
569
570
0
  uint32_t current_size = 0;
571
572
0
  encoded_field_t encoded_field;
573
574
0
  encoded_field.field_idx_diff = (uint32_t) read_uleb128(
575
0
      (dex->data + start_offset + current_size), &current_size);
576
577
0
  encoded_field.access_flags = (uint32_t) read_uleb128(
578
0
      (dex->data + start_offset + current_size), &current_size);
579
580
0
  yr_set_integer(
581
0
      encoded_field.field_idx_diff,
582
0
      dex->object,
583
0
      "field[%i].field_idx_diff",
584
0
      index_encoded_field);
585
586
0
  yr_set_integer(
587
0
      encoded_field.access_flags,
588
0
      dex->object,
589
0
      "field[%i].access_flags",
590
0
      index_encoded_field);
591
592
0
  yr_set_integer(
593
0
      static_field, dex->object, "field[%i].static", index_encoded_field);
594
595
0
  yr_set_integer(
596
0
      instance_field, dex->object, "field[%i].instance", index_encoded_field);
597
598
0
  *previous_field_idx = encoded_field.field_idx_diff + *previous_field_idx;
599
600
#ifdef DEBUG_DEX_MODULE
601
  printf(
602
      "[DEX]\tEncoded field field_idx:0x%x field_idx_diff:0x%x "
603
      "access_flags:0x%x\n",
604
      *previous_field_idx,
605
      encoded_field.field_idx_diff,
606
      encoded_field.access_flags);
607
#endif
608
609
0
  int64_t name_idx = dex_get_integer(
610
0
      dex->object, "field_ids[%i].name_idx", *previous_field_idx);
611
612
0
  if (name_idx == YR_UNDEFINED)
613
0
    return 0;
614
615
0
  SIZED_STRING* field_name = dex_get_string(
616
0
      dex->object, "string_ids[%i].value", name_idx);
617
618
0
  if (field_name != NULL)
619
0
  {
620
#ifdef DEBUG_DEX_MODULE
621
    printf(
622
        "[DEX]\tFIELD_NAME %s NAME_IDX 0x%llx\n", field_name->c_string, name_idx);
623
#endif
624
625
0
    yr_set_sized_string(
626
0
        field_name->c_string,
627
0
        field_name->length,
628
0
        dex->object,
629
0
        "field[%i].name",
630
0
        index_encoded_field);
631
0
  }
632
633
0
  int64_t class_idx = dex_get_integer(
634
0
      dex->object, "field_ids[%i].class_idx", *previous_field_idx);
635
636
0
  int64_t descriptor_idx = dex_get_integer(
637
0
      dex->object, "type_ids[%i].descriptor_idx", class_idx);
638
639
0
  SIZED_STRING* class_name = dex_get_string(
640
0
      dex->object, "string_ids[%i].value", descriptor_idx);
641
642
0
  if (class_name != NULL)
643
0
  {
644
#ifdef DEBUG_DEX_MODULE
645
    printf(
646
        "[DEX]\tCLASS_NAME %s CLASS_IDX 0x%llx DESCRIPTOR_IDX 0x%llx\n",
647
        class_name->c_string,
648
        class_idx,
649
        descriptor_idx);
650
#endif
651
652
0
    yr_set_sized_string(
653
0
        class_name->c_string,
654
0
        class_name->length,
655
0
        dex->object,
656
0
        "field[%i].class_name",
657
0
        index_encoded_field);
658
0
  }
659
660
0
  int type_idx = dex_get_integer(
661
0
      dex->object, "field_ids[%i].type_idx", *previous_field_idx);
662
663
0
  int shorty_idx = dex_get_integer(
664
0
      dex->object, "type_ids[%i].descriptor_idx", type_idx);
665
666
0
  SIZED_STRING* proto_name = dex_get_string(
667
0
      dex->object, "string_ids[%i].value", shorty_idx);
668
669
0
  if (proto_name != NULL)
670
0
  {
671
#ifdef DEBUG_DEX_MODULE
672
    printf(
673
        "[DEX]\tPROTO_NAME %s TYPE_IDX 0x%x SHORTY_IDX 0x%x\n",
674
        proto_name->c_string,
675
        type_idx,
676
        shorty_idx);
677
#endif
678
679
0
    yr_set_sized_string(
680
0
        proto_name->c_string,
681
0
        proto_name->length,
682
0
        dex->object,
683
0
        "field[%i].proto",
684
0
        index_encoded_field);
685
0
  }
686
687
0
  return current_size;
688
0
}
689
690
691
uint32_t load_encoded_method(
692
    DEX* dex,
693
    size_t start_offset,
694
    uint32_t* previous_method_idx,
695
    int index_encoded_method,
696
    int direct_method,
697
    int virtual_method)
698
0
{
699
#ifdef DEBUG_DEX_MODULE
700
  printf("[DEX] Parse encoded method start_offset:0x%zx\n", start_offset);
701
#endif
702
703
0
  if (!fits_in_dex(dex, dex->data + start_offset, sizeof(uint32_t) * 3))
704
0
    return 0;
705
706
0
  uint32_t current_size = 0;
707
0
  encoded_method_t encoded_method;
708
709
0
  encoded_method.method_idx_diff = (uint32_t) read_uleb128(
710
0
      (dex->data + start_offset + current_size), &current_size);
711
712
0
  encoded_method.access_flags = (uint32_t) read_uleb128(
713
0
      (dex->data + start_offset + current_size), &current_size);
714
715
0
  encoded_method.code_off = (uint32_t) read_uleb128(
716
0
      (dex->data + start_offset + current_size), &current_size);
717
718
0
  yr_set_integer(
719
0
      encoded_method.method_idx_diff,
720
0
      dex->object,
721
0
      "method[%i].method_idx_diff",
722
0
      index_encoded_method);
723
724
0
  yr_set_integer(
725
0
      encoded_method.access_flags,
726
0
      dex->object,
727
0
      "method[%i].access_flags",
728
0
      index_encoded_method);
729
730
0
  yr_set_integer(
731
0
      encoded_method.code_off,
732
0
      dex->object,
733
0
      "method[%i].code_off",
734
0
      index_encoded_method);
735
736
0
  yr_set_integer(
737
0
      direct_method, dex->object, "method[%i].direct", index_encoded_method);
738
739
0
  yr_set_integer(
740
0
      virtual_method, dex->object, "method[%i].virtual", index_encoded_method);
741
742
0
  *previous_method_idx = encoded_method.method_idx_diff + *previous_method_idx;
743
744
0
  int64_t name_idx = dex_get_integer(
745
0
      dex->object, "method_ids[%i].name_idx", *previous_method_idx);
746
747
0
  if (name_idx == YR_UNDEFINED)
748
0
    return 0;
749
750
#ifdef DEBUG_DEX_MODULE
751
  printf("[DEX]\tNAME_IDX 0x%llx\n", name_idx);
752
#endif
753
754
#ifdef DEBUG_DEX_MODULE
755
  printf(
756
      "[DEX]\tEncoded method method_idx:0x%x method_idx_diff:0x%x "
757
      "access_flags:0x%x code_off:0x%x\n",
758
      *previous_method_idx,
759
      encoded_method.method_idx_diff,
760
      encoded_method.access_flags,
761
      encoded_method.code_off);
762
#endif
763
764
0
  SIZED_STRING* method_name = dex_get_string(
765
0
      dex->object, "string_ids[%i].value", name_idx);
766
767
0
  if (method_name != NULL)
768
0
  {
769
#ifdef DEBUG_DEX_MODULE
770
    printf(
771
        "[DEX]\tMETHOD_NAME %s NAME_IDX 0x%llx\n",
772
        method_name->c_string,
773
        name_idx);
774
#endif
775
776
0
    yr_set_sized_string(
777
0
        method_name->c_string,
778
0
        method_name->length,
779
0
        dex->object,
780
0
        "method[%i].name",
781
0
        index_encoded_method);
782
0
  }
783
784
0
  int64_t class_idx = dex_get_integer(
785
0
      dex->object, "method_ids[%i].class_idx", *previous_method_idx);
786
787
0
  int64_t descriptor_idx = dex_get_integer(
788
0
      dex->object, "type_ids[%i].descriptor_idx", class_idx);
789
790
0
  SIZED_STRING* class_name = dex_get_string(
791
0
      dex->object, "string_ids[%i].value", descriptor_idx);
792
793
0
  if (class_name != NULL)
794
0
  {
795
#ifdef DEBUG_DEX_MODULE
796
    printf(
797
        "[DEX]\tCLASS_NAME %s CLASS_IDX 0x%llx DESCRIPTOR_IDX:0x%llx\n",
798
        class_name->c_string,
799
        class_idx,
800
        descriptor_idx);
801
#endif
802
803
0
    yr_set_sized_string(
804
0
        class_name->c_string,
805
0
        class_name->length,
806
0
        dex->object,
807
0
        "method[%i].class_name",
808
0
        index_encoded_method);
809
0
  }
810
811
0
  int64_t proto_idx = dex_get_integer(
812
0
      dex->object, "method_ids[%i].proto_idx", *previous_method_idx);
813
814
0
  int64_t shorty_idx = dex_get_integer(
815
0
      dex->object, "proto_ids[%i].shorty_idx", proto_idx);
816
817
0
  SIZED_STRING* proto_name = dex_get_string(
818
0
      dex->object, "string_ids[%i].value", shorty_idx);
819
820
0
  if (proto_name != NULL)
821
0
  {
822
#ifdef DEBUG_DEX_MODULE
823
    printf(
824
        "[DEX]\tPROTO_NAME %s CLASS_IDX 0x%llx DESCRIPTOR_IDX:0x%llx\n",
825
        proto_name->c_string,
826
        class_idx,
827
        descriptor_idx);
828
#endif
829
830
0
    yr_set_sized_string(
831
0
        proto_name->c_string,
832
0
        proto_name->length,
833
0
        dex->object,
834
0
        "method[%i].proto",
835
0
        index_encoded_method);
836
0
  }
837
838
0
  if (encoded_method.code_off != 0)
839
0
  {
840
#ifdef DEBUG_DEX_MODULE
841
    printf("[DEX]\t\tParse CODE item\n");
842
#endif
843
844
0
    if (struct_fits_in_dex(
845
0
            dex, dex->data + encoded_method.code_off, code_item_t))
846
0
    {
847
0
      code_item_t* code_item =
848
0
          (code_item_t*) (dex->data + encoded_method.code_off);
849
850
0
      yr_set_integer(
851
0
          code_item->registers_size,
852
0
          dex->object,
853
0
          "method[%i].code_item.registers_size",
854
0
          index_encoded_method);
855
0
      yr_set_integer(
856
0
          code_item->ins_size,
857
0
          dex->object,
858
0
          "method[%i].code_item.ins_size",
859
0
          index_encoded_method);
860
0
      yr_set_integer(
861
0
          code_item->outs_size,
862
0
          dex->object,
863
0
          "method[%i].code_item.outs_size",
864
0
          index_encoded_method);
865
0
      yr_set_integer(
866
0
          code_item->tries_size,
867
0
          dex->object,
868
0
          "method[%i].code_item.tries_size",
869
0
          index_encoded_method);
870
0
      yr_set_integer(
871
0
          code_item->debug_info_off,
872
0
          dex->object,
873
0
          "method[%i].code_item.debug_info_off",
874
0
          index_encoded_method);
875
0
      yr_set_integer(
876
0
          code_item->insns_size,
877
0
          dex->object,
878
0
          "method[%i].code_item.insns_size",
879
0
          index_encoded_method);
880
881
0
      if (fits_in_dex(
882
0
              dex,
883
0
              dex->data + encoded_method.code_off + sizeof(code_item_t),
884
0
              code_item->insns_size * 2))
885
0
      {
886
0
        yr_set_sized_string(
887
0
            (const char*) (dex->data + encoded_method.code_off + sizeof(code_item_t)),
888
0
            code_item->insns_size * 2,
889
0
            dex->object,
890
0
            "method[%i].code_item.insns",
891
0
            index_encoded_method);
892
0
      }
893
0
    }
894
0
  }
895
896
0
  return current_size;
897
0
}
898
899
900
void dex_parse(DEX* dex, uint64_t base_address)
901
0
{
902
0
  dex_header_t* dex_header;
903
904
0
  int i, j;
905
906
0
  uint32_t uleb128_size = 0;
907
0
  uint32_t new_size = 0;
908
0
  uint32_t index_class_data_item = 0;
909
0
  uint32_t index_encoded_method = 0;
910
0
  uint32_t index_encoded_field = 0;
911
912
0
  if (!struct_fits_in_dex(dex, dex->data, dex_header_t))
913
0
    return;
914
915
0
  dex_parse_header(dex->header, dex->object);
916
917
0
  dex_header = dex->header;
918
919
0
  if (!fits_in_dex(
920
0
          dex,
921
0
          dex->data + yr_le32toh(dex_header->string_ids_offset),
922
0
          yr_le32toh(dex_header->string_ids_size) * sizeof(string_id_item_t)))
923
0
    return;
924
925
#ifdef DEBUG_DEX_MODULE
926
  printf("[DEX] Parse STRING ID section\n");
927
#endif
928
929
  // Get information about the String ID section
930
0
  for (i = 0; i < yr_le32toh(dex_header->string_ids_size); i++)
931
0
  {
932
0
    string_id_item_t* string_id_item =
933
0
        (string_id_item_t*) (dex->data + yr_le32toh(dex_header->string_ids_offset) + i * sizeof(string_id_item_t));
934
935
#ifdef DEBUG_DEX_MODULE
936
    printf(
937
        "[DEX] STRING ID item data_offset:0x%x\n",
938
        yr_le32toh(string_id_item->string_data_offset));
939
#endif
940
941
0
    if (!fits_in_dex(
942
0
            dex,
943
0
            dex->data + yr_le32toh(string_id_item->string_data_offset),
944
0
            sizeof(uint32_t)))
945
0
      continue;
946
947
0
    uint32_t value = (uint32_t) read_uleb128(
948
0
        (dex->data + yr_le32toh(string_id_item->string_data_offset)),
949
0
        &uleb128_size);
950
951
#ifdef DEBUG_DEX_MODULE
952
    printf("[DEX] STRING ID item size:0x%x\n", value);
953
#endif
954
955
0
    if (!fits_in_dex(
956
0
            dex,
957
0
            dex->data + yr_le32toh(string_id_item->string_data_offset) + 1,
958
0
            value))
959
0
      continue;
960
961
0
    yr_set_integer(
962
0
        yr_le32toh(string_id_item->string_data_offset),
963
0
        dex->object,
964
0
        "string_ids[%i].offset",
965
0
        i);
966
967
0
    yr_set_integer(value, dex->object, "string_ids[%i].size", i);
968
969
0
    yr_set_sized_string(
970
0
        (const char*) (
971
0
            dex->data + yr_le32toh(string_id_item->string_data_offset) + 1),
972
0
        value,
973
0
        dex->object,
974
0
        "string_ids[%i].value",
975
0
        i);
976
0
  }
977
978
0
  if (!fits_in_dex(
979
0
          dex,
980
0
          dex->data + yr_le32toh(dex_header->type_ids_offset),
981
0
          yr_le32toh(dex_header->type_ids_size) * sizeof(type_id_item_t)))
982
0
    return;
983
984
#ifdef DEBUG_DEX_MODULE
985
  printf("[DEX] Parse TYPE ID section\n");
986
#endif
987
988
  // Get information about the Type ID section
989
0
  for (i = 0; i < yr_le32toh(dex_header->type_ids_size); i++)
990
0
  {
991
0
    type_id_item_t* type_id_item =
992
0
        (type_id_item_t*) (dex->data + yr_le32toh(dex_header->type_ids_offset) + i * sizeof(type_id_item_t));
993
994
0
    yr_set_integer(
995
0
        yr_le32toh(type_id_item->descriptor_idx),
996
0
        dex->object,
997
0
        "type_ids[%i].descriptor_idx",
998
0
        i);
999
0
  }
1000
1001
0
  if (!fits_in_dex(
1002
0
          dex,
1003
0
          dex->data + yr_le32toh(dex_header->proto_ids_offset),
1004
0
          yr_le32toh(dex_header->proto_ids_size) * sizeof(proto_id_item_t)))
1005
0
    return;
1006
1007
#ifdef DEBUG_DEX_MODULE
1008
  printf("[DEX] Parse PROTO ID section\n");
1009
#endif
1010
1011
  // Get information about the Proto ID section
1012
0
  for (i = 0; i < yr_le32toh(dex_header->proto_ids_size); i++)
1013
0
  {
1014
0
    proto_id_item_t* proto_id_item =
1015
0
        (proto_id_item_t*) (dex->data + yr_le32toh(dex_header->proto_ids_offset) + i * sizeof(proto_id_item_t));
1016
1017
0
    yr_set_integer(
1018
0
        yr_le32toh(proto_id_item->shorty_idx),
1019
0
        dex->object,
1020
0
        "proto_ids[%i].shorty_idx",
1021
0
        i);
1022
0
    yr_set_integer(
1023
0
        yr_le32toh(proto_id_item->return_type_idx),
1024
0
        dex->object,
1025
0
        "proto_ids[%i].return_type_idx",
1026
0
        i);
1027
0
    yr_set_integer(
1028
0
        yr_le32toh(proto_id_item->parameters_offset),
1029
0
        dex->object,
1030
0
        "proto_ids[%i].parameters_offset",
1031
0
        i);
1032
0
  }
1033
1034
0
  if (!fits_in_dex(
1035
0
          dex,
1036
0
          dex->data + yr_le32toh(dex_header->field_ids_offset),
1037
0
          yr_le32toh(dex_header->field_ids_size) * sizeof(field_id_item_t)))
1038
0
    return;
1039
1040
#ifdef DEBUG_DEX_MODULE
1041
  printf("[DEX] Parse FIELD ID section\n");
1042
#endif
1043
1044
  // Get information about the Field ID section
1045
0
  for (i = 0; i < yr_le32toh(dex_header->field_ids_size); i++)
1046
0
  {
1047
0
    field_id_item_t* field_id_item =
1048
0
        (field_id_item_t*) (dex->data + yr_le32toh(dex_header->field_ids_offset) + i * sizeof(field_id_item_t));
1049
1050
0
    yr_set_integer(
1051
0
        yr_le16toh(field_id_item->class_idx),
1052
0
        dex->object,
1053
0
        "field_ids[%i].class_idx",
1054
0
        i);
1055
0
    yr_set_integer(
1056
0
        yr_le16toh(field_id_item->type_idx),
1057
0
        dex->object,
1058
0
        "field_ids[%i].type_idx",
1059
0
        i);
1060
0
    yr_set_integer(
1061
0
        yr_le32toh(field_id_item->name_idx),
1062
0
        dex->object,
1063
0
        "field_ids[%i].name_idx",
1064
0
        i);
1065
0
  }
1066
1067
0
  if (!fits_in_dex(
1068
0
          dex,
1069
0
          dex->data + yr_le32toh(dex_header->method_ids_offset),
1070
0
          yr_le32toh(dex_header->method_ids_size) * sizeof(method_id_item_t)))
1071
0
    return;
1072
1073
#ifdef DEBUG_DEX_MODULE
1074
  printf("[DEX] Parse METHOD ID section\n");
1075
#endif
1076
1077
  // Get information about the Method ID section
1078
0
  for (i = 0; i < yr_le32toh(dex_header->method_ids_size); i++)
1079
0
  {
1080
0
    method_id_item_t* method_id_item =
1081
0
        (method_id_item_t*) (dex->data + yr_le32toh(dex_header->method_ids_offset) + i * sizeof(method_id_item_t));
1082
1083
0
    yr_set_integer(
1084
0
        yr_le16toh(method_id_item->class_idx),
1085
0
        dex->object,
1086
0
        "method_ids[%i].class_idx",
1087
0
        i);
1088
0
    yr_set_integer(
1089
0
        yr_le16toh(method_id_item->proto_idx),
1090
0
        dex->object,
1091
0
        "method_ids[%i].proto_idx",
1092
0
        i);
1093
0
    yr_set_integer(
1094
0
        yr_le32toh(method_id_item->name_idx),
1095
0
        dex->object,
1096
0
        "method_ids[%i].name_idx",
1097
0
        i);
1098
0
  }
1099
1100
#ifdef DEBUG_DEX_MODULE
1101
  printf("[DEX] Parse MAP List ID section\n");
1102
#endif
1103
1104
  // Get information about the Map List ID section
1105
0
  if (yr_le32toh(dex_header->map_offset) != 0 &&
1106
0
      fits_in_dex(
1107
0
          dex,
1108
0
          dex->data + yr_le32toh(dex_header->map_offset),
1109
0
          sizeof(uint32_t)))
1110
0
  {
1111
0
    uint32_t* map_list_size =
1112
0
        (uint32_t*) (dex->data + yr_le32toh(dex_header->map_offset));
1113
1114
0
    yr_set_integer(yr_le32toh(*map_list_size), dex->object, "map_list.size");
1115
1116
0
    if (!fits_in_dex(
1117
0
            dex,
1118
0
            dex->data + yr_le32toh(dex_header->map_offset),
1119
0
            sizeof(uint32_t) + yr_le32toh(*map_list_size) * sizeof(map_item_t)))
1120
0
      return;
1121
1122
0
    for (i = 0; i < yr_le32toh(*map_list_size); i++)
1123
0
    {
1124
0
      map_item_t* map_item =
1125
0
          (map_item_t*) (dex->data + yr_le32toh(dex_header->map_offset) + sizeof(uint32_t) + i * sizeof(map_item_t));
1126
1127
0
      if (!struct_fits_in_dex(dex, map_item, map_item_t))
1128
0
        return;
1129
1130
0
      yr_set_integer(
1131
0
          yr_le16toh(map_item->type),
1132
0
          dex->object,
1133
0
          "map_list.map_item[%i].type",
1134
0
          i);
1135
0
      yr_set_integer(
1136
0
          yr_le16toh(map_item->unused),
1137
0
          dex->object,
1138
0
          "map_list.map_item[%i].unused",
1139
0
          i);
1140
0
      yr_set_integer(
1141
0
          yr_le32toh(map_item->size),
1142
0
          dex->object,
1143
0
          "map_list.map_item[%i].size",
1144
0
          i);
1145
0
      yr_set_integer(
1146
0
          yr_le32toh(map_item->offset),
1147
0
          dex->object,
1148
0
          "map_list.map_item[%i].offset",
1149
0
          i);
1150
0
    }
1151
0
  }
1152
1153
0
  if (!fits_in_dex(
1154
0
          dex,
1155
0
          dex->data + yr_le32toh(dex_header->class_defs_offset),
1156
0
          yr_le32toh(dex_header->class_defs_size) * sizeof(class_id_item_t)))
1157
0
    return;
1158
1159
#ifdef DEBUG_DEX_MODULE
1160
  printf("[DEX] Parse CLASS ID section\n");
1161
#endif
1162
1163
  // Get information about the Class ID section
1164
0
  for (i = 0; i < yr_le32toh(dex_header->class_defs_size); i++)
1165
0
  {
1166
0
    class_id_item_t* class_id_item =
1167
0
        (class_id_item_t*) (dex->data + yr_le32toh(dex_header->class_defs_offset) + i * sizeof(class_id_item_t));
1168
1169
#ifdef DEBUG_DEX_MODULE
1170
    printf(
1171
        "[DEX] CLASS ID item class_idx:0x%x access_flags:0x%x "
1172
        "super_class_idx:0x%x interfaces_offset:0x%x source_file_idx:0x%x "
1173
        "annotations_offset:0x%x class_data_offset:0x%x "
1174
        "static_values_offset:0x%x\n",
1175
        yr_le32toh(class_id_item->class_idx),
1176
        yr_le32toh(class_id_item->access_flags),
1177
        yr_le32toh(class_id_item->super_class_idx),
1178
        yr_le32toh(class_id_item->interfaces_offset),
1179
        yr_le32toh(class_id_item->source_file_idx),
1180
        yr_le32toh(class_id_item->annotations_offset),
1181
        yr_le32toh(class_id_item->class_data_offset),
1182
        yr_le32toh(class_id_item->static_values_offset));
1183
#endif
1184
1185
0
    yr_set_integer(
1186
0
        yr_le32toh(class_id_item->class_idx),
1187
0
        dex->object,
1188
0
        "class_defs[%i].class_idx",
1189
0
        i);
1190
0
    yr_set_integer(
1191
0
        yr_le32toh(class_id_item->access_flags),
1192
0
        dex->object,
1193
0
        "class_defs[%i].access_flags",
1194
0
        i);
1195
0
    yr_set_integer(
1196
0
        yr_le32toh(class_id_item->super_class_idx),
1197
0
        dex->object,
1198
0
        "class_defs[%i].super_class_idx",
1199
0
        i);
1200
0
    yr_set_integer(
1201
0
        yr_le32toh(class_id_item->interfaces_offset),
1202
0
        dex->object,
1203
0
        "class_defs[%i].interfaces_offset",
1204
0
        i);
1205
0
    yr_set_integer(
1206
0
        yr_le32toh(class_id_item->source_file_idx),
1207
0
        dex->object,
1208
0
        "class_defs[%i].source_file_idx",
1209
0
        i);
1210
0
    yr_set_integer(
1211
0
        yr_le32toh(class_id_item->annotations_offset),
1212
0
        dex->object,
1213
0
        "class_defs[%i].annotations_offset",
1214
0
        i);
1215
0
    yr_set_integer(
1216
0
        yr_le32toh(class_id_item->class_data_offset),
1217
0
        dex->object,
1218
0
        "class_defs[%i].class_data_offset",
1219
0
        i);
1220
0
    yr_set_integer(
1221
0
        yr_le32toh(class_id_item->static_values_offset),
1222
0
        dex->object,
1223
0
        "class_defs[%i].static_values_offset",
1224
0
        i);
1225
1226
0
    if (yr_le32toh(class_id_item->class_data_offset) != 0)
1227
0
    {
1228
0
      class_data_item_t class_data_item;
1229
1230
0
      if (!fits_in_dex(
1231
0
              dex,
1232
0
              dex->data + yr_le32toh(class_id_item->class_data_offset),
1233
0
              4 * sizeof(uint32_t)))
1234
0
        return;
1235
1236
0
      uleb128_size = 0;
1237
1238
0
      class_data_item.static_fields_size = (uint32_t) read_uleb128(
1239
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset)),
1240
0
          &uleb128_size);
1241
1242
0
      class_data_item.instance_fields_size = (uint32_t) read_uleb128(
1243
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1244
0
           uleb128_size),
1245
0
          &uleb128_size);
1246
1247
0
      class_data_item.direct_methods_size = (uint32_t) read_uleb128(
1248
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1249
0
           uleb128_size),
1250
0
          &uleb128_size);
1251
1252
0
      class_data_item.virtual_methods_size = (uint32_t) read_uleb128(
1253
0
          (dex->data + yr_le32toh(class_id_item->class_data_offset) +
1254
0
           uleb128_size),
1255
0
          &uleb128_size);
1256
1257
0
      yr_set_integer(
1258
0
          class_data_item.static_fields_size,
1259
0
          dex->object,
1260
0
          "class_data_item[%i].static_fields_size",
1261
0
          index_class_data_item);
1262
1263
0
      yr_set_integer(
1264
0
          class_data_item.instance_fields_size,
1265
0
          dex->object,
1266
0
          "class_data_item[%i].instance_fields_size",
1267
0
          index_class_data_item);
1268
1269
0
      yr_set_integer(
1270
0
          class_data_item.direct_methods_size,
1271
0
          dex->object,
1272
0
          "class_data_item[%i].direct_methods_size",
1273
0
          index_class_data_item);
1274
1275
0
      yr_set_integer(
1276
0
          class_data_item.virtual_methods_size,
1277
0
          dex->object,
1278
0
          "class_data_item[%i].virtual_methods_size",
1279
0
          index_class_data_item);
1280
1281
#ifdef DEBUG_DEX_MODULE
1282
      printf("[DEX] CLASS DATA item static fields\n");
1283
#endif
1284
1285
0
      uint32_t previous_field_idx = 0;
1286
0
      for (j = 0; j < class_data_item.static_fields_size; j++)
1287
0
      {
1288
0
        new_size = load_encoded_field(
1289
0
            dex,
1290
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1291
0
            &previous_field_idx,
1292
0
            index_encoded_field,
1293
0
            1,
1294
0
            0);
1295
1296
        // If the current field isn't parsed the other fields aren't likely to
1297
        // parse.
1298
0
        if (new_size == 0)
1299
0
          break;
1300
1301
0
        uleb128_size += new_size;
1302
0
        index_encoded_field += 1;
1303
0
      }
1304
1305
#ifdef DEBUG_DEX_MODULE
1306
      printf("[DEX] CLASS DATA item instance fields\n");
1307
#endif
1308
1309
0
      previous_field_idx = 0;
1310
1311
0
      for (j = 0; j < class_data_item.instance_fields_size; j++)
1312
0
      {
1313
0
        new_size = load_encoded_field(
1314
0
            dex,
1315
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1316
0
            &previous_field_idx,
1317
0
            index_encoded_field,
1318
0
            0,
1319
0
            1);
1320
1321
        // If the current field isn't parsed the other fields aren't likely to
1322
        // parse.
1323
0
        if (new_size == 0)
1324
0
          break;
1325
1326
0
        uleb128_size += new_size;
1327
0
        index_encoded_field += 1;
1328
0
      }
1329
1330
#ifdef DEBUG_DEX_MODULE
1331
      printf("[DEX] CLASS DATA item direct methods\n");
1332
#endif
1333
1334
0
      uint32_t previous_method_idx = 0;
1335
1336
0
      for (j = 0; j < class_data_item.direct_methods_size; j++)
1337
0
      {
1338
0
        new_size = load_encoded_method(
1339
0
            dex,
1340
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1341
0
            &previous_method_idx,
1342
0
            index_encoded_method,
1343
0
            1,
1344
0
            0);
1345
1346
        // If the current field isn't parsed the other fields aren't likely to
1347
        // parse.
1348
0
        if (new_size == 0)
1349
0
          break;
1350
1351
0
        uleb128_size += new_size;
1352
0
        index_encoded_method += 1;
1353
0
      }
1354
1355
#ifdef DEBUG_DEX_MODULE
1356
      printf("[DEX] CLASS DATA item virtual methods\n");
1357
#endif
1358
1359
0
      previous_method_idx = 0;
1360
1361
0
      for (j = 0; j < class_data_item.virtual_methods_size; j++)
1362
0
      {
1363
0
        new_size = load_encoded_method(
1364
0
            dex,
1365
0
            yr_le32toh(class_id_item->class_data_offset) + uleb128_size,
1366
0
            &previous_method_idx,
1367
0
            index_encoded_method,
1368
0
            0,
1369
0
            1);
1370
1371
        // If the current field isn't parsed the other fields aren't likely to
1372
        // parse.
1373
0
        if (new_size == 0)
1374
0
          break;
1375
1376
0
        uleb128_size += new_size;
1377
0
        index_encoded_method += 1;
1378
0
      }
1379
1380
0
      index_class_data_item++;
1381
0
    }
1382
0
  }
1383
1384
0
  yr_set_integer(index_encoded_method, dex->object, "number_of_methods");
1385
0
  yr_set_integer(index_encoded_field, dex->object, "number_of_fields");
1386
0
}
1387
1388
1389
int module_initialize(YR_MODULE* module)
1390
2
{
1391
2
  return ERROR_SUCCESS;
1392
2
}
1393
1394
1395
int module_finalize(YR_MODULE* module)
1396
0
{
1397
0
  return ERROR_SUCCESS;
1398
0
}
1399
1400
1401
int module_load(
1402
    YR_SCAN_CONTEXT* context,
1403
    YR_OBJECT* module_object,
1404
    void* module_data,
1405
    size_t module_data_size)
1406
0
{
1407
0
  YR_MEMORY_BLOCK* block;
1408
0
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1409
1410
0
  dex_header_t* dex_header;
1411
1412
0
  yr_set_string(DEX_FILE_MAGIC_035, module_object, "DEX_FILE_MAGIC_035");
1413
0
  yr_set_string(DEX_FILE_MAGIC_036, module_object, "DEX_FILE_MAGIC_036");
1414
0
  yr_set_string(DEX_FILE_MAGIC_037, module_object, "DEX_FILE_MAGIC_037");
1415
0
  yr_set_string(DEX_FILE_MAGIC_038, module_object, "DEX_FILE_MAGIC_038");
1416
0
  yr_set_string(DEX_FILE_MAGIC_039, module_object, "DEX_FILE_MAGIC_039");
1417
1418
0
  yr_set_integer(0x12345678, module_object, "ENDIAN_CONSTANT");
1419
0
  yr_set_integer(0x78563412, module_object, "REVERSE_ENDIAN_CONSTANT");
1420
1421
0
  yr_set_integer(0xffffffff, module_object, "NO_INDEX");
1422
0
  yr_set_integer(0x1, module_object, "ACC_PUBLIC");
1423
0
  yr_set_integer(0x2, module_object, "ACC_PRIVATE");
1424
0
  yr_set_integer(0x4, module_object, "ACC_PROTECTED");
1425
0
  yr_set_integer(0x8, module_object, "ACC_STATIC");
1426
0
  yr_set_integer(0x10, module_object, "ACC_FINAL");
1427
0
  yr_set_integer(0x20, module_object, "ACC_SYNCHRONIZED");
1428
0
  yr_set_integer(0x40, module_object, "ACC_VOLATILE");
1429
0
  yr_set_integer(0x40, module_object, "ACC_BRIDGE");
1430
0
  yr_set_integer(0x80, module_object, "ACC_TRANSIENT");
1431
0
  yr_set_integer(0x80, module_object, "ACC_VARARGS");
1432
0
  yr_set_integer(0x100, module_object, "ACC_NATIVE");
1433
0
  yr_set_integer(0x200, module_object, "ACC_INTERFACE");
1434
0
  yr_set_integer(0x400, module_object, "ACC_ABSTRACT");
1435
0
  yr_set_integer(0x800, module_object, "ACC_STRICT");
1436
0
  yr_set_integer(0x1000, module_object, "ACC_SYNTHETIC");
1437
0
  yr_set_integer(0x2000, module_object, "ACC_ANNOTATION");
1438
0
  yr_set_integer(0x4000, module_object, "ACC_ENUM");
1439
0
  yr_set_integer(0x10000, module_object, "ACC_CONSTRUCTOR");
1440
0
  yr_set_integer(0x20000, module_object, "ACC_DECLARED_SYNCHRONIZED");
1441
1442
0
  yr_set_integer(0x0000, module_object, "TYPE_HEADER_ITEM");
1443
0
  yr_set_integer(0x0001, module_object, "TYPE_STRING_ID_ITEM");
1444
0
  yr_set_integer(0x0002, module_object, "TYPE_TYPE_ID_ITEM");
1445
0
  yr_set_integer(0x0003, module_object, "TYPE_PROTO_ID_ITEM");
1446
0
  yr_set_integer(0x0004, module_object, "TYPE_FIELD_ID_ITEM");
1447
0
  yr_set_integer(0x0005, module_object, "TYPE_METHOD_ID_ITEM");
1448
0
  yr_set_integer(0x0006, module_object, "TYPE_CLASS_DEF_ITEM");
1449
0
  yr_set_integer(0x0007, module_object, "TYPE_CALL_SITE_ID_ITEM");
1450
0
  yr_set_integer(0x0008, module_object, "TYPE_METHOD_HANDLE_ITEM");
1451
0
  yr_set_integer(0x1000, module_object, "TYPE_MAP_LIST");
1452
0
  yr_set_integer(0x1001, module_object, "TYPE_TYPE_LIST");
1453
0
  yr_set_integer(0x1002, module_object, "TYPE_ANNOTATION_SET_REF_LIST");
1454
0
  yr_set_integer(0x1003, module_object, "TYPE_ANNOTATION_SET_ITEM");
1455
0
  yr_set_integer(0x2000, module_object, "TYPE_CLASS_DATA_ITEM");
1456
0
  yr_set_integer(0x2001, module_object, "TYPE_CODE_ITEM");
1457
0
  yr_set_integer(0x2002, module_object, "TYPE_STRING_DATA_ITEM");
1458
0
  yr_set_integer(0x2003, module_object, "TYPE_DEBUG_INFO_ITEM");
1459
0
  yr_set_integer(0x2004, module_object, "TYPE_ANNOTATION_ITEM");
1460
0
  yr_set_integer(0x2005, module_object, "TYPE_ENCODED_ARRAY_ITEM");
1461
0
  yr_set_integer(0x2006, module_object, "TYPE_ANNOTATIONS_DIRECTORY_ITEM");
1462
1463
0
  foreach_memory_block(iterator, block)
1464
0
  {
1465
0
    const uint8_t* block_data = block->fetch_data(block);
1466
1467
0
    if (block_data == NULL)
1468
0
      continue;
1469
1470
0
    dex_header = dex_get_header(block_data, block->size);
1471
1472
0
    if (dex_header != NULL)
1473
0
    {
1474
0
      DEX* dex = (DEX*) yr_malloc(sizeof(DEX));
1475
1476
0
      if (dex == NULL)
1477
0
        return ERROR_INSUFFICIENT_MEMORY;
1478
1479
0
      dex->data = block_data;
1480
0
      dex->data_size = block->size;
1481
0
      dex->object = module_object;
1482
0
      dex->header = dex_header;
1483
1484
0
      module_object->data = dex;
1485
1486
0
      dex_parse(dex, block->base);
1487
0
      break;
1488
0
    }
1489
0
  }
1490
1491
0
  return ERROR_SUCCESS;
1492
0
}
1493
1494
1495
int module_unload(YR_OBJECT* module_object)
1496
0
{
1497
0
  DEX* dex = (DEX*) module_object->data;
1498
1499
0
  if (dex == NULL)
1500
0
    return ERROR_SUCCESS;
1501
1502
0
  yr_free(dex);
1503
1504
0
  return ERROR_SUCCESS;
1505
0
}
1506
1507
#undef MODULE_NAME