Coverage Report

Created: 2026-02-14 06:52

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