Coverage Report

Created: 2025-11-24 06:34

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