Coverage Report

Created: 2025-07-23 06:46

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