Coverage Report

Created: 2026-08-13 06:10

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