Coverage Report

Created: 2023-03-01 06:20

/src/yara/libyara/modules/elf/elf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2014. 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 <limits.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <tlshc/tlsh.h>
34
#include <yara/elf.h>
35
#include <yara/elf_utils.h>
36
#include <yara/endian.h>
37
#include <yara/mem.h>
38
#include <yara/modules.h>
39
#include <yara/simple_str.h>
40
#include <yara/utils.h>
41
#include "../crypto.h"
42
43
#define MODULE_NAME elf
44
45
0
#define CLASS_DATA(c, d) ((c << 8) | d)
46
47
static int sort_strcmp(const void* a, const void* b)
48
0
{
49
0
  return strcmp(*(const char**) a, *(const char**) b);
50
0
}
51
52
define_function(telfhash)
53
0
{
54
0
  YR_OBJECT* obj = yr_module();
55
0
  ELF* elf = (ELF*) obj->data;
56
0
  if (elf == NULL)
57
0
    return_string(YR_UNDEFINED);
58
59
0
  if (elf->telfhash)
60
0
    return_string(elf->telfhash);
61
62
  /* We prefer dynsym if possible */
63
0
  ELF_SYMBOL_LIST* list = elf->dynsym ? elf->dynsym : elf->symtab;
64
0
  if (!list)
65
0
    return_string(YR_UNDEFINED);
66
67
  /* exclusions are based on the original implementation
68
     https://github.com/trendmicro/telfhash/blob/master/telfhash/telfhash.py */
69
0
  char* exclude_strings[] = {
70
0
      "__libc_start_main",
71
0
      "main",
72
0
      "abort",
73
0
      "cachectl",
74
0
      "cacheflush",
75
0
      "puts",
76
0
      "atol",
77
0
      "malloc_trim"};
78
79
0
  SIMPLE_STR* sstr = NULL;
80
0
  Tlsh* tlsh = NULL;
81
82
0
  int symbol_count = 0;
83
0
  char** clean_names = yr_calloc(list->count, sizeof(*clean_names));
84
85
0
  if (!clean_names)
86
0
    return_string(YR_UNDEFINED);
87
88
0
  for (ELF_SYMBOL* i = list->symbols; i != NULL; i = i->next)
89
0
  {
90
0
    char* name = i->name;
91
92
0
    if (!name)
93
0
      continue;
94
95
    /* Use only global code symbols */
96
0
    if (i->bind != ELF_STB_GLOBAL || i->type != ELF_STT_FUNC ||
97
0
        i->visibility != ELF_STV_DEFAULT)
98
0
      continue;
99
100
    /* ignore:
101
        x86-64 specific functions
102
        string functions (str.* and mem.*), gcc changes them depending on arch
103
        symbols starting with . or _ */
104
0
    bool is_bad_prefix = name[0] == '.' || name[0] == '_';
105
0
    size_t namelen = strlen(name);
106
0
    bool is_x86_64 = namelen >= 2 && strncmp(name + namelen - 2, "64", 2) == 0;
107
0
    bool is_mem_or_str = strncmp(name, "str", 3) == 0 ||
108
0
                         strncmp(name, "mem", 3) == 0;
109
110
0
    if (is_bad_prefix || is_x86_64 || is_mem_or_str)
111
0
      continue;
112
113
    /* Exclude any symbols that match the excluded ones */
114
0
    bool is_excluded = false;
115
0
    for (int i = 0; i < sizeof(exclude_strings) / sizeof(*exclude_strings); i++)
116
0
    {
117
0
      if (strcmp(name, exclude_strings[i]) == 0)
118
0
      {
119
0
        is_excluded = true;
120
0
        break;
121
0
      }
122
0
    }
123
124
0
    if (is_excluded)
125
0
      continue;
126
127
0
    clean_names[symbol_count] = yr_malloc(strlen(name) + 1);
128
129
0
    if (!clean_names[symbol_count])
130
0
      goto cleanup;
131
132
    /* Convert it to lowercase */
133
0
    int j;
134
0
    for (j = 0; name[j]; j++) clean_names[symbol_count][j] = tolower(name[j]);
135
136
0
    clean_names[symbol_count][j] = '\0';
137
138
0
    symbol_count++;
139
0
  }
140
141
0
  if (!symbol_count)
142
0
    goto cleanup;
143
144
  /* Now we have all the valid symbols, sort them, concat them */
145
0
  qsort(clean_names, symbol_count, sizeof(*clean_names), &sort_strcmp);
146
147
0
  sstr = sstr_newf("%s", clean_names[0]);
148
0
  if (!sstr)
149
0
    goto cleanup;
150
151
  /* We've already written first symbol, start at 1 */
152
0
  for (int i = 1; i < symbol_count; ++i)
153
0
  {
154
0
    if (!sstr_appendf(sstr, ",%s", clean_names[i]))
155
0
      goto cleanup;
156
0
  }
157
158
0
  tlsh = tlsh_new();
159
0
  if (!tlsh)
160
0
    goto cleanup;
161
162
0
  tlsh_final(tlsh, (const unsigned char*) sstr->str, sstr->len, 0);
163
164
0
  const char* telfhash = tlsh_get_hash(tlsh, true);
165
0
  elf->telfhash = yr_strdup(telfhash);  // cache it
166
0
  if (!elf->telfhash)
167
0
    goto cleanup;
168
169
0
  for (int i = 0; i < symbol_count; ++i) yr_free(clean_names[i]);
170
0
  yr_free(clean_names);
171
0
  sstr_free(sstr);
172
0
  tlsh_free(tlsh);
173
174
0
  return_string(elf->telfhash);
175
176
0
cleanup:
177
0
  for (int i = 0; i < symbol_count; ++i) yr_free(clean_names[i]);
178
0
  yr_free(clean_names);
179
0
  sstr_free(sstr);
180
0
  tlsh_free(tlsh);
181
182
0
  return_string(YR_UNDEFINED);
183
0
}
184
185
#if defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H) || \
186
    defined(HAVE_COMMONCRYPTO_COMMONCRYPTO_H)
187
188
define_function(import_md5)
189
{
190
  YR_OBJECT* obj = yr_module();
191
  ELF* elf = (ELF*) obj->data;
192
  if (elf == NULL)
193
    return_string(YR_UNDEFINED);
194
195
  if (elf->import_hash)
196
    return_string(elf->import_hash);
197
198
  ELF_SYMBOL_LIST* list = elf->dynsym ? elf->dynsym : elf->symtab;
199
  if (!list)
200
    return_string(YR_UNDEFINED);
201
202
  SIMPLE_STR* sstr = NULL;
203
204
  int symbol_count = 0;
205
  char** clean_names = yr_malloc(list->count * sizeof(*clean_names));
206
  if (!clean_names)
207
    return_string(YR_UNDEFINED);
208
209
  for (ELF_SYMBOL* i = list->symbols; i != NULL; i = i->next)
210
  {
211
    char* name = i->name;
212
213
    if (!name)
214
      continue;
215
216
    if (i->shndx != ELF_SHN_UNDEF)
217
      continue;
218
219
    // skip empty names
220
    if (strlen(i->name) == 0)
221
      continue;
222
223
    clean_names[symbol_count] = yr_malloc(strlen(name) + 1);
224
    if (!clean_names[symbol_count])
225
      goto cleanup;
226
227
    /* Convert it to lowercase */
228
    int j;
229
    for (j = 0; name[j]; j++) clean_names[symbol_count][j] = tolower(name[j]);
230
231
    clean_names[symbol_count][j] = '\0';
232
233
    symbol_count++;
234
  }
235
236
  if (!symbol_count)
237
    goto cleanup;
238
239
  /* Now we have all the valid symbols, sort them, concat them */
240
  qsort(clean_names, symbol_count, sizeof(*clean_names), &sort_strcmp);
241
242
  sstr = sstr_newf("%s", clean_names[0]);
243
  if (!sstr)
244
    goto cleanup;
245
246
  /* We've already written first symbol, start at 1 */
247
  for (int i = 1; i < symbol_count; ++i)
248
  {
249
    if (!sstr_appendf(sstr, ",%s", clean_names[i]))
250
      goto cleanup;
251
  }
252
253
  unsigned char hash[YR_MD5_LEN];
254
255
  yr_md5_ctx ctx;
256
  yr_md5_init(&ctx);
257
  yr_md5_update(&ctx, sstr->str, sstr->len);
258
  yr_md5_final(hash, &ctx);
259
260
  elf->import_hash = yr_malloc(YR_MD5_LEN * 2 + 1);
261
  if (!elf->import_hash)
262
    goto cleanup;
263
264
  for (int i = 0; i < YR_MD5_LEN; ++i)
265
    sprintf(elf->import_hash + (i * 2), "%02x", hash[i]);
266
267
  for (int i = 0; i < symbol_count; ++i) yr_free(clean_names[i]);
268
  yr_free(clean_names);
269
  sstr_free(sstr);
270
271
  return_string(elf->import_hash);
272
273
cleanup:
274
  for (int i = 0; i < symbol_count; ++i) yr_free(clean_names[i]);
275
  yr_free(clean_names);
276
  sstr_free(sstr);
277
278
  return_string(YR_UNDEFINED);
279
}
280
281
#endif  // defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H)
282
283
int get_elf_class_data(const uint8_t* buffer, size_t buffer_length)
284
0
{
285
0
  elf_ident_t* elf_ident;
286
287
0
  if (buffer_length < sizeof(elf_ident_t))
288
0
    return 0;
289
290
0
  elf_ident = (elf_ident_t*) buffer;
291
292
0
  if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
293
0
  {
294
0
    return CLASS_DATA(elf_ident->_class, elf_ident->data);
295
0
  }
296
0
  else
297
0
  {
298
0
    return 0;
299
0
  }
300
0
}
301
302
static bool is_valid_ptr(
303
    const void* base,
304
    size_t size,
305
    const void* ptr,
306
    uint64_t ptr_size)  // ptr_size can be 64bit even in 32bit systems.
307
0
{
308
0
  return ptr >= base && ptr_size <= size &&
309
0
         ((char*) ptr) + ptr_size <= ((char*) base) + size;
310
0
}
311
312
#define IS_VALID_PTR(base, size, ptr) \
313
0
  is_valid_ptr(base, size, ptr, sizeof(*ptr))
314
315
//
316
// Returns a string table entry for the index or NULL if the entry is out
317
// of bounds. A non-null return value will be a null-terminated C string.
318
//
319
static const char* str_table_entry(
320
    const char* str_table_base,
321
    const char* str_table_limit,
322
    int index)
323
0
{
324
0
  size_t len;
325
0
  const char* str_entry;
326
327
0
  if (str_table_base >= str_table_limit)
328
0
    return NULL;
329
330
  // The first entry in the string table must be a null character, if not the
331
  // string table is probably corrupted.
332
0
  if (*str_table_base != '\0')
333
0
    return NULL;
334
335
0
  if (index < 0)
336
0
    return NULL;
337
338
0
  str_entry = str_table_base + index;
339
340
0
  if (str_entry >= str_table_limit)
341
0
    return NULL;
342
343
0
  len = strnlen(str_entry, str_table_limit - str_entry);
344
345
  // Entry is clamped by extent of string table, not null-terminated.
346
0
  if (str_entry + len == str_table_limit)
347
0
    return NULL;
348
349
0
  return str_entry;
350
0
}
351
352
#define ELF_SIZE_OF_SECTION_TABLE(bits, bo, h) \
353
0
  (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count))
354
355
#define ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, h) \
356
0
  (sizeof(elf##bits##_program_header_t) * yr_##bo##16toh(h->ph_entry_count))
357
358
#define ELF_RVA_TO_OFFSET(bits, bo)                                                \
359
  uint64_t elf_rva_to_offset_##bits##_##bo(                                        \
360
      elf##bits##_header_t* elf_header, uint64_t rva, size_t elf_size)             \
361
0
  {                                                                                \
362
0
    if (yr_##bo##16toh(elf_header->type) == ELF_ET_EXEC)                           \
363
0
    {                                                                              \
364
0
      int i;                                                                       \
365
0
                                                                                   \
366
0
      elf##bits##_program_header_t* program;                                       \
367
0
                                                                                   \
368
0
      /* check that ph_offset doesn't wrap when added to SIZE_OF_PROGRAM_TABLE     \
369
0
       */                                                                          \
370
0
                                                                                   \
371
0
      if (ULONG_MAX - yr_##bo##bits##toh(elf_header->ph_offset) <                  \
372
0
          ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, elf_header))                         \
373
0
      {                                                                            \
374
0
        return YR_UNDEFINED;                                                       \
375
0
      }                                                                            \
376
0
                                                                                   \
377
0
      if (yr_##bo##bits##toh(elf_header->ph_offset) == 0 ||                        \
378
0
          yr_##bo##bits##toh(elf_header->ph_offset) > elf_size ||                  \
379
0
          yr_##bo##bits##toh(elf_header->ph_offset) +                              \
380
0
                  ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, elf_header) >                \
381
0
              elf_size ||                                                          \
382
0
          yr_##bo##16toh(elf_header->ph_entry_count) == 0)                         \
383
0
      {                                                                            \
384
0
        return YR_UNDEFINED;                                                       \
385
0
      }                                                                            \
386
0
                                                                                   \
387
0
      program = (elf##bits##_program_header_t*)                                  \
388
0
        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->ph_offset)); \
389
0
                                                                                   \
390
0
      for (i = 0; i < yr_##bo##16toh(elf_header->ph_entry_count); i++)             \
391
0
      {                                                                            \
392
0
        if (rva >= yr_##bo##bits##toh(program->virt_addr) &&                       \
393
0
            rva < yr_##bo##bits##toh(program->virt_addr) +                         \
394
0
                      yr_##bo##bits##toh(program->mem_size))                       \
395
0
        {                                                                          \
396
0
          return yr_##bo##bits##toh(program->offset) +                             \
397
0
                 (rva - yr_##bo##bits##toh(program->virt_addr));                   \
398
0
        }                                                                          \
399
0
                                                                                   \
400
0
        program++;                                                                 \
401
0
      }                                                                            \
402
0
    }                                                                              \
403
0
    else                                                                           \
404
0
    {                                                                              \
405
0
      int i;                                                                       \
406
0
                                                                                   \
407
0
      elf##bits##_section_header_t* section;                                       \
408
0
                                                                                   \
409
0
      /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE     \
410
0
       */                                                                          \
411
0
                                                                                   \
412
0
      if (ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                  \
413
0
          ELF_SIZE_OF_SECTION_TABLE(bits, bo, elf_header))                         \
414
0
      {                                                                            \
415
0
        return YR_UNDEFINED;                                                       \
416
0
      }                                                                            \
417
0
                                                                                   \
418
0
      if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                        \
419
0
          yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                  \
420
0
          yr_##bo##bits##toh(elf_header->sh_offset) +                              \
421
0
                  ELF_SIZE_OF_SECTION_TABLE(bits, bo, elf_header) >                \
422
0
              elf_size ||                                                          \
423
0
          yr_##bo##16toh(elf_header->sh_entry_count) == 0)                         \
424
0
      {                                                                            \
425
0
        return YR_UNDEFINED;                                                       \
426
0
      }                                                                            \
427
0
                                                                                   \
428
0
      section = (elf##bits##_section_header_t*)                                  \
429
0
        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset)); \
430
0
                                                                                   \
431
0
      for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)             \
432
0
      {                                                                            \
433
0
        if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                       \
434
0
            yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                     \
435
0
            rva >= yr_##bo##bits##toh(section->addr) &&                            \
436
0
            rva < yr_##bo##bits##toh(section->addr) +                              \
437
0
                      yr_##bo##bits##toh(section->size))                           \
438
0
        {                                                                          \
439
0
          return yr_##bo##bits##toh(section->offset) +                             \
440
0
                 (rva - yr_##bo##bits##toh(section->addr));                        \
441
0
        }                                                                          \
442
0
                                                                                   \
443
0
        section++;                                                                 \
444
0
      }                                                                            \
445
0
    }                                                                              \
446
0
    return YR_UNDEFINED;                                                           \
447
0
  }
Unexecuted instantiation: elf_rva_to_offset_32_le
Unexecuted instantiation: elf_rva_to_offset_64_le
Unexecuted instantiation: elf_rva_to_offset_32_be
Unexecuted instantiation: elf_rva_to_offset_64_be
448
449
#define PARSE_ELF_HEADER(bits, bo)                                                        \
450
  int parse_elf_header_##bits##_##bo(                                                     \
451
      ELF* elf_data,                                                                      \
452
      elf##bits##_header_t* elf,                                                          \
453
      uint64_t base_address,                                                              \
454
      size_t elf_size,                                                                    \
455
      int flags,                                                                          \
456
      YR_OBJECT* elf_obj)                                                                 \
457
0
  {                                                                                       \
458
0
    unsigned int i, j, m;                                                                 \
459
0
    const char* elf_raw = (const char*) elf;                                              \
460
0
    uint16_t str_table_index = yr_##bo##16toh(elf->sh_str_table_index);                   \
461
0
                                                                                          \
462
0
    const char* sym_table = NULL;                                                         \
463
0
    const char* sym_str_table = NULL;                                                     \
464
0
    const char* dyn_sym_table = NULL;                                                     \
465
0
    const char* dyn_sym_str_table = NULL;                                                 \
466
0
                                                                                          \
467
0
    uint##bits##_t sym_table_size = 0;                                                    \
468
0
    uint##bits##_t sym_str_table_size = 0;                                                \
469
0
    uint##bits##_t dyn_sym_table_size = 0;                                                \
470
0
    uint##bits##_t dyn_sym_str_table_size = 0;                                            \
471
0
                                                                                          \
472
0
    elf_data->symtab = elf_data->dynsym = NULL;                                           \
473
0
                                                                                          \
474
0
    elf##bits##_section_header_t* section_table;                                          \
475
0
    elf##bits##_section_header_t* section;                                                \
476
0
    elf##bits##_program_header_t* segment;                                                \
477
0
                                                                                          \
478
0
    yr_set_integer(yr_##bo##16toh(elf->type), elf_obj, "type");                           \
479
0
    yr_set_integer(yr_##bo##16toh(elf->machine), elf_obj, "machine");                     \
480
0
    yr_set_integer(yr_##bo##bits##toh(elf->sh_offset), elf_obj, "sh_offset");             \
481
0
    yr_set_integer(                                                                       \
482
0
        yr_##bo##16toh(elf->sh_entry_size), elf_obj, "sh_entry_size");                    \
483
0
    yr_set_integer(                                                                       \
484
0
        yr_##bo##16toh(elf->sh_entry_count), elf_obj, "number_of_sections");              \
485
0
    yr_set_integer(yr_##bo##bits##toh(elf->ph_offset), elf_obj, "ph_offset");             \
486
0
    yr_set_integer(                                                                       \
487
0
        yr_##bo##16toh(elf->ph_entry_size), elf_obj, "ph_entry_size");                    \
488
0
    yr_set_integer(                                                                       \
489
0
        yr_##bo##16toh(elf->ph_entry_count), elf_obj, "number_of_segments");              \
490
0
                                                                                          \
491
0
    if (yr_##bo##bits##toh(elf->entry) != 0)                                              \
492
0
    {                                                                                     \
493
0
      yr_set_integer(                                                                     \
494
0
          flags& SCAN_FLAGS_PROCESS_MEMORY                                                \
495
0
              ? base_address + yr_##bo##bits##toh(elf->entry)                             \
496
0
              : elf_rva_to_offset_##bits##_##bo(                                          \
497
0
                    elf, yr_##bo##bits##toh(elf->entry), elf_size),                       \
498
0
          elf_obj,                                                                        \
499
0
          "entry_point");                                                                 \
500
0
    }                                                                                     \
501
0
                                                                                          \
502
0
    if (yr_##bo##16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&                        \
503
0
        str_table_index < yr_##bo##16toh(elf->sh_entry_count) &&                          \
504
0
        yr_##bo##bits##toh(elf->sh_offset) < elf_size &&                                  \
505
0
        yr_##bo##bits##toh(elf->sh_offset) +                                              \
506
0
                yr_##bo##16toh(elf->sh_entry_count) *                                     \
507
0
                    sizeof(elf##bits##_section_header_t) <=                               \
508
0
            elf_size)                                                                     \
509
0
    {                                                                                     \
510
0
      const char* str_table = NULL;                                                       \
511
0
                                                                                          \
512
0
      section_table =                                                                     \
513
0
          (elf##bits##_section_header_t*) (elf_raw + yr_##bo##bits##toh(elf->sh_offset)); \
514
0
                                                                                          \
515
0
      if (yr_##bo##bits##toh(section_table[str_table_index].offset) <                     \
516
0
          elf_size)                                                                       \
517
0
      {                                                                                   \
518
0
        str_table = elf_raw +                                                             \
519
0
                    yr_##bo##bits##toh(section_table[str_table_index].offset);            \
520
0
      }                                                                                   \
521
0
                                                                                          \
522
0
      section = section_table;                                                            \
523
0
                                                                                          \
524
0
      for (i = 0; i < yr_##bo##16toh(elf->sh_entry_count); i++, section++)                \
525
0
      {                                                                                   \
526
0
        yr_set_integer(                                                                   \
527
0
            yr_##bo##32toh(section->type), elf_obj, "sections[%i].type", i);              \
528
0
        yr_set_integer(                                                                   \
529
0
            yr_##bo##bits##toh(section->flags),                                           \
530
0
            elf_obj,                                                                      \
531
0
            "sections[%i].flags",                                                         \
532
0
            i);                                                                           \
533
0
        yr_set_integer(                                                                   \
534
0
            yr_##bo##bits##toh(section->addr),                                            \
535
0
            elf_obj,                                                                      \
536
0
            "sections[%i].address",                                                       \
537
0
            i);                                                                           \
538
0
        yr_set_integer(                                                                   \
539
0
            yr_##bo##bits##toh(section->size),                                            \
540
0
            elf_obj,                                                                      \
541
0
            "sections[%i].size",                                                          \
542
0
            i);                                                                           \
543
0
        yr_set_integer(                                                                   \
544
0
            yr_##bo##bits##toh(section->offset),                                          \
545
0
            elf_obj,                                                                      \
546
0
            "sections[%i].offset",                                                        \
547
0
            i);                                                                           \
548
0
                                                                                          \
549
0
        if (yr_##bo##32toh(section->name) < elf_size && str_table > elf_raw)              \
550
0
        {                                                                                 \
551
0
          const char* section_name = str_table_entry(                                     \
552
0
              str_table, elf_raw + elf_size, yr_##bo##32toh(section->name));              \
553
0
                                                                                          \
554
0
          if (section_name)                                                               \
555
0
            yr_set_string(section_name, elf_obj, "sections[%i].name", i);                 \
556
0
        }                                                                                 \
557
0
                                                                                          \
558
0
        if (yr_##bo##32toh(section->type) == ELF_SHT_SYMTAB &&                            \
559
0
            yr_##bo##32toh(section->link) < elf->sh_entry_count)                          \
560
0
        {                                                                                 \
561
0
          elf##bits##_section_header_t* string_section = section_table +                  \
562
0
                                                         yr_##bo##32toh(                  \
563
0
                                                             section->link);              \
564
0
                                                                                          \
565
0
          if (IS_VALID_PTR(elf, elf_size, string_section) &&                              \
566
0
              yr_##bo##32toh(string_section->type) == ELF_SHT_STRTAB)                     \
567
0
          {                                                                               \
568
0
            sym_table = elf_raw + yr_##bo##bits##toh(section->offset);                    \
569
0
            sym_str_table = elf_raw +                                                     \
570
0
                            yr_##bo##bits##toh(string_section->offset);                   \
571
0
            sym_table_size = yr_##bo##bits##toh(section->size);                           \
572
0
            sym_str_table_size = yr_##bo##bits##toh(string_section->size);                \
573
0
          }                                                                               \
574
0
        }                                                                                 \
575
0
                                                                                          \
576
0
        if (yr_##bo##32toh(section->type) == ELF_SHT_DYNSYM &&                            \
577
0
            yr_##bo##32toh(section->link) < elf->sh_entry_count)                          \
578
0
        {                                                                                 \
579
0
          elf##bits##_section_header_t* dynstr_section = section_table +                  \
580
0
                                                         yr_##bo##32toh(                  \
581
0
                                                             section->link);              \
582
0
                                                                                          \
583
0
          if (IS_VALID_PTR(elf, elf_size, dynstr_section) &&                              \
584
0
              yr_##bo##32toh(dynstr_section->type) == ELF_SHT_STRTAB)                     \
585
0
          {                                                                               \
586
0
            dyn_sym_table = elf_raw + yr_##bo##bits##toh(section->offset);                \
587
0
            dyn_sym_str_table = elf_raw +                                                 \
588
0
                                yr_##bo##bits##toh(dynstr_section->offset);               \
589
0
            dyn_sym_table_size = yr_##bo##bits##toh(section->size);                       \
590
0
            dyn_sym_str_table_size = yr_##bo##bits##toh(dynstr_section->size);            \
591
0
          }                                                                               \
592
0
        }                                                                                 \
593
0
      }                                                                                   \
594
0
                                                                                          \
595
0
      if (is_valid_ptr(elf, elf_size, sym_str_table, sym_str_table_size) &&               \
596
0
          is_valid_ptr(elf, elf_size, sym_table, sym_table_size))                         \
597
0
      {                                                                                   \
598
0
        elf##bits##_sym_t* sym = (elf##bits##_sym_t*) sym_table;                          \
599
0
        elf_data->symtab = (ELF_SYMBOL_LIST*) yr_malloc(                                  \
600
0
            sizeof(ELF_SYMBOL_LIST));                                                     \
601
0
                                                                                          \
602
0
        if (elf_data->symtab == NULL)                                                     \
603
0
          return ERROR_INSUFFICIENT_MEMORY;                                               \
604
0
                                                                                          \
605
0
        ELF_SYMBOL** symbol = &(elf_data->symtab->symbols);                               \
606
0
        *symbol = NULL;                                                                   \
607
0
                                                                                          \
608
0
        for (j = 0; j < sym_table_size / sizeof(elf##bits##_sym_t);                       \
609
0
             j++, sym++)                                                                  \
610
0
        {                                                                                 \
611
0
          *symbol = (ELF_SYMBOL*) yr_malloc(sizeof(ELF_SYMBOL));                          \
612
0
          if (*symbol == NULL)                                                            \
613
0
            return ERROR_INSUFFICIENT_MEMORY;                                             \
614
0
                                                                                          \
615
0
          (*symbol)->name = NULL;                                                         \
616
0
          (*symbol)->next = NULL;                                                         \
617
0
                                                                                          \
618
0
          const char* sym_name = str_table_entry(                                         \
619
0
              sym_str_table,                                                              \
620
0
              sym_str_table + sym_str_table_size,                                         \
621
0
              yr_##bo##32toh(sym->name));                                                 \
622
0
                                                                                          \
623
0
          if (sym_name)                                                                   \
624
0
          {                                                                               \
625
0
            yr_set_string(sym_name, elf_obj, "symtab[%i].name", j);                       \
626
0
            (*symbol)->name = (char*) yr_malloc(strlen(sym_name) + 1);                    \
627
0
            if ((*symbol)->name == NULL)                                                  \
628
0
              return ERROR_INSUFFICIENT_MEMORY;                                           \
629
0
                                                                                          \
630
0
            strcpy((*symbol)->name, sym_name);                                            \
631
0
          }                                                                               \
632
0
                                                                                          \
633
0
          int bind = sym->info >> 4;                                                      \
634
0
          (*symbol)->bind = bind;                                                         \
635
0
          yr_set_integer(bind, elf_obj, "symtab[%i].bind", j);                            \
636
0
                                                                                          \
637
0
          int type = sym->info & 0xf;                                                     \
638
0
          (*symbol)->type = type;                                                         \
639
0
          yr_set_integer(type, elf_obj, "symtab[%i].type", j);                            \
640
0
                                                                                          \
641
0
          int shndx = yr_##bo##16toh(sym->shndx);                                         \
642
0
          (*symbol)->shndx = shndx;                                                       \
643
0
          yr_set_integer(shndx, elf_obj, "symtab[%i].shndx", j);                          \
644
0
                                                                                          \
645
0
          int value = yr_##bo##bits##toh(sym->value);                                     \
646
0
          (*symbol)->value = value;                                                       \
647
0
          yr_set_integer(                                                                 \
648
0
              yr_##bo##bits##toh(sym->value), elf_obj, "symtab[%i].value", j);            \
649
0
                                                                                          \
650
0
          int size = yr_##bo##bits##toh(sym->size);                                       \
651
0
          (*symbol)->size = size;                                                         \
652
0
          yr_set_integer(                                                                 \
653
0
              yr_##bo##bits##toh(sym->size), elf_obj, "symtab[%i].size", j);              \
654
0
                                                                                          \
655
0
          (*symbol)->visibility = sym->other & 0x3;                                       \
656
0
                                                                                          \
657
0
          symbol = &((*symbol)->next);                                                    \
658
0
        }                                                                                 \
659
0
                                                                                          \
660
0
        elf_data->symtab->count = j;                                                      \
661
0
        yr_set_integer(j, elf_obj, "symtab_entries");                                     \
662
0
      }                                                                                   \
663
0
                                                                                          \
664
0
      if (is_valid_ptr(                                                                   \
665
0
              elf, elf_size, dyn_sym_str_table, dyn_sym_str_table_size) &&                \
666
0
          is_valid_ptr(elf, elf_size, dyn_sym_table, dyn_sym_table_size))                 \
667
0
      {                                                                                   \
668
0
        elf##bits##_sym_t* dynsym = (elf##bits##_sym_t*) dyn_sym_table;                   \
669
0
                                                                                          \
670
0
        elf_data->dynsym = (ELF_SYMBOL_LIST*) yr_malloc(                                  \
671
0
            sizeof(ELF_SYMBOL_LIST));                                                     \
672
0
                                                                                          \
673
0
        if (elf_data->dynsym == NULL)                                                     \
674
0
          return ERROR_INSUFFICIENT_MEMORY;                                               \
675
0
                                                                                          \
676
0
        ELF_SYMBOL** symbol = &(elf_data->dynsym->symbols);                               \
677
0
        *symbol = NULL;                                                                   \
678
0
                                                                                          \
679
0
        for (m = 0; m < dyn_sym_table_size / sizeof(elf##bits##_sym_t);                   \
680
0
             m++, dynsym++)                                                               \
681
0
        {                                                                                 \
682
0
          *symbol = (ELF_SYMBOL*) yr_malloc(sizeof(ELF_SYMBOL));                          \
683
0
          if (*symbol == NULL)                                                            \
684
0
            return ERROR_INSUFFICIENT_MEMORY;                                             \
685
0
                                                                                          \
686
0
          (*symbol)->name = NULL;                                                         \
687
0
          (*symbol)->next = NULL;                                                         \
688
0
                                                                                          \
689
0
          const char* dynsym_name = str_table_entry(                                      \
690
0
              dyn_sym_str_table,                                                          \
691
0
              dyn_sym_str_table + dyn_sym_str_table_size,                                 \
692
0
              yr_##bo##32toh(dynsym->name));                                              \
693
0
                                                                                          \
694
0
          if (dynsym_name)                                                                \
695
0
          {                                                                               \
696
0
            yr_set_string(dynsym_name, elf_obj, "dynsym[%i].name", m);                    \
697
0
            (*symbol)->name = (char*) yr_malloc(strlen(dynsym_name) + 1);                 \
698
0
            if ((*symbol)->name == NULL)                                                  \
699
0
              return ERROR_INSUFFICIENT_MEMORY;                                           \
700
0
                                                                                          \
701
0
            strcpy((*symbol)->name, dynsym_name);                                         \
702
0
          }                                                                               \
703
0
                                                                                          \
704
0
          int bind = dynsym->info >> 4;                                                   \
705
0
          (*symbol)->bind = bind;                                                         \
706
0
          yr_set_integer(dynsym->info >> 4, elf_obj, "dynsym[%i].bind", m);               \
707
0
                                                                                          \
708
0
          int type = dynsym->info & 0xf;                                                  \
709
0
          (*symbol)->type = type;                                                         \
710
0
          yr_set_integer(dynsym->info & 0xf, elf_obj, "dynsym[%i].type", m);              \
711
0
                                                                                          \
712
0
          int shndx = yr_##bo##16toh(dynsym->shndx);                                      \
713
0
          (*symbol)->shndx = shndx;                                                       \
714
0
          yr_set_integer(                                                                 \
715
0
              yr_##bo##16toh(dynsym->shndx), elf_obj, "dynsym[%i].shndx", m);             \
716
0
                                                                                          \
717
0
          int value = yr_##bo##bits##toh(dynsym->value);                                  \
718
0
          (*symbol)->value = value;                                                       \
719
0
          yr_set_integer(                                                                 \
720
0
              yr_##bo##bits##toh(dynsym->value),                                          \
721
0
              elf_obj,                                                                    \
722
0
              "dynsym[%i].value",                                                         \
723
0
              m);                                                                         \
724
0
                                                                                          \
725
0
          int size = yr_##bo##bits##toh(dynsym->size);                                    \
726
0
          (*symbol)->size = size;                                                         \
727
0
          yr_set_integer(                                                                 \
728
0
              yr_##bo##bits##toh(dynsym->size),                                           \
729
0
              elf_obj,                                                                    \
730
0
              "dynsym[%i].size",                                                          \
731
0
              m);                                                                         \
732
0
                                                                                          \
733
0
          (*symbol)->visibility = dynsym->other & 0x3;                                    \
734
0
                                                                                          \
735
0
          symbol = &((*symbol)->next);                                                    \
736
0
        }                                                                                 \
737
0
                                                                                          \
738
0
        elf_data->dynsym->count = m;                                                      \
739
0
        yr_set_integer(m, elf_obj, "dynsym_entries");                                     \
740
0
      }                                                                                   \
741
0
    }                                                                                     \
742
0
                                                                                          \
743
0
    if (yr_##bo##16toh(elf->ph_entry_count) > 0 &&                                        \
744
0
        yr_##bo##16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                              \
745
0
        yr_##bo##bits##toh(elf->ph_offset) < elf_size &&                                  \
746
0
        yr_##bo##bits##toh(elf->ph_offset) +                                              \
747
0
                yr_##bo##16toh(elf->ph_entry_count) *                                     \
748
0
                    sizeof(elf##bits##_program_header_t) <=                               \
749
0
            elf_size)                                                                     \
750
0
    {                                                                                     \
751
0
      segment =                                                                           \
752
0
          (elf##bits##_program_header_t*) (elf_raw + yr_##bo##bits##toh(elf->ph_offset)); \
753
0
                                                                                          \
754
0
      for (i = 0; i < yr_##bo##16toh(elf->ph_entry_count); i++, segment++)                \
755
0
      {                                                                                   \
756
0
        yr_set_integer(                                                                   \
757
0
            yr_##bo##32toh(segment->type), elf_obj, "segments[%i].type", i);              \
758
0
        yr_set_integer(                                                                   \
759
0
            yr_##bo##32toh(segment->flags), elf_obj, "segments[%i].flags", i);            \
760
0
        yr_set_integer(                                                                   \
761
0
            yr_##bo##bits##toh(segment->offset),                                          \
762
0
            elf_obj,                                                                      \
763
0
            "segments[%i].offset",                                                        \
764
0
            i);                                                                           \
765
0
        yr_set_integer(                                                                   \
766
0
            yr_##bo##bits##toh(segment->virt_addr),                                       \
767
0
            elf_obj,                                                                      \
768
0
            "segments[%i].virtual_address",                                               \
769
0
            i);                                                                           \
770
0
        yr_set_integer(                                                                   \
771
0
            yr_##bo##bits##toh(segment->phys_addr),                                       \
772
0
            elf_obj,                                                                      \
773
0
            "segments[%i].physical_address",                                              \
774
0
            i);                                                                           \
775
0
        yr_set_integer(                                                                   \
776
0
            yr_##bo##bits##toh(segment->file_size),                                       \
777
0
            elf_obj,                                                                      \
778
0
            "segments[%i].file_size",                                                     \
779
0
            i);                                                                           \
780
0
        yr_set_integer(                                                                   \
781
0
            yr_##bo##bits##toh(segment->mem_size),                                        \
782
0
            elf_obj,                                                                      \
783
0
            "segments[%i].memory_size",                                                   \
784
0
            i);                                                                           \
785
0
        yr_set_integer(                                                                   \
786
0
            yr_##bo##bits##toh(segment->alignment),                                       \
787
0
            elf_obj,                                                                      \
788
0
            "segments[%i].alignment",                                                     \
789
0
            i);                                                                           \
790
0
                                                                                          \
791
0
        if (yr_##bo##32toh(segment->type) == ELF_PT_DYNAMIC)                              \
792
0
        {                                                                                 \
793
0
          elf##bits##_dyn_t* dyn =                                                        \
794
0
              (elf##bits##_dyn_t*) (elf_raw + yr_##bo##bits##toh(segment->offset));       \
795
0
                                                                                          \
796
0
          for (j = 0; IS_VALID_PTR(elf, elf_size, dyn); dyn++, j++)                       \
797
0
          {                                                                               \
798
0
            yr_set_integer(                                                               \
799
0
                yr_##bo##bits##toh(dyn->tag), elf_obj, "dynamic[%i].type", j);            \
800
0
            yr_set_integer(                                                               \
801
0
                yr_##bo##bits##toh(dyn->val), elf_obj, "dynamic[%i].val", j);             \
802
0
                                                                                          \
803
0
            if (dyn->tag == ELF_DT_NULL)                                                  \
804
0
            {                                                                             \
805
0
              j++;                                                                        \
806
0
              break;                                                                      \
807
0
            }                                                                             \
808
0
          }                                                                               \
809
0
          yr_set_integer(j, elf_obj, "dynamic_section_entries");                          \
810
0
        }                                                                                 \
811
0
      }                                                                                   \
812
0
    }                                                                                     \
813
0
    return ERROR_SUCCESS;                                                                 \
814
0
  }
Unexecuted instantiation: parse_elf_header_32_le
Unexecuted instantiation: parse_elf_header_64_le
Unexecuted instantiation: parse_elf_header_32_be
Unexecuted instantiation: parse_elf_header_64_be
815
816
ELF_RVA_TO_OFFSET(32, le);
817
ELF_RVA_TO_OFFSET(64, le);
818
ELF_RVA_TO_OFFSET(32, be);
819
ELF_RVA_TO_OFFSET(64, be);
820
821
PARSE_ELF_HEADER(32, le);
822
PARSE_ELF_HEADER(64, le);
823
PARSE_ELF_HEADER(32, be);
824
PARSE_ELF_HEADER(64, be);
825
826
5
begin_declarations
827
5
  declare_integer("ET_NONE");
828
5
  declare_integer("ET_REL");
829
5
  declare_integer("ET_EXEC");
830
5
  declare_integer("ET_DYN");
831
5
  declare_integer("ET_CORE");
832
833
5
  declare_integer("EM_NONE");
834
5
  declare_integer("EM_M32");
835
5
  declare_integer("EM_SPARC");
836
5
  declare_integer("EM_386");
837
5
  declare_integer("EM_68K");
838
5
  declare_integer("EM_88K");
839
5
  declare_integer("EM_860");
840
5
  declare_integer("EM_MIPS");
841
5
  declare_integer("EM_MIPS_RS3_LE");
842
5
  declare_integer("EM_PPC");
843
5
  declare_integer("EM_PPC64");
844
5
  declare_integer("EM_ARM");
845
5
  declare_integer("EM_X86_64");
846
5
  declare_integer("EM_AARCH64");
847
848
5
  declare_integer("SHT_NULL");
849
5
  declare_integer("SHT_PROGBITS");
850
5
  declare_integer("SHT_SYMTAB");
851
5
  declare_integer("SHT_STRTAB");
852
5
  declare_integer("SHT_RELA");
853
5
  declare_integer("SHT_HASH");
854
5
  declare_integer("SHT_DYNAMIC");
855
5
  declare_integer("SHT_NOTE");
856
5
  declare_integer("SHT_NOBITS");
857
5
  declare_integer("SHT_REL");
858
5
  declare_integer("SHT_SHLIB");
859
5
  declare_integer("SHT_DYNSYM");
860
861
5
  declare_integer("SHF_WRITE");
862
5
  declare_integer("SHF_ALLOC");
863
5
  declare_integer("SHF_EXECINSTR");
864
865
5
  declare_integer("type");
866
5
  declare_integer("machine");
867
5
  declare_integer("entry_point");
868
869
5
  declare_integer("number_of_sections");
870
5
  declare_integer("sh_offset");
871
5
  declare_integer("sh_entry_size");
872
873
5
  declare_integer("number_of_segments");
874
5
  declare_integer("ph_offset");
875
5
  declare_integer("ph_entry_size");
876
877
15
  begin_struct_array("sections")
878
5
    declare_integer("type");
879
5
    declare_integer("flags");
880
5
    declare_integer("address");
881
5
    declare_string("name");
882
5
    declare_integer("size");
883
5
    declare_integer("offset");
884
10
  end_struct_array("sections")
885
886
5
  declare_integer("PT_NULL");
887
5
  declare_integer("PT_LOAD");
888
5
  declare_integer("PT_DYNAMIC");
889
5
  declare_integer("PT_INTERP");
890
5
  declare_integer("PT_NOTE");
891
5
  declare_integer("PT_SHLIB");
892
5
  declare_integer("PT_PHDR");
893
5
  declare_integer("PT_TLS");
894
5
  declare_integer("PT_GNU_EH_FRAME");
895
5
  declare_integer("PT_GNU_STACK");
896
897
5
  declare_integer("DT_NULL");
898
5
  declare_integer("DT_NEEDED");
899
5
  declare_integer("DT_PLTRELSZ");
900
5
  declare_integer("DT_PLTGOT");
901
5
  declare_integer("DT_HASH");
902
5
  declare_integer("DT_STRTAB");
903
5
  declare_integer("DT_SYMTAB");
904
5
  declare_integer("DT_RELA");
905
5
  declare_integer("DT_RELASZ");
906
5
  declare_integer("DT_RELAENT");
907
5
  declare_integer("DT_STRSZ");
908
5
  declare_integer("DT_SYMENT");
909
5
  declare_integer("DT_INIT");
910
5
  declare_integer("DT_FINI");
911
5
  declare_integer("DT_SONAME");
912
5
  declare_integer("DT_RPATH");
913
5
  declare_integer("DT_SYMBOLIC");
914
5
  declare_integer("DT_REL");
915
5
  declare_integer("DT_RELSZ");
916
5
  declare_integer("DT_RELENT");
917
5
  declare_integer("DT_PLTREL");
918
5
  declare_integer("DT_DEBUG");
919
5
  declare_integer("DT_TEXTREL");
920
5
  declare_integer("DT_JMPREL");
921
5
  declare_integer("DT_BIND_NOW");
922
5
  declare_integer("DT_INIT_ARRAY");
923
5
  declare_integer("DT_FINI_ARRAY");
924
5
  declare_integer("DT_INIT_ARRAYSZ");
925
5
  declare_integer("DT_FINI_ARRAYSZ");
926
5
  declare_integer("DT_RUNPATH");
927
5
  declare_integer("DT_FLAGS");
928
5
  declare_integer("DT_ENCODING");
929
930
5
  declare_integer("STT_NOTYPE");
931
5
  declare_integer("STT_OBJECT");
932
5
  declare_integer("STT_FUNC");
933
5
  declare_integer("STT_SECTION");
934
5
  declare_integer("STT_FILE");
935
5
  declare_integer("STT_COMMON");
936
5
  declare_integer("STT_TLS");
937
938
5
  declare_integer("STB_LOCAL");
939
5
  declare_integer("STB_GLOBAL");
940
5
  declare_integer("STB_WEAK");
941
942
5
  declare_integer("PF_X");
943
5
  declare_integer("PF_W");
944
5
  declare_integer("PF_R");
945
946
15
  begin_struct_array("segments")
947
5
    declare_integer("type");
948
5
    declare_integer("flags");
949
5
    declare_integer("offset");
950
5
    declare_integer("virtual_address");
951
5
    declare_integer("physical_address");
952
5
    declare_integer("file_size");
953
5
    declare_integer("memory_size");
954
5
    declare_integer("alignment");
955
10
  end_struct_array("segments")
956
957
5
  declare_integer("dynamic_section_entries");
958
15
  begin_struct_array("dynamic")
959
5
    declare_integer("type");
960
5
    declare_integer("val");
961
10
  end_struct_array("dynamic")
962
963
5
  declare_integer("symtab_entries");
964
15
  begin_struct_array("symtab")
965
5
    declare_string("name");
966
5
    declare_integer("value");
967
5
    declare_integer("size");
968
5
    declare_integer("type");
969
5
    declare_integer("bind");
970
5
    declare_integer("shndx");
971
10
  end_struct_array("symtab")
972
973
5
  declare_integer("dynsym_entries");
974
15
  begin_struct_array("dynsym")
975
5
    declare_string("name");
976
5
    declare_integer("value");
977
5
    declare_integer("size");
978
5
    declare_integer("type");
979
5
    declare_integer("bind");
980
5
    declare_integer("shndx");
981
10
  end_struct_array("dynsym")
982
983
5
  declare_function("telfhash", "", "s", telfhash);
984
985
#if defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H) || \
986
    defined(HAVE_COMMONCRYPTO_COMMONCRYPTO_H)
987
  declare_function("import_md5", "", "s", import_md5);
988
#endif  // defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H)
989
990
5
end_declarations
991
992
int module_initialize(YR_MODULE* module)
993
2
{
994
2
  return ERROR_SUCCESS;
995
2
}
996
997
int module_finalize(YR_MODULE* module)
998
0
{
999
0
  return ERROR_SUCCESS;
1000
0
}
1001
1002
int module_load(
1003
    YR_SCAN_CONTEXT* context,
1004
    YR_OBJECT* module_object,
1005
    void* module_data,
1006
    size_t module_data_size)
1007
0
{
1008
0
  YR_MEMORY_BLOCK* block;
1009
0
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1010
1011
0
  elf32_header_t* elf_header32;
1012
0
  elf64_header_t* elf_header64;
1013
1014
0
  yr_set_integer(ELF_ET_NONE, module_object, "ET_NONE");
1015
0
  yr_set_integer(ELF_ET_REL, module_object, "ET_REL");
1016
0
  yr_set_integer(ELF_ET_EXEC, module_object, "ET_EXEC");
1017
0
  yr_set_integer(ELF_ET_DYN, module_object, "ET_DYN");
1018
0
  yr_set_integer(ELF_ET_CORE, module_object, "ET_CORE");
1019
1020
0
  yr_set_integer(ELF_EM_NONE, module_object, "EM_NONE");
1021
0
  yr_set_integer(ELF_EM_M32, module_object, "EM_M32");
1022
0
  yr_set_integer(ELF_EM_SPARC, module_object, "EM_SPARC");
1023
0
  yr_set_integer(ELF_EM_386, module_object, "EM_386");
1024
0
  yr_set_integer(ELF_EM_68K, module_object, "EM_68K");
1025
0
  yr_set_integer(ELF_EM_88K, module_object, "EM_88K");
1026
0
  yr_set_integer(ELF_EM_860, module_object, "EM_860");
1027
0
  yr_set_integer(ELF_EM_MIPS, module_object, "EM_MIPS");
1028
0
  yr_set_integer(ELF_EM_MIPS_RS3_LE, module_object, "EM_MIPS_RS3_LE");
1029
0
  yr_set_integer(ELF_EM_PPC, module_object, "EM_PPC");
1030
0
  yr_set_integer(ELF_EM_PPC64, module_object, "EM_PPC64");
1031
0
  yr_set_integer(ELF_EM_ARM, module_object, "EM_ARM");
1032
0
  yr_set_integer(ELF_EM_X86_64, module_object, "EM_X86_64");
1033
0
  yr_set_integer(ELF_EM_AARCH64, module_object, "EM_AARCH64");
1034
1035
0
  yr_set_integer(ELF_SHT_NULL, module_object, "SHT_NULL");
1036
0
  yr_set_integer(ELF_SHT_PROGBITS, module_object, "SHT_PROGBITS");
1037
0
  yr_set_integer(ELF_SHT_SYMTAB, module_object, "SHT_SYMTAB");
1038
0
  yr_set_integer(ELF_SHT_STRTAB, module_object, "SHT_STRTAB");
1039
0
  yr_set_integer(ELF_SHT_RELA, module_object, "SHT_RELA");
1040
0
  yr_set_integer(ELF_SHT_HASH, module_object, "SHT_HASH");
1041
0
  yr_set_integer(ELF_SHT_DYNAMIC, module_object, "SHT_DYNAMIC");
1042
0
  yr_set_integer(ELF_SHT_NOTE, module_object, "SHT_NOTE");
1043
0
  yr_set_integer(ELF_SHT_NOBITS, module_object, "SHT_NOBITS");
1044
0
  yr_set_integer(ELF_SHT_REL, module_object, "SHT_REL");
1045
0
  yr_set_integer(ELF_SHT_SHLIB, module_object, "SHT_SHLIB");
1046
0
  yr_set_integer(ELF_SHT_DYNSYM, module_object, "SHT_DYNSYM");
1047
1048
0
  yr_set_integer(ELF_SHF_WRITE, module_object, "SHF_WRITE");
1049
0
  yr_set_integer(ELF_SHF_ALLOC, module_object, "SHF_ALLOC");
1050
0
  yr_set_integer(ELF_SHF_EXECINSTR, module_object, "SHF_EXECINSTR");
1051
1052
0
  yr_set_integer(ELF_PT_NULL, module_object, "PT_NULL");
1053
0
  yr_set_integer(ELF_PT_LOAD, module_object, "PT_LOAD");
1054
0
  yr_set_integer(ELF_PT_DYNAMIC, module_object, "PT_DYNAMIC");
1055
0
  yr_set_integer(ELF_PT_INTERP, module_object, "PT_INTERP");
1056
0
  yr_set_integer(ELF_PT_NOTE, module_object, "PT_NOTE");
1057
0
  yr_set_integer(ELF_PT_SHLIB, module_object, "PT_SHLIB");
1058
0
  yr_set_integer(ELF_PT_PHDR, module_object, "PT_PHDR");
1059
0
  yr_set_integer(ELF_PT_TLS, module_object, "PT_TLS");
1060
0
  yr_set_integer(ELF_PT_GNU_EH_FRAME, module_object, "PT_GNU_EH_FRAME");
1061
0
  yr_set_integer(ELF_PT_GNU_STACK, module_object, "PT_GNU_STACK");
1062
1063
0
  yr_set_integer(ELF_DT_NULL, module_object, "DT_NULL");
1064
0
  yr_set_integer(ELF_DT_NEEDED, module_object, "DT_NEEDED");
1065
0
  yr_set_integer(ELF_DT_PLTRELSZ, module_object, "DT_PLTRELSZ");
1066
0
  yr_set_integer(ELF_DT_PLTGOT, module_object, "DT_PLTGOT");
1067
0
  yr_set_integer(ELF_DT_HASH, module_object, "DT_HASH");
1068
0
  yr_set_integer(ELF_DT_STRTAB, module_object, "DT_STRTAB");
1069
0
  yr_set_integer(ELF_DT_SYMTAB, module_object, "DT_SYMTAB");
1070
0
  yr_set_integer(ELF_DT_RELA, module_object, "DT_RELA");
1071
0
  yr_set_integer(ELF_DT_RELASZ, module_object, "DT_RELASZ");
1072
0
  yr_set_integer(ELF_DT_RELAENT, module_object, "DT_RELAENT");
1073
0
  yr_set_integer(ELF_DT_STRSZ, module_object, "DT_STRSZ");
1074
0
  yr_set_integer(ELF_DT_SYMENT, module_object, "DT_SYMENT");
1075
0
  yr_set_integer(ELF_DT_INIT, module_object, "DT_INIT");
1076
0
  yr_set_integer(ELF_DT_FINI, module_object, "DT_FINI");
1077
0
  yr_set_integer(ELF_DT_SONAME, module_object, "DT_SONAME");
1078
0
  yr_set_integer(ELF_DT_RPATH, module_object, "DT_RPATH");
1079
0
  yr_set_integer(ELF_DT_SYMBOLIC, module_object, "DT_SYMBOLIC");
1080
0
  yr_set_integer(ELF_DT_REL, module_object, "DT_REL");
1081
0
  yr_set_integer(ELF_DT_RELSZ, module_object, "DT_RELSZ");
1082
0
  yr_set_integer(ELF_DT_RELENT, module_object, "DT_RELENT");
1083
0
  yr_set_integer(ELF_DT_PLTREL, module_object, "DT_PLTREL");
1084
0
  yr_set_integer(ELF_DT_DEBUG, module_object, "DT_DEBUG");
1085
0
  yr_set_integer(ELF_DT_TEXTREL, module_object, "DT_TEXTREL");
1086
0
  yr_set_integer(ELF_DT_JMPREL, module_object, "DT_JMPREL");
1087
0
  yr_set_integer(ELF_DT_BIND_NOW, module_object, "DT_BIND_NOW");
1088
0
  yr_set_integer(ELF_DT_INIT_ARRAY, module_object, "DT_INIT_ARRAY");
1089
0
  yr_set_integer(ELF_DT_FINI_ARRAY, module_object, "DT_FINI_ARRAY");
1090
0
  yr_set_integer(ELF_DT_INIT_ARRAYSZ, module_object, "DT_INIT_ARRAYSZ");
1091
0
  yr_set_integer(ELF_DT_FINI_ARRAYSZ, module_object, "DT_FINI_ARRAYSZ");
1092
0
  yr_set_integer(ELF_DT_RUNPATH, module_object, "DT_RUNPATH");
1093
0
  yr_set_integer(ELF_DT_FLAGS, module_object, "DT_FLAGS");
1094
0
  yr_set_integer(ELF_DT_ENCODING, module_object, "DT_ENCODING");
1095
1096
0
  yr_set_integer(ELF_STT_NOTYPE, module_object, "STT_NOTYPE");
1097
0
  yr_set_integer(ELF_STT_OBJECT, module_object, "STT_OBJECT");
1098
0
  yr_set_integer(ELF_STT_FUNC, module_object, "STT_FUNC");
1099
0
  yr_set_integer(ELF_STT_SECTION, module_object, "STT_SECTION");
1100
0
  yr_set_integer(ELF_STT_FILE, module_object, "STT_FILE");
1101
0
  yr_set_integer(ELF_STT_COMMON, module_object, "STT_COMMON");
1102
0
  yr_set_integer(ELF_STT_TLS, module_object, "STT_TLS");
1103
1104
0
  yr_set_integer(ELF_STB_LOCAL, module_object, "STB_LOCAL");
1105
0
  yr_set_integer(ELF_STB_GLOBAL, module_object, "STB_GLOBAL");
1106
0
  yr_set_integer(ELF_STB_WEAK, module_object, "STB_WEAK");
1107
1108
0
  yr_set_integer(ELF_PF_X, module_object, "PF_X");
1109
0
  yr_set_integer(ELF_PF_W, module_object, "PF_W");
1110
0
  yr_set_integer(ELF_PF_R, module_object, "PF_R");
1111
1112
0
  uint64_t parse_result = ERROR_SUCCESS;
1113
1114
0
  foreach_memory_block(iterator, block)
1115
0
  {
1116
0
    const uint8_t* block_data = block->fetch_data(block);
1117
1118
0
    if (block_data == NULL)
1119
0
      continue;
1120
1121
0
    ELF* elf = (ELF*) yr_calloc(1, sizeof(ELF));
1122
0
    if (elf == NULL)
1123
0
      return ERROR_INSUFFICIENT_MEMORY;
1124
1125
0
    module_object->data = elf;
1126
0
    switch (get_elf_class_data(block_data, block->size))
1127
0
    {
1128
0
    case CLASS_DATA(ELF_CLASS_32, ELF_DATA_2LSB):
1129
1130
0
      if (block->size > sizeof(elf32_header_t))
1131
0
      {
1132
0
        elf_header32 = (elf32_header_t*) block_data;
1133
1134
0
        if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1135
0
            yr_le16toh(elf_header32->type) == ELF_ET_EXEC)
1136
0
        {
1137
0
          parse_result = parse_elf_header_32_le(
1138
0
              elf,
1139
0
              elf_header32,
1140
0
              block->base,
1141
0
              block->size,
1142
0
              context->flags,
1143
0
              module_object);
1144
0
        }
1145
0
      }
1146
1147
0
      break;
1148
1149
0
    case CLASS_DATA(ELF_CLASS_32, ELF_DATA_2MSB):
1150
1151
0
      if (block->size > sizeof(elf32_header_t))
1152
0
      {
1153
0
        elf_header32 = (elf32_header_t*) block_data;
1154
1155
0
        if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1156
0
            yr_be16toh(elf_header32->type) == ELF_ET_EXEC)
1157
0
        {
1158
0
          parse_result = parse_elf_header_32_be(
1159
0
              elf,
1160
0
              elf_header32,
1161
0
              block->base,
1162
0
              block->size,
1163
0
              context->flags,
1164
0
              module_object);
1165
0
        }
1166
0
      }
1167
1168
0
      break;
1169
1170
0
    case CLASS_DATA(ELF_CLASS_64, ELF_DATA_2LSB):
1171
1172
0
      if (block->size > sizeof(elf64_header_t))
1173
0
      {
1174
0
        elf_header64 = (elf64_header_t*) block_data;
1175
1176
0
        if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1177
0
            yr_le16toh(elf_header64->type) == ELF_ET_EXEC)
1178
0
        {
1179
0
          parse_result = parse_elf_header_64_le(
1180
0
              elf,
1181
0
              elf_header64,
1182
0
              block->base,
1183
0
              block->size,
1184
0
              context->flags,
1185
0
              module_object);
1186
0
        }
1187
0
      }
1188
1189
0
      break;
1190
1191
0
    case CLASS_DATA(ELF_CLASS_64, ELF_DATA_2MSB):
1192
1193
0
      if (block->size > sizeof(elf64_header_t))
1194
0
      {
1195
0
        elf_header64 = (elf64_header_t*) block_data;
1196
1197
0
        if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1198
0
            yr_be16toh(elf_header64->type) == ELF_ET_EXEC)
1199
0
        {
1200
0
          parse_result = parse_elf_header_64_be(
1201
0
              elf,
1202
0
              elf_header64,
1203
0
              block->base,
1204
0
              block->size,
1205
0
              context->flags,
1206
0
              module_object);
1207
0
        }
1208
0
      }
1209
1210
0
      break;
1211
0
    }
1212
0
  }
1213
1214
0
  return parse_result;
1215
0
}
1216
1217
int module_unload(YR_OBJECT* module_object)
1218
0
{
1219
0
  ELF* elf = (ELF*) module_object->data;
1220
0
  if (elf == NULL)
1221
0
    return ERROR_SUCCESS;
1222
1223
0
  if (elf->symtab != NULL)
1224
0
  {
1225
0
    ELF_SYMBOL *act = NULL, *next = NULL;
1226
0
    for (act = elf->symtab->symbols; act != NULL; act = next)
1227
0
    {
1228
0
      next = act->next;
1229
0
      if (act->name != NULL)
1230
0
        yr_free(act->name);
1231
0
      yr_free(act);
1232
0
    }
1233
0
    yr_free(elf->symtab);
1234
0
  }
1235
1236
0
  if (elf->dynsym != NULL)
1237
0
  {
1238
0
    ELF_SYMBOL *act = NULL, *next = NULL;
1239
0
    for (act = elf->dynsym->symbols; act != NULL; act = next)
1240
0
    {
1241
0
      next = act->next;
1242
0
      if (act->name != NULL)
1243
0
        yr_free(act->name);
1244
0
      yr_free(act);
1245
0
    }
1246
0
    yr_free(elf->dynsym);
1247
0
  }
1248
1249
0
  yr_free(elf->telfhash);
1250
0
  yr_free(elf->import_hash);
1251
0
  yr_free(elf);
1252
1253
0
  module_object->data = NULL;
1254
1255
0
  return ERROR_SUCCESS;
1256
0
}