Coverage Report

Created: 2025-09-05 06:55

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