Coverage Report

Created: 2026-10-19 06:44

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