Coverage Report

Created: 2026-10-17 06:42

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
  if (!yr_md5_init(&ctx))
260
    goto cleanup;
261
262
  yr_md5_update(&ctx, sstr->str, sstr->len);
263
  yr_md5_final(hash, &ctx);
264
265
  elf->import_hash = yr_malloc(YR_MD5_LEN * 2 + 1);
266
  if (!elf->import_hash)
267
    goto cleanup;
268
269
  for (int i = 0; i < YR_MD5_LEN; ++i)
270
    sprintf(elf->import_hash + (i * 2), "%02x", hash[i]);
271
272
  for (int i = 0; i < symbol_count; ++i) yr_free(clean_names[i]);
273
  yr_free(clean_names);
274
  sstr_free(sstr);
275
276
  return_string(elf->import_hash);
277
278
cleanup:
279
  for (int i = 0; i < symbol_count; ++i) yr_free(clean_names[i]);
280
  yr_free(clean_names);
281
  sstr_free(sstr);
282
283
  return_string(YR_UNDEFINED);
284
}
285
286
#endif  // defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H)
287
288
int get_elf_class_data(const uint8_t* buffer, size_t buffer_length)
289
0
{
290
0
  elf_ident_t* elf_ident;
291
292
0
  if (buffer_length < sizeof(elf_ident_t))
293
0
    return 0;
294
295
0
  elf_ident = (elf_ident_t*) buffer;
296
297
0
  if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
298
0
  {
299
0
    return CLASS_DATA(elf_ident->_class, elf_ident->data);
300
0
  }
301
0
  else
302
0
  {
303
0
    return 0;
304
0
  }
305
0
}
306
307
static bool is_valid_ptr(
308
    const void* base,
309
    size_t size,
310
    const void* ptr,
311
    uint64_t ptr_size)  // ptr_size can be 64bit even in 32bit systems.
312
0
{
313
0
  return ptr >= base && ptr_size <= size &&
314
0
         ((char*) ptr) + ptr_size <= ((char*) base) + size;
315
0
}
316
317
#define IS_VALID_PTR(base, size, ptr) \
318
0
  is_valid_ptr(base, size, ptr, sizeof(*ptr))
319
320
//
321
// Returns a string table entry for the index or NULL if the entry is out
322
// of bounds. A non-null return value will be a null-terminated C string.
323
//
324
static const char* str_table_entry(
325
    const char* str_table_base,
326
    const char* str_table_limit,
327
    int index)
328
0
{
329
0
  size_t len;
330
0
  const char* str_entry;
331
332
0
  if (str_table_base >= str_table_limit)
333
0
    return NULL;
334
335
  // The first entry in the string table must be a null character, if not the
336
  // string table is probably corrupted.
337
0
  if (*str_table_base != '\0')
338
0
    return NULL;
339
340
0
  if (index < 0)
341
0
    return NULL;
342
343
  // Bound the index against the table size before forming the pointer. On
344
  // 32-bit builds str_table_base + index can wrap past str_table_limit for a
345
  // large index and pass the check below, letting strnlen read out of bounds.
346
0
  if ((size_t) index >= (size_t) (str_table_limit - str_table_base))
347
0
    return NULL;
348
349
0
  str_entry = str_table_base + index;
350
351
0
  len = strnlen(str_entry, str_table_limit - str_entry);
352
353
  // Entry is clamped by extent of string table, not null-terminated.
354
0
  if (str_entry + len == str_table_limit)
355
0
    return NULL;
356
357
0
  return str_entry;
358
0
}
359
360
#define ELF_SIZE_OF_SECTION_TABLE(bits, bo, h) \
361
0
  (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count))
362
363
#define ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, h) \
364
0
  (sizeof(elf##bits##_program_header_t) * yr_##bo##16toh(h->ph_entry_count))
365
366
#define ELF_RVA_TO_OFFSET(bits, bo)                                                \
367
  uint64_t elf_rva_to_offset_##bits##_##bo(                                        \
368
      elf##bits##_header_t* elf_header, uint64_t rva, size_t elf_size)             \
369
0
  {                                                                                \
370
0
    if (yr_##bo##16toh(elf_header->type) == ELF_ET_EXEC)                           \
371
0
    {                                                                              \
372
0
      int i;                                                                       \
373
0
                                                                                   \
374
0
      elf##bits##_program_header_t* program;                                       \
375
0
                                                                                   \
376
0
      /* check that ph_offset doesn't wrap when added to SIZE_OF_PROGRAM_TABLE     \
377
0
       */                                                                          \
378
0
                                                                                   \
379
0
      if (ULONG_MAX - yr_##bo##bits##toh(elf_header->ph_offset) <                  \
380
0
          ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, elf_header))                         \
381
0
      {                                                                            \
382
0
        return YR_UNDEFINED;                                                       \
383
0
      }                                                                            \
384
0
                                                                                   \
385
0
      if (yr_##bo##bits##toh(elf_header->ph_offset) == 0 ||                        \
386
0
          yr_##bo##bits##toh(elf_header->ph_offset) > elf_size ||                  \
387
0
          yr_##bo##bits##toh(elf_header->ph_offset) +                              \
388
0
                  ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, elf_header) >                \
389
0
              elf_size ||                                                          \
390
0
          yr_##bo##16toh(elf_header->ph_entry_count) == 0)                         \
391
0
      {                                                                            \
392
0
        return YR_UNDEFINED;                                                       \
393
0
      }                                                                            \
394
0
                                                                                   \
395
0
      program = (elf##bits##_program_header_t*)                                  \
396
0
        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->ph_offset)); \
397
0
                                                                                   \
398
0
      for (i = 0; i < yr_##bo##16toh(elf_header->ph_entry_count); i++)             \
399
0
      {                                                                            \
400
0
        if (rva >= yr_##bo##bits##toh(program->virt_addr) &&                       \
401
0
            rva < yr_##bo##bits##toh(program->virt_addr) +                         \
402
0
                      yr_##bo##bits##toh(program->mem_size))                       \
403
0
        {                                                                          \
404
0
          return yr_##bo##bits##toh(program->offset) +                             \
405
0
                 (rva - yr_##bo##bits##toh(program->virt_addr));                   \
406
0
        }                                                                          \
407
0
                                                                                   \
408
0
        program++;                                                                 \
409
0
      }                                                                            \
410
0
    }                                                                              \
411
0
    else                                                                           \
412
0
    {                                                                              \
413
0
      int i;                                                                       \
414
0
                                                                                   \
415
0
      elf##bits##_section_header_t* section;                                       \
416
0
                                                                                   \
417
0
      /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE     \
418
0
       */                                                                          \
419
0
                                                                                   \
420
0
      if (ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                  \
421
0
          ELF_SIZE_OF_SECTION_TABLE(bits, bo, elf_header))                         \
422
0
      {                                                                            \
423
0
        return YR_UNDEFINED;                                                       \
424
0
      }                                                                            \
425
0
                                                                                   \
426
0
      if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                        \
427
0
          yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                  \
428
0
          yr_##bo##bits##toh(elf_header->sh_offset) +                              \
429
0
                  ELF_SIZE_OF_SECTION_TABLE(bits, bo, elf_header) >                \
430
0
              elf_size ||                                                          \
431
0
          yr_##bo##16toh(elf_header->sh_entry_count) == 0)                         \
432
0
      {                                                                            \
433
0
        return YR_UNDEFINED;                                                       \
434
0
      }                                                                            \
435
0
                                                                                   \
436
0
      section = (elf##bits##_section_header_t*)                                  \
437
0
        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset)); \
438
0
                                                                                   \
439
0
      for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)             \
440
0
      {                                                                            \
441
0
        if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                       \
442
0
            yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                     \
443
0
            rva >= yr_##bo##bits##toh(section->addr) &&                            \
444
0
            rva < yr_##bo##bits##toh(section->addr) +                              \
445
0
                      yr_##bo##bits##toh(section->size))                           \
446
0
        {                                                                          \
447
0
          return yr_##bo##bits##toh(section->offset) +                             \
448
0
                 (rva - yr_##bo##bits##toh(section->addr));                        \
449
0
        }                                                                          \
450
0
                                                                                   \
451
0
        section++;                                                                 \
452
0
      }                                                                            \
453
0
    }                                                                              \
454
0
    return YR_UNDEFINED;                                                           \
455
0
  }
456
457
#define PARSE_ELF_HEADER(bits, bo)                                                        \
458
  int parse_elf_header_##bits##_##bo(                                                     \
459
      ELF* elf_data,                                                                      \
460
      elf##bits##_header_t* elf,                                                          \
461
      uint64_t base_address,                                                              \
462
      size_t elf_size,                                                                    \
463
      int flags,                                                                          \
464
      YR_OBJECT* elf_obj)                                                                 \
465
0
  {                                                                                       \
466
0
    unsigned int i, j, m;                                                                 \
467
0
    const char* elf_raw = (const char*) elf;                                              \
468
0
    uint16_t str_table_index = yr_##bo##16toh(elf->sh_str_table_index);                   \
469
0
                                                                                          \
470
0
    const char* sym_table = NULL;                                                         \
471
0
    const char* sym_str_table = NULL;                                                     \
472
0
    const char* dyn_sym_table = NULL;                                                     \
473
0
    const char* dyn_sym_str_table = NULL;                                                 \
474
0
                                                                                          \
475
0
    uint##bits##_t sym_table_size = 0;                                                    \
476
0
    uint##bits##_t sym_str_table_size = 0;                                                \
477
0
    uint##bits##_t dyn_sym_table_size = 0;                                                \
478
0
    uint##bits##_t dyn_sym_str_table_size = 0;                                            \
479
0
                                                                                          \
480
0
    elf_data->symtab = elf_data->dynsym = NULL;                                           \
481
0
                                                                                          \
482
0
    elf##bits##_section_header_t* section_table;                                          \
483
0
    elf##bits##_section_header_t* section;                                                \
484
0
    elf##bits##_program_header_t* segment;                                                \
485
0
                                                                                          \
486
0
    yr_set_integer(yr_##bo##16toh(elf->type), elf_obj, "type");                           \
487
0
    yr_set_integer(yr_##bo##16toh(elf->machine), elf_obj, "machine");                     \
488
0
    yr_set_integer(yr_##bo##bits##toh(elf->sh_offset), elf_obj, "sh_offset");             \
489
0
    yr_set_integer(                                                                       \
490
0
        yr_##bo##16toh(elf->sh_entry_size), elf_obj, "sh_entry_size");                    \
491
0
    yr_set_integer(                                                                       \
492
0
        yr_##bo##16toh(elf->sh_entry_count), elf_obj, "number_of_sections");              \
493
0
    yr_set_integer(yr_##bo##bits##toh(elf->ph_offset), elf_obj, "ph_offset");             \
494
0
    yr_set_integer(                                                                       \
495
0
        yr_##bo##16toh(elf->ph_entry_size), elf_obj, "ph_entry_size");                    \
496
0
    yr_set_integer(                                                                       \
497
0
        yr_##bo##16toh(elf->ph_entry_count), elf_obj, "number_of_segments");              \
498
0
                                                                                          \
499
0
    if (yr_##bo##bits##toh(elf->entry) != 0)                                              \
500
0
    {                                                                                     \
501
0
      yr_set_integer(                                                                     \
502
0
          flags& SCAN_FLAGS_PROCESS_MEMORY                                                \
503
0
              ? base_address + yr_##bo##bits##toh(elf->entry)                             \
504
0
              : elf_rva_to_offset_##bits##_##bo(                                          \
505
0
                    elf, yr_##bo##bits##toh(elf->entry), elf_size),                       \
506
0
          elf_obj,                                                                        \
507
0
          "entry_point");                                                                 \
508
0
    }                                                                                     \
509
0
                                                                                          \
510
0
    if (yr_##bo##16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&                        \
511
0
        str_table_index < yr_##bo##16toh(elf->sh_entry_count) &&                          \
512
0
        yr_##bo##bits##toh(elf->sh_offset) < elf_size &&                                  \
513
0
        yr_##bo##bits##toh(elf->sh_offset) +                                              \
514
0
                yr_##bo##16toh(elf->sh_entry_count) *                                     \
515
0
                    sizeof(elf##bits##_section_header_t) <=                               \
516
0
            elf_size)                                                                     \
517
0
    {                                                                                     \
518
0
      const char* str_table = NULL;                                                       \
519
0
                                                                                          \
520
0
      section_table =                                                                     \
521
0
          (elf##bits##_section_header_t*) (elf_raw + yr_##bo##bits##toh(elf->sh_offset)); \
522
0
                                                                                          \
523
0
      if (yr_##bo##bits##toh(section_table[str_table_index].offset) <                     \
524
0
          elf_size)                                                                       \
525
0
      {                                                                                   \
526
0
        str_table = elf_raw +                                                             \
527
0
                    yr_##bo##bits##toh(section_table[str_table_index].offset);            \
528
0
      }                                                                                   \
529
0
                                                                                          \
530
0
      section = section_table;                                                            \
531
0
                                                                                          \
532
0
      for (i = 0; i < yr_##bo##16toh(elf->sh_entry_count); i++, section++)                \
533
0
      {                                                                                   \
534
0
        yr_set_integer(                                                                   \
535
0
            yr_##bo##32toh(section->type), elf_obj, "sections[%i].type", i);              \
536
0
        yr_set_integer(                                                                   \
537
0
            yr_##bo##bits##toh(section->flags),                                           \
538
0
            elf_obj,                                                                      \
539
0
            "sections[%i].flags",                                                         \
540
0
            i);                                                                           \
541
0
        yr_set_integer(                                                                   \
542
0
            yr_##bo##bits##toh(section->addr),                                            \
543
0
            elf_obj,                                                                      \
544
0
            "sections[%i].address",                                                       \
545
0
            i);                                                                           \
546
0
        yr_set_integer(                                                                   \
547
0
            yr_##bo##bits##toh(section->size),                                            \
548
0
            elf_obj,                                                                      \
549
0
            "sections[%i].size",                                                          \
550
0
            i);                                                                           \
551
0
        yr_set_integer(                                                                   \
552
0
            yr_##bo##bits##toh(section->offset),                                          \
553
0
            elf_obj,                                                                      \
554
0
            "sections[%i].offset",                                                        \
555
0
            i);                                                                           \
556
0
                                                                                          \
557
0
        if (yr_##bo##32toh(section->name) < elf_size && str_table > elf_raw)              \
558
0
        {                                                                                 \
559
0
          const char* section_name = str_table_entry(                                     \
560
0
              str_table, elf_raw + elf_size, yr_##bo##32toh(section->name));              \
561
0
                                                                                          \
562
0
          if (section_name)                                                               \
563
0
            yr_set_string(section_name, elf_obj, "sections[%i].name", i);                 \
564
0
        }                                                                                 \
565
0
                                                                                          \
566
0
        if (yr_##bo##32toh(section->type) == ELF_SHT_SYMTAB &&                            \
567
0
            yr_##bo##32toh(section->link) <                                               \
568
0
                yr_##bo##16toh(elf->sh_entry_count))                                      \
569
0
        {                                                                                 \
570
0
          elf##bits##_section_header_t* string_section = section_table +                  \
571
0
                                                         yr_##bo##32toh(                  \
572
0
                                                             section->link);              \
573
0
                                                                                          \
574
0
          if (IS_VALID_PTR(elf, elf_size, string_section) &&                              \
575
0
              yr_##bo##32toh(string_section->type) == ELF_SHT_STRTAB)                     \
576
0
          {                                                                               \
577
0
            sym_table = elf_raw + yr_##bo##bits##toh(section->offset);                    \
578
0
            sym_str_table = elf_raw +                                                     \
579
0
                            yr_##bo##bits##toh(string_section->offset);                   \
580
0
            sym_table_size = yr_##bo##bits##toh(section->size);                           \
581
0
            sym_str_table_size = yr_##bo##bits##toh(string_section->size);                \
582
0
          }                                                                               \
583
0
        }                                                                                 \
584
0
                                                                                          \
585
0
        if (yr_##bo##32toh(section->type) == ELF_SHT_DYNSYM &&                            \
586
0
            yr_##bo##32toh(section->link) <                                               \
587
0
                yr_##bo##16toh(elf->sh_entry_count))                                      \
588
0
        {                                                                                 \
589
0
          elf##bits##_section_header_t* dynstr_section = section_table +                  \
590
0
                                                         yr_##bo##32toh(                  \
591
0
                                                             section->link);              \
592
0
                                                                                          \
593
0
          if (IS_VALID_PTR(elf, elf_size, dynstr_section) &&                              \
594
0
              yr_##bo##32toh(dynstr_section->type) == ELF_SHT_STRTAB)                     \
595
0
          {                                                                               \
596
0
            dyn_sym_table = elf_raw + yr_##bo##bits##toh(section->offset);                \
597
0
            dyn_sym_str_table = elf_raw +                                                 \
598
0
                                yr_##bo##bits##toh(dynstr_section->offset);               \
599
0
            dyn_sym_table_size = yr_##bo##bits##toh(section->size);                       \
600
0
            dyn_sym_str_table_size = yr_##bo##bits##toh(dynstr_section->size);            \
601
0
          }                                                                               \
602
0
        }                                                                                 \
603
0
      }                                                                                   \
604
0
                                                                                          \
605
0
      if (is_valid_ptr(elf, elf_size, sym_str_table, sym_str_table_size) &&               \
606
0
          is_valid_ptr(elf, elf_size, sym_table, sym_table_size))                         \
607
0
      {                                                                                   \
608
0
        elf##bits##_sym_t* sym = (elf##bits##_sym_t*) sym_table;                          \
609
0
        elf_data->symtab = (ELF_SYMBOL_LIST*) yr_malloc(                                  \
610
0
            sizeof(ELF_SYMBOL_LIST));                                                     \
611
0
                                                                                          \
612
0
        if (elf_data->symtab == NULL)                                                     \
613
0
          return ERROR_INSUFFICIENT_MEMORY;                                               \
614
0
                                                                                          \
615
0
        ELF_SYMBOL** symbol = &(elf_data->symtab->symbols);                               \
616
0
        *symbol = NULL;                                                                   \
617
0
                                                                                          \
618
0
        for (j = 0; j < sym_table_size / sizeof(elf##bits##_sym_t);                       \
619
0
             j++, sym++)                                                                  \
620
0
        {                                                                                 \
621
0
          *symbol = (ELF_SYMBOL*) yr_malloc(sizeof(ELF_SYMBOL));                          \
622
0
          if (*symbol == NULL)                                                            \
623
0
            return ERROR_INSUFFICIENT_MEMORY;                                             \
624
0
                                                                                          \
625
0
          (*symbol)->name = NULL;                                                         \
626
0
          (*symbol)->next = NULL;                                                         \
627
0
                                                                                          \
628
0
          const char* sym_name = str_table_entry(                                         \
629
0
              sym_str_table,                                                              \
630
0
              sym_str_table + sym_str_table_size,                                         \
631
0
              yr_##bo##32toh(sym->name));                                                 \
632
0
                                                                                          \
633
0
          if (sym_name)                                                                   \
634
0
          {                                                                               \
635
0
            yr_set_string(sym_name, elf_obj, "symtab[%i].name", j);                       \
636
0
            (*symbol)->name = (char*) yr_malloc(strlen(sym_name) + 1);                    \
637
0
            if ((*symbol)->name == NULL)                                                  \
638
0
              return ERROR_INSUFFICIENT_MEMORY;                                           \
639
0
                                                                                          \
640
0
            strcpy((*symbol)->name, sym_name);                                            \
641
0
          }                                                                               \
642
0
                                                                                          \
643
0
          int bind = sym->info >> 4;                                                      \
644
0
          (*symbol)->bind = bind;                                                         \
645
0
          yr_set_integer(bind, elf_obj, "symtab[%i].bind", j);                            \
646
0
                                                                                          \
647
0
          int type = sym->info & 0xf;                                                     \
648
0
          (*symbol)->type = type;                                                         \
649
0
          yr_set_integer(type, elf_obj, "symtab[%i].type", j);                            \
650
0
                                                                                          \
651
0
          int shndx = yr_##bo##16toh(sym->shndx);                                         \
652
0
          (*symbol)->shndx = shndx;                                                       \
653
0
          yr_set_integer(shndx, elf_obj, "symtab[%i].shndx", j);                          \
654
0
                                                                                          \
655
0
          int value = yr_##bo##bits##toh(sym->value);                                     \
656
0
          (*symbol)->value = value;                                                       \
657
0
          yr_set_integer(                                                                 \
658
0
              yr_##bo##bits##toh(sym->value), elf_obj, "symtab[%i].value", j);            \
659
0
                                                                                          \
660
0
          int size = yr_##bo##bits##toh(sym->size);                                       \
661
0
          (*symbol)->size = size;                                                         \
662
0
          yr_set_integer(                                                                 \
663
0
              yr_##bo##bits##toh(sym->size), elf_obj, "symtab[%i].size", j);              \
664
0
                                                                                          \
665
0
          (*symbol)->visibility = sym->other & 0x3;                                       \
666
0
                                                                                          \
667
0
          symbol = &((*symbol)->next);                                                    \
668
0
        }                                                                                 \
669
0
                                                                                          \
670
0
        elf_data->symtab->count = j;                                                      \
671
0
        yr_set_integer(j, elf_obj, "symtab_entries");                                     \
672
0
      }                                                                                   \
673
0
                                                                                          \
674
0
      if (is_valid_ptr(                                                                   \
675
0
              elf, elf_size, dyn_sym_str_table, dyn_sym_str_table_size) &&                \
676
0
          is_valid_ptr(elf, elf_size, dyn_sym_table, dyn_sym_table_size))                 \
677
0
      {                                                                                   \
678
0
        elf##bits##_sym_t* dynsym = (elf##bits##_sym_t*) dyn_sym_table;                   \
679
0
                                                                                          \
680
0
        elf_data->dynsym = (ELF_SYMBOL_LIST*) yr_malloc(                                  \
681
0
            sizeof(ELF_SYMBOL_LIST));                                                     \
682
0
                                                                                          \
683
0
        if (elf_data->dynsym == NULL)                                                     \
684
0
          return ERROR_INSUFFICIENT_MEMORY;                                               \
685
0
                                                                                          \
686
0
        ELF_SYMBOL** symbol = &(elf_data->dynsym->symbols);                               \
687
0
        *symbol = NULL;                                                                   \
688
0
                                                                                          \
689
0
        for (m = 0; m < dyn_sym_table_size / sizeof(elf##bits##_sym_t);                   \
690
0
             m++, dynsym++)                                                               \
691
0
        {                                                                                 \
692
0
          *symbol = (ELF_SYMBOL*) yr_malloc(sizeof(ELF_SYMBOL));                          \
693
0
          if (*symbol == NULL)                                                            \
694
0
            return ERROR_INSUFFICIENT_MEMORY;                                             \
695
0
                                                                                          \
696
0
          (*symbol)->name = NULL;                                                         \
697
0
          (*symbol)->next = NULL;                                                         \
698
0
                                                                                          \
699
0
          const char* dynsym_name = str_table_entry(                                      \
700
0
              dyn_sym_str_table,                                                          \
701
0
              dyn_sym_str_table + dyn_sym_str_table_size,                                 \
702
0
              yr_##bo##32toh(dynsym->name));                                              \
703
0
                                                                                          \
704
0
          if (dynsym_name)                                                                \
705
0
          {                                                                               \
706
0
            yr_set_string(dynsym_name, elf_obj, "dynsym[%i].name", m);                    \
707
0
            (*symbol)->name = (char*) yr_malloc(strlen(dynsym_name) + 1);                 \
708
0
            if ((*symbol)->name == NULL)                                                  \
709
0
              return ERROR_INSUFFICIENT_MEMORY;                                           \
710
0
                                                                                          \
711
0
            strcpy((*symbol)->name, dynsym_name);                                         \
712
0
          }                                                                               \
713
0
                                                                                          \
714
0
          int bind = dynsym->info >> 4;                                                   \
715
0
          (*symbol)->bind = bind;                                                         \
716
0
          yr_set_integer(dynsym->info >> 4, elf_obj, "dynsym[%i].bind", m);               \
717
0
                                                                                          \
718
0
          int type = dynsym->info & 0xf;                                                  \
719
0
          (*symbol)->type = type;                                                         \
720
0
          yr_set_integer(dynsym->info & 0xf, elf_obj, "dynsym[%i].type", m);              \
721
0
                                                                                          \
722
0
          int shndx = yr_##bo##16toh(dynsym->shndx);                                      \
723
0
          (*symbol)->shndx = shndx;                                                       \
724
0
          yr_set_integer(                                                                 \
725
0
              yr_##bo##16toh(dynsym->shndx), elf_obj, "dynsym[%i].shndx", m);             \
726
0
                                                                                          \
727
0
          int value = yr_##bo##bits##toh(dynsym->value);                                  \
728
0
          (*symbol)->value = value;                                                       \
729
0
          yr_set_integer(                                                                 \
730
0
              yr_##bo##bits##toh(dynsym->value),                                          \
731
0
              elf_obj,                                                                    \
732
0
              "dynsym[%i].value",                                                         \
733
0
              m);                                                                         \
734
0
                                                                                          \
735
0
          int size = yr_##bo##bits##toh(dynsym->size);                                    \
736
0
          (*symbol)->size = size;                                                         \
737
0
          yr_set_integer(                                                                 \
738
0
              yr_##bo##bits##toh(dynsym->size),                                           \
739
0
              elf_obj,                                                                    \
740
0
              "dynsym[%i].size",                                                          \
741
0
              m);                                                                         \
742
0
                                                                                          \
743
0
          (*symbol)->visibility = dynsym->other & 0x3;                                    \
744
0
                                                                                          \
745
0
          symbol = &((*symbol)->next);                                                    \
746
0
        }                                                                                 \
747
0
                                                                                          \
748
0
        elf_data->dynsym->count = m;                                                      \
749
0
        yr_set_integer(m, elf_obj, "dynsym_entries");                                     \
750
0
      }                                                                                   \
751
0
    }                                                                                     \
752
0
                                                                                          \
753
0
    if (yr_##bo##16toh(elf->ph_entry_count) > 0 &&                                        \
754
0
        yr_##bo##16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                              \
755
0
        yr_##bo##bits##toh(elf->ph_offset) < elf_size &&                                  \
756
0
        yr_##bo##bits##toh(elf->ph_offset) +                                              \
757
0
                yr_##bo##16toh(elf->ph_entry_count) *                                     \
758
0
                    sizeof(elf##bits##_program_header_t) <=                               \
759
0
            elf_size)                                                                     \
760
0
    {                                                                                     \
761
0
      segment =                                                                           \
762
0
          (elf##bits##_program_header_t*) (elf_raw + yr_##bo##bits##toh(elf->ph_offset)); \
763
0
                                                                                          \
764
0
      for (i = 0; i < yr_##bo##16toh(elf->ph_entry_count); i++, segment++)                \
765
0
      {                                                                                   \
766
0
        yr_set_integer(                                                                   \
767
0
            yr_##bo##32toh(segment->type), elf_obj, "segments[%i].type", i);              \
768
0
        yr_set_integer(                                                                   \
769
0
            yr_##bo##32toh(segment->flags), elf_obj, "segments[%i].flags", i);            \
770
0
        yr_set_integer(                                                                   \
771
0
            yr_##bo##bits##toh(segment->offset),                                          \
772
0
            elf_obj,                                                                      \
773
0
            "segments[%i].offset",                                                        \
774
0
            i);                                                                           \
775
0
        yr_set_integer(                                                                   \
776
0
            yr_##bo##bits##toh(segment->virt_addr),                                       \
777
0
            elf_obj,                                                                      \
778
0
            "segments[%i].virtual_address",                                               \
779
0
            i);                                                                           \
780
0
        yr_set_integer(                                                                   \
781
0
            yr_##bo##bits##toh(segment->phys_addr),                                       \
782
0
            elf_obj,                                                                      \
783
0
            "segments[%i].physical_address",                                              \
784
0
            i);                                                                           \
785
0
        yr_set_integer(                                                                   \
786
0
            yr_##bo##bits##toh(segment->file_size),                                       \
787
0
            elf_obj,                                                                      \
788
0
            "segments[%i].file_size",                                                     \
789
0
            i);                                                                           \
790
0
        yr_set_integer(                                                                   \
791
0
            yr_##bo##bits##toh(segment->mem_size),                                        \
792
0
            elf_obj,                                                                      \
793
0
            "segments[%i].memory_size",                                                   \
794
0
            i);                                                                           \
795
0
        yr_set_integer(                                                                   \
796
0
            yr_##bo##bits##toh(segment->alignment),                                       \
797
0
            elf_obj,                                                                      \
798
0
            "segments[%i].alignment",                                                     \
799
0
            i);                                                                           \
800
0
                                                                                          \
801
0
        if (yr_##bo##32toh(segment->type) == ELF_PT_DYNAMIC)                              \
802
0
        {                                                                                 \
803
0
          j = 0;                                                                          \
804
0
          if (yr_##bo##bits##toh(segment->offset) < elf_size)                             \
805
0
          {                                                                               \
806
0
            elf##bits##_dyn_t* dyn =                                                      \
807
0
                (elf##bits##_dyn_t*) (elf_raw + yr_##bo##bits##toh(segment->offset));     \
808
0
                                                                                          \
809
0
            for (j = 0; IS_VALID_PTR(elf, elf_size, dyn); dyn++, j++)                     \
810
0
            {                                                                             \
811
0
              yr_set_integer(                                                             \
812
0
                  yr_##bo##bits##toh(dyn->tag), elf_obj, "dynamic[%i].type", j);          \
813
0
              yr_set_integer(                                                             \
814
0
                  yr_##bo##bits##toh(dyn->val), elf_obj, "dynamic[%i].val", j);           \
815
0
                                                                                          \
816
0
              if (dyn->tag == ELF_DT_NULL)                                                \
817
0
              {                                                                           \
818
0
                j++;                                                                      \
819
0
                break;                                                                    \
820
0
              }                                                                           \
821
0
            }                                                                             \
822
0
          }                                                                               \
823
0
          yr_set_integer(j, elf_obj, "dynamic_section_entries");                          \
824
0
        }                                                                                 \
825
0
      }                                                                                   \
826
0
    }                                                                                     \
827
0
    return ERROR_SUCCESS;                                                                 \
828
0
  }
829
830
0
ELF_RVA_TO_OFFSET(32, le);
831
0
ELF_RVA_TO_OFFSET(64, le);
832
0
ELF_RVA_TO_OFFSET(32, be);
833
0
ELF_RVA_TO_OFFSET(64, be);
834
835
0
PARSE_ELF_HEADER(32, le);
836
0
PARSE_ELF_HEADER(64, le);
837
0
PARSE_ELF_HEADER(32, be);
838
0
PARSE_ELF_HEADER(64, be);
839
840
0
begin_declarations
841
0
  declare_integer("ET_NONE");
842
0
  declare_integer("ET_REL");
843
0
  declare_integer("ET_EXEC");
844
0
  declare_integer("ET_DYN");
845
0
  declare_integer("ET_CORE");
846
847
0
  declare_integer("EM_NONE");
848
0
  declare_integer("EM_M32");
849
0
  declare_integer("EM_SPARC");
850
0
  declare_integer("EM_386");
851
0
  declare_integer("EM_68K");
852
0
  declare_integer("EM_88K");
853
0
  declare_integer("EM_860");
854
0
  declare_integer("EM_MIPS");
855
0
  declare_integer("EM_MIPS_RS3_LE");
856
0
  declare_integer("EM_PARISC");
857
0
  declare_integer("EM_SPARC32PLUS");
858
0
  declare_integer("EM_PPC");
859
0
  declare_integer("EM_PPC64");
860
0
  declare_integer("EM_S390");
861
0
  declare_integer("EM_MCORE");
862
0
  declare_integer("EM_RCE");
863
0
  declare_integer("EM_ARM");
864
0
  declare_integer("EM_SH");
865
0
  declare_integer("EM_SPARCV9");
866
0
  declare_integer("EM_X86_64");
867
0
  declare_integer("EM_ARC_COMPACT");
868
0
  declare_integer("EM_AARCH64");
869
0
  declare_integer("EM_BPF");
870
0
  declare_integer("EM_LOONGARCH");
871
872
0
  declare_integer("SHT_NULL");
873
0
  declare_integer("SHT_PROGBITS");
874
0
  declare_integer("SHT_SYMTAB");
875
0
  declare_integer("SHT_STRTAB");
876
0
  declare_integer("SHT_RELA");
877
0
  declare_integer("SHT_HASH");
878
0
  declare_integer("SHT_DYNAMIC");
879
0
  declare_integer("SHT_NOTE");
880
0
  declare_integer("SHT_NOBITS");
881
0
  declare_integer("SHT_REL");
882
0
  declare_integer("SHT_SHLIB");
883
0
  declare_integer("SHT_DYNSYM");
884
885
0
  declare_integer("SHF_WRITE");
886
0
  declare_integer("SHF_ALLOC");
887
0
  declare_integer("SHF_EXECINSTR");
888
889
0
  declare_integer("type");
890
0
  declare_integer("machine");
891
0
  declare_integer("entry_point");
892
893
0
  declare_integer("number_of_sections");
894
0
  declare_integer("sh_offset");
895
0
  declare_integer("sh_entry_size");
896
897
0
  declare_integer("number_of_segments");
898
0
  declare_integer("ph_offset");
899
0
  declare_integer("ph_entry_size");
900
901
0
  begin_struct_array("sections")
902
0
    declare_integer("type");
903
0
    declare_integer("flags");
904
0
    declare_integer("address");
905
0
    declare_string("name");
906
0
    declare_integer("size");
907
0
    declare_integer("offset");
908
0
  end_struct_array("sections")
909
910
0
  declare_integer("PT_NULL");
911
0
  declare_integer("PT_LOAD");
912
0
  declare_integer("PT_DYNAMIC");
913
0
  declare_integer("PT_INTERP");
914
0
  declare_integer("PT_NOTE");
915
0
  declare_integer("PT_SHLIB");
916
0
  declare_integer("PT_PHDR");
917
0
  declare_integer("PT_TLS");
918
0
  declare_integer("PT_GNU_EH_FRAME");
919
0
  declare_integer("PT_GNU_STACK");
920
921
0
  declare_integer("DT_NULL");
922
0
  declare_integer("DT_NEEDED");
923
0
  declare_integer("DT_PLTRELSZ");
924
0
  declare_integer("DT_PLTGOT");
925
0
  declare_integer("DT_HASH");
926
0
  declare_integer("DT_STRTAB");
927
0
  declare_integer("DT_SYMTAB");
928
0
  declare_integer("DT_RELA");
929
0
  declare_integer("DT_RELASZ");
930
0
  declare_integer("DT_RELAENT");
931
0
  declare_integer("DT_STRSZ");
932
0
  declare_integer("DT_SYMENT");
933
0
  declare_integer("DT_INIT");
934
0
  declare_integer("DT_FINI");
935
0
  declare_integer("DT_SONAME");
936
0
  declare_integer("DT_RPATH");
937
0
  declare_integer("DT_SYMBOLIC");
938
0
  declare_integer("DT_REL");
939
0
  declare_integer("DT_RELSZ");
940
0
  declare_integer("DT_RELENT");
941
0
  declare_integer("DT_PLTREL");
942
0
  declare_integer("DT_DEBUG");
943
0
  declare_integer("DT_TEXTREL");
944
0
  declare_integer("DT_JMPREL");
945
0
  declare_integer("DT_BIND_NOW");
946
0
  declare_integer("DT_INIT_ARRAY");
947
0
  declare_integer("DT_FINI_ARRAY");
948
0
  declare_integer("DT_INIT_ARRAYSZ");
949
0
  declare_integer("DT_FINI_ARRAYSZ");
950
0
  declare_integer("DT_RUNPATH");
951
0
  declare_integer("DT_FLAGS");
952
0
  declare_integer("DT_ENCODING");
953
954
0
  declare_integer("STT_NOTYPE");
955
0
  declare_integer("STT_OBJECT");
956
0
  declare_integer("STT_FUNC");
957
0
  declare_integer("STT_SECTION");
958
0
  declare_integer("STT_FILE");
959
0
  declare_integer("STT_COMMON");
960
0
  declare_integer("STT_TLS");
961
962
0
  declare_integer("STB_LOCAL");
963
0
  declare_integer("STB_GLOBAL");
964
0
  declare_integer("STB_WEAK");
965
966
0
  declare_integer("PF_X");
967
0
  declare_integer("PF_W");
968
0
  declare_integer("PF_R");
969
970
0
  begin_struct_array("segments")
971
0
    declare_integer("type");
972
0
    declare_integer("flags");
973
0
    declare_integer("offset");
974
0
    declare_integer("virtual_address");
975
0
    declare_integer("physical_address");
976
0
    declare_integer("file_size");
977
0
    declare_integer("memory_size");
978
0
    declare_integer("alignment");
979
0
  end_struct_array("segments")
980
981
0
  declare_integer("dynamic_section_entries");
982
0
  begin_struct_array("dynamic")
983
0
    declare_integer("type");
984
0
    declare_integer("val");
985
0
  end_struct_array("dynamic")
986
987
0
  declare_integer("symtab_entries");
988
0
  begin_struct_array("symtab")
989
0
    declare_string("name");
990
0
    declare_integer("value");
991
0
    declare_integer("size");
992
0
    declare_integer("type");
993
0
    declare_integer("bind");
994
0
    declare_integer("shndx");
995
0
  end_struct_array("symtab")
996
997
0
  declare_integer("dynsym_entries");
998
0
  begin_struct_array("dynsym")
999
0
    declare_string("name");
1000
0
    declare_integer("value");
1001
0
    declare_integer("size");
1002
0
    declare_integer("type");
1003
0
    declare_integer("bind");
1004
0
    declare_integer("shndx");
1005
0
  end_struct_array("dynsym")
1006
1007
0
  declare_function("telfhash", "", "s", telfhash);
1008
1009
#if defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H) || \
1010
    defined(HAVE_COMMONCRYPTO_COMMONCRYPTO_H)
1011
  declare_function("import_md5", "", "s", import_md5);
1012
#endif  // defined(HAVE_LIBCRYPTO) || defined(HAVE_WINCRYPT_H)
1013
1014
0
end_declarations
1015
1016
int module_initialize(YR_MODULE* module)
1017
1
{
1018
1
  return ERROR_SUCCESS;
1019
1
}
1020
1021
int module_finalize(YR_MODULE* module)
1022
0
{
1023
0
  return ERROR_SUCCESS;
1024
0
}
1025
1026
int module_load(
1027
    YR_SCAN_CONTEXT* context,
1028
    YR_OBJECT* module_object,
1029
    void* module_data,
1030
    size_t module_data_size)
1031
0
{
1032
0
  YR_MEMORY_BLOCK* block;
1033
0
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1034
1035
0
  elf32_header_t* elf_header32;
1036
0
  elf64_header_t* elf_header64;
1037
1038
0
  yr_set_integer(ELF_ET_NONE, module_object, "ET_NONE");
1039
0
  yr_set_integer(ELF_ET_REL, module_object, "ET_REL");
1040
0
  yr_set_integer(ELF_ET_EXEC, module_object, "ET_EXEC");
1041
0
  yr_set_integer(ELF_ET_DYN, module_object, "ET_DYN");
1042
0
  yr_set_integer(ELF_ET_CORE, module_object, "ET_CORE");
1043
1044
0
  yr_set_integer(ELF_EM_NONE, module_object, "EM_NONE");
1045
0
  yr_set_integer(ELF_EM_M32, module_object, "EM_M32");
1046
0
  yr_set_integer(ELF_EM_SPARC, module_object, "EM_SPARC");
1047
0
  yr_set_integer(ELF_EM_386, module_object, "EM_386");
1048
0
  yr_set_integer(ELF_EM_68K, module_object, "EM_68K");
1049
0
  yr_set_integer(ELF_EM_88K, module_object, "EM_88K");
1050
0
  yr_set_integer(ELF_EM_860, module_object, "EM_860");
1051
0
  yr_set_integer(ELF_EM_MIPS, module_object, "EM_MIPS");
1052
0
  yr_set_integer(ELF_EM_MIPS_RS3_LE, module_object, "EM_MIPS_RS3_LE");
1053
0
  yr_set_integer(ELF_EM_PARISC, module_object, "EM_PARISC");
1054
0
  yr_set_integer(ELF_EM_SPARC32PLUS, module_object, "EM_SPARC32PLUS");
1055
0
  yr_set_integer(ELF_EM_PPC, module_object, "EM_PPC");
1056
0
  yr_set_integer(ELF_EM_PPC64, module_object, "EM_PPC64");
1057
0
  yr_set_integer(ELF_EM_S390, module_object, "EM_S390");
1058
0
  yr_set_integer(ELF_EM_MCORE, module_object, "EM_MCORE");
1059
  // EM_RCE is the name 0x27 was originally registered under and is still what
1060
  // some toolchains emit. Same value, exposed so either name works in a rule.
1061
0
  yr_set_integer(ELF_EM_MCORE, module_object, "EM_RCE");
1062
0
  yr_set_integer(ELF_EM_ARM, module_object, "EM_ARM");
1063
0
  yr_set_integer(ELF_EM_SH, module_object, "EM_SH");
1064
0
  yr_set_integer(ELF_EM_SPARCV9, module_object, "EM_SPARCV9");
1065
0
  yr_set_integer(ELF_EM_X86_64, module_object, "EM_X86_64");
1066
0
  yr_set_integer(ELF_EM_ARC_COMPACT, module_object, "EM_ARC_COMPACT");
1067
0
  yr_set_integer(ELF_EM_AARCH64, module_object, "EM_AARCH64");
1068
0
  yr_set_integer(ELF_EM_BPF, module_object, "EM_BPF");
1069
0
  yr_set_integer(ELF_EM_LOONGARCH, module_object, "EM_LOONGARCH");
1070
1071
0
  yr_set_integer(ELF_SHT_NULL, module_object, "SHT_NULL");
1072
0
  yr_set_integer(ELF_SHT_PROGBITS, module_object, "SHT_PROGBITS");
1073
0
  yr_set_integer(ELF_SHT_SYMTAB, module_object, "SHT_SYMTAB");
1074
0
  yr_set_integer(ELF_SHT_STRTAB, module_object, "SHT_STRTAB");
1075
0
  yr_set_integer(ELF_SHT_RELA, module_object, "SHT_RELA");
1076
0
  yr_set_integer(ELF_SHT_HASH, module_object, "SHT_HASH");
1077
0
  yr_set_integer(ELF_SHT_DYNAMIC, module_object, "SHT_DYNAMIC");
1078
0
  yr_set_integer(ELF_SHT_NOTE, module_object, "SHT_NOTE");
1079
0
  yr_set_integer(ELF_SHT_NOBITS, module_object, "SHT_NOBITS");
1080
0
  yr_set_integer(ELF_SHT_REL, module_object, "SHT_REL");
1081
0
  yr_set_integer(ELF_SHT_SHLIB, module_object, "SHT_SHLIB");
1082
0
  yr_set_integer(ELF_SHT_DYNSYM, module_object, "SHT_DYNSYM");
1083
1084
0
  yr_set_integer(ELF_SHF_WRITE, module_object, "SHF_WRITE");
1085
0
  yr_set_integer(ELF_SHF_ALLOC, module_object, "SHF_ALLOC");
1086
0
  yr_set_integer(ELF_SHF_EXECINSTR, module_object, "SHF_EXECINSTR");
1087
1088
0
  yr_set_integer(ELF_PT_NULL, module_object, "PT_NULL");
1089
0
  yr_set_integer(ELF_PT_LOAD, module_object, "PT_LOAD");
1090
0
  yr_set_integer(ELF_PT_DYNAMIC, module_object, "PT_DYNAMIC");
1091
0
  yr_set_integer(ELF_PT_INTERP, module_object, "PT_INTERP");
1092
0
  yr_set_integer(ELF_PT_NOTE, module_object, "PT_NOTE");
1093
0
  yr_set_integer(ELF_PT_SHLIB, module_object, "PT_SHLIB");
1094
0
  yr_set_integer(ELF_PT_PHDR, module_object, "PT_PHDR");
1095
0
  yr_set_integer(ELF_PT_TLS, module_object, "PT_TLS");
1096
0
  yr_set_integer(ELF_PT_GNU_EH_FRAME, module_object, "PT_GNU_EH_FRAME");
1097
0
  yr_set_integer(ELF_PT_GNU_STACK, module_object, "PT_GNU_STACK");
1098
1099
0
  yr_set_integer(ELF_DT_NULL, module_object, "DT_NULL");
1100
0
  yr_set_integer(ELF_DT_NEEDED, module_object, "DT_NEEDED");
1101
0
  yr_set_integer(ELF_DT_PLTRELSZ, module_object, "DT_PLTRELSZ");
1102
0
  yr_set_integer(ELF_DT_PLTGOT, module_object, "DT_PLTGOT");
1103
0
  yr_set_integer(ELF_DT_HASH, module_object, "DT_HASH");
1104
0
  yr_set_integer(ELF_DT_STRTAB, module_object, "DT_STRTAB");
1105
0
  yr_set_integer(ELF_DT_SYMTAB, module_object, "DT_SYMTAB");
1106
0
  yr_set_integer(ELF_DT_RELA, module_object, "DT_RELA");
1107
0
  yr_set_integer(ELF_DT_RELASZ, module_object, "DT_RELASZ");
1108
0
  yr_set_integer(ELF_DT_RELAENT, module_object, "DT_RELAENT");
1109
0
  yr_set_integer(ELF_DT_STRSZ, module_object, "DT_STRSZ");
1110
0
  yr_set_integer(ELF_DT_SYMENT, module_object, "DT_SYMENT");
1111
0
  yr_set_integer(ELF_DT_INIT, module_object, "DT_INIT");
1112
0
  yr_set_integer(ELF_DT_FINI, module_object, "DT_FINI");
1113
0
  yr_set_integer(ELF_DT_SONAME, module_object, "DT_SONAME");
1114
0
  yr_set_integer(ELF_DT_RPATH, module_object, "DT_RPATH");
1115
0
  yr_set_integer(ELF_DT_SYMBOLIC, module_object, "DT_SYMBOLIC");
1116
0
  yr_set_integer(ELF_DT_REL, module_object, "DT_REL");
1117
0
  yr_set_integer(ELF_DT_RELSZ, module_object, "DT_RELSZ");
1118
0
  yr_set_integer(ELF_DT_RELENT, module_object, "DT_RELENT");
1119
0
  yr_set_integer(ELF_DT_PLTREL, module_object, "DT_PLTREL");
1120
0
  yr_set_integer(ELF_DT_DEBUG, module_object, "DT_DEBUG");
1121
0
  yr_set_integer(ELF_DT_TEXTREL, module_object, "DT_TEXTREL");
1122
0
  yr_set_integer(ELF_DT_JMPREL, module_object, "DT_JMPREL");
1123
0
  yr_set_integer(ELF_DT_BIND_NOW, module_object, "DT_BIND_NOW");
1124
0
  yr_set_integer(ELF_DT_INIT_ARRAY, module_object, "DT_INIT_ARRAY");
1125
0
  yr_set_integer(ELF_DT_FINI_ARRAY, module_object, "DT_FINI_ARRAY");
1126
0
  yr_set_integer(ELF_DT_INIT_ARRAYSZ, module_object, "DT_INIT_ARRAYSZ");
1127
0
  yr_set_integer(ELF_DT_FINI_ARRAYSZ, module_object, "DT_FINI_ARRAYSZ");
1128
0
  yr_set_integer(ELF_DT_RUNPATH, module_object, "DT_RUNPATH");
1129
0
  yr_set_integer(ELF_DT_FLAGS, module_object, "DT_FLAGS");
1130
0
  yr_set_integer(ELF_DT_ENCODING, module_object, "DT_ENCODING");
1131
1132
0
  yr_set_integer(ELF_STT_NOTYPE, module_object, "STT_NOTYPE");
1133
0
  yr_set_integer(ELF_STT_OBJECT, module_object, "STT_OBJECT");
1134
0
  yr_set_integer(ELF_STT_FUNC, module_object, "STT_FUNC");
1135
0
  yr_set_integer(ELF_STT_SECTION, module_object, "STT_SECTION");
1136
0
  yr_set_integer(ELF_STT_FILE, module_object, "STT_FILE");
1137
0
  yr_set_integer(ELF_STT_COMMON, module_object, "STT_COMMON");
1138
0
  yr_set_integer(ELF_STT_TLS, module_object, "STT_TLS");
1139
1140
0
  yr_set_integer(ELF_STB_LOCAL, module_object, "STB_LOCAL");
1141
0
  yr_set_integer(ELF_STB_GLOBAL, module_object, "STB_GLOBAL");
1142
0
  yr_set_integer(ELF_STB_WEAK, module_object, "STB_WEAK");
1143
1144
0
  yr_set_integer(ELF_PF_X, module_object, "PF_X");
1145
0
  yr_set_integer(ELF_PF_W, module_object, "PF_W");
1146
0
  yr_set_integer(ELF_PF_R, module_object, "PF_R");
1147
1148
0
  uint64_t parse_result = ERROR_SUCCESS;
1149
1150
0
  foreach_memory_block(iterator, block)
1151
0
  {
1152
0
    const uint8_t* block_data = yr_fetch_block_data(block);
1153
1154
0
    if (block_data == NULL)
1155
0
      continue;
1156
1157
0
    ELF* elf = (ELF*) yr_calloc(1, sizeof(ELF));
1158
0
    if (elf == NULL)
1159
0
      return ERROR_INSUFFICIENT_MEMORY;
1160
1161
0
    module_object->data = elf;
1162
0
    int class_data = get_elf_class_data(block_data, block->size);
1163
1164
0
    if (class_data == CLASS_DATA(ELF_CLASS_32, ELF_DATA_2LSB) &&
1165
0
        block->size > sizeof(elf32_header_t))
1166
0
    {
1167
0
      elf_header32 = (elf32_header_t*) block_data;
1168
1169
0
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1170
0
          yr_le16toh(elf_header32->type) == ELF_ET_EXEC)
1171
0
      {
1172
0
        parse_result = parse_elf_header_32_le(
1173
0
            elf,
1174
0
            elf_header32,
1175
0
            block->base,
1176
0
            block->size,
1177
0
            context->flags,
1178
0
            module_object);
1179
0
        break;
1180
0
      }
1181
0
    } else if (
1182
0
        class_data == CLASS_DATA(ELF_CLASS_32, ELF_DATA_2MSB) &&
1183
0
        block->size > sizeof(elf32_header_t))
1184
0
    {
1185
0
      elf_header32 = (elf32_header_t*) block_data;
1186
1187
0
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1188
0
          yr_be16toh(elf_header32->type) == ELF_ET_EXEC)
1189
0
      {
1190
0
        parse_result = parse_elf_header_32_be(
1191
0
            elf,
1192
0
            elf_header32,
1193
0
            block->base,
1194
0
            block->size,
1195
0
            context->flags,
1196
0
            module_object);
1197
0
        break;
1198
0
      }
1199
0
    } else if (
1200
0
        class_data == CLASS_DATA(ELF_CLASS_64, ELF_DATA_2LSB) &&
1201
0
        block->size > sizeof(elf64_header_t))
1202
0
    {
1203
0
      elf_header64 = (elf64_header_t*) block_data;
1204
1205
0
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1206
0
          yr_le16toh(elf_header64->type) == ELF_ET_EXEC)
1207
0
      {
1208
0
        parse_result = parse_elf_header_64_le(
1209
0
            elf,
1210
0
            elf_header64,
1211
0
            block->base,
1212
0
            block->size,
1213
0
            context->flags,
1214
0
            module_object);
1215
0
        break;
1216
0
      }
1217
0
    } else if (
1218
0
        class_data == CLASS_DATA(ELF_CLASS_64, ELF_DATA_2MSB) &&
1219
0
        block->size > sizeof(elf64_header_t))
1220
0
    {
1221
0
      elf_header64 = (elf64_header_t*) block_data;
1222
1223
0
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1224
0
          yr_be16toh(elf_header64->type) == ELF_ET_EXEC)
1225
0
      {
1226
0
        parse_result = parse_elf_header_64_be(
1227
0
            elf,
1228
0
            elf_header64,
1229
0
            block->base,
1230
0
            block->size,
1231
0
            context->flags,
1232
0
            module_object);
1233
0
        break;
1234
0
      }
1235
0
    }
1236
0
  }
1237
1238
0
  return parse_result;
1239
0
}
1240
1241
int module_unload(YR_OBJECT* module_object)
1242
0
{
1243
0
  ELF* elf = (ELF*) module_object->data;
1244
0
  if (elf == NULL)
1245
0
    return ERROR_SUCCESS;
1246
1247
0
  if (elf->symtab != NULL)
1248
0
  {
1249
0
    ELF_SYMBOL *act = NULL, *next = NULL;
1250
0
    for (act = elf->symtab->symbols; act != NULL; act = next)
1251
0
    {
1252
0
      next = act->next;
1253
0
      if (act->name != NULL)
1254
0
        yr_free(act->name);
1255
0
      yr_free(act);
1256
0
    }
1257
0
    yr_free(elf->symtab);
1258
0
  }
1259
1260
0
  if (elf->dynsym != NULL)
1261
0
  {
1262
0
    ELF_SYMBOL *act = NULL, *next = NULL;
1263
0
    for (act = elf->dynsym->symbols; act != NULL; act = next)
1264
0
    {
1265
0
      next = act->next;
1266
0
      if (act->name != NULL)
1267
0
        yr_free(act->name);
1268
0
      yr_free(act);
1269
0
    }
1270
0
    yr_free(elf->dynsym);
1271
0
  }
1272
1273
0
  yr_free(elf->telfhash);
1274
0
  yr_free(elf->import_hash);
1275
0
  yr_free(elf);
1276
1277
0
  module_object->data = NULL;
1278
1279
0
  return ERROR_SUCCESS;
1280
0
}