Coverage Report

Created: 2023-09-25 07:12

/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
0
begin_declarations
827
0
  declare_integer("ET_NONE");
828
0
  declare_integer("ET_REL");
829
0
  declare_integer("ET_EXEC");
830
0
  declare_integer("ET_DYN");
831
0
  declare_integer("ET_CORE");
832
833
0
  declare_integer("EM_NONE");
834
0
  declare_integer("EM_M32");
835
0
  declare_integer("EM_SPARC");
836
0
  declare_integer("EM_386");
837
0
  declare_integer("EM_68K");
838
0
  declare_integer("EM_88K");
839
0
  declare_integer("EM_860");
840
0
  declare_integer("EM_MIPS");
841
0
  declare_integer("EM_MIPS_RS3_LE");
842
0
  declare_integer("EM_PPC");
843
0
  declare_integer("EM_PPC64");
844
0
  declare_integer("EM_ARM");
845
0
  declare_integer("EM_X86_64");
846
0
  declare_integer("EM_AARCH64");
847
848
0
  declare_integer("SHT_NULL");
849
0
  declare_integer("SHT_PROGBITS");
850
0
  declare_integer("SHT_SYMTAB");
851
0
  declare_integer("SHT_STRTAB");
852
0
  declare_integer("SHT_RELA");
853
0
  declare_integer("SHT_HASH");
854
0
  declare_integer("SHT_DYNAMIC");
855
0
  declare_integer("SHT_NOTE");
856
0
  declare_integer("SHT_NOBITS");
857
0
  declare_integer("SHT_REL");
858
0
  declare_integer("SHT_SHLIB");
859
0
  declare_integer("SHT_DYNSYM");
860
861
0
  declare_integer("SHF_WRITE");
862
0
  declare_integer("SHF_ALLOC");
863
0
  declare_integer("SHF_EXECINSTR");
864
865
0
  declare_integer("type");
866
0
  declare_integer("machine");
867
0
  declare_integer("entry_point");
868
869
0
  declare_integer("number_of_sections");
870
0
  declare_integer("sh_offset");
871
0
  declare_integer("sh_entry_size");
872
873
0
  declare_integer("number_of_segments");
874
0
  declare_integer("ph_offset");
875
0
  declare_integer("ph_entry_size");
876
877
0
  begin_struct_array("sections")
878
0
    declare_integer("type");
879
0
    declare_integer("flags");
880
0
    declare_integer("address");
881
0
    declare_string("name");
882
0
    declare_integer("size");
883
0
    declare_integer("offset");
884
0
  end_struct_array("sections")
885
886
0
  declare_integer("PT_NULL");
887
0
  declare_integer("PT_LOAD");
888
0
  declare_integer("PT_DYNAMIC");
889
0
  declare_integer("PT_INTERP");
890
0
  declare_integer("PT_NOTE");
891
0
  declare_integer("PT_SHLIB");
892
0
  declare_integer("PT_PHDR");
893
0
  declare_integer("PT_TLS");
894
0
  declare_integer("PT_GNU_EH_FRAME");
895
0
  declare_integer("PT_GNU_STACK");
896
897
0
  declare_integer("DT_NULL");
898
0
  declare_integer("DT_NEEDED");
899
0
  declare_integer("DT_PLTRELSZ");
900
0
  declare_integer("DT_PLTGOT");
901
0
  declare_integer("DT_HASH");
902
0
  declare_integer("DT_STRTAB");
903
0
  declare_integer("DT_SYMTAB");
904
0
  declare_integer("DT_RELA");
905
0
  declare_integer("DT_RELASZ");
906
0
  declare_integer("DT_RELAENT");
907
0
  declare_integer("DT_STRSZ");
908
0
  declare_integer("DT_SYMENT");
909
0
  declare_integer("DT_INIT");
910
0
  declare_integer("DT_FINI");
911
0
  declare_integer("DT_SONAME");
912
0
  declare_integer("DT_RPATH");
913
0
  declare_integer("DT_SYMBOLIC");
914
0
  declare_integer("DT_REL");
915
0
  declare_integer("DT_RELSZ");
916
0
  declare_integer("DT_RELENT");
917
0
  declare_integer("DT_PLTREL");
918
0
  declare_integer("DT_DEBUG");
919
0
  declare_integer("DT_TEXTREL");
920
0
  declare_integer("DT_JMPREL");
921
0
  declare_integer("DT_BIND_NOW");
922
0
  declare_integer("DT_INIT_ARRAY");
923
0
  declare_integer("DT_FINI_ARRAY");
924
0
  declare_integer("DT_INIT_ARRAYSZ");
925
0
  declare_integer("DT_FINI_ARRAYSZ");
926
0
  declare_integer("DT_RUNPATH");
927
0
  declare_integer("DT_FLAGS");
928
0
  declare_integer("DT_ENCODING");
929
930
0
  declare_integer("STT_NOTYPE");
931
0
  declare_integer("STT_OBJECT");
932
0
  declare_integer("STT_FUNC");
933
0
  declare_integer("STT_SECTION");
934
0
  declare_integer("STT_FILE");
935
0
  declare_integer("STT_COMMON");
936
0
  declare_integer("STT_TLS");
937
938
0
  declare_integer("STB_LOCAL");
939
0
  declare_integer("STB_GLOBAL");
940
0
  declare_integer("STB_WEAK");
941
942
0
  declare_integer("PF_X");
943
0
  declare_integer("PF_W");
944
0
  declare_integer("PF_R");
945
946
0
  begin_struct_array("segments")
947
0
    declare_integer("type");
948
0
    declare_integer("flags");
949
0
    declare_integer("offset");
950
0
    declare_integer("virtual_address");
951
0
    declare_integer("physical_address");
952
0
    declare_integer("file_size");
953
0
    declare_integer("memory_size");
954
0
    declare_integer("alignment");
955
0
  end_struct_array("segments")
956
957
0
  declare_integer("dynamic_section_entries");
958
0
  begin_struct_array("dynamic")
959
0
    declare_integer("type");
960
0
    declare_integer("val");
961
0
  end_struct_array("dynamic")
962
963
0
  declare_integer("symtab_entries");
964
0
  begin_struct_array("symtab")
965
0
    declare_string("name");
966
0
    declare_integer("value");
967
0
    declare_integer("size");
968
0
    declare_integer("type");
969
0
    declare_integer("bind");
970
0
    declare_integer("shndx");
971
0
  end_struct_array("symtab")
972
973
0
  declare_integer("dynsym_entries");
974
0
  begin_struct_array("dynsym")
975
0
    declare_string("name");
976
0
    declare_integer("value");
977
0
    declare_integer("size");
978
0
    declare_integer("type");
979
0
    declare_integer("bind");
980
0
    declare_integer("shndx");
981
0
  end_struct_array("dynsym")
982
983
0
  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
0
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
}