Coverage Report

Created: 2025-12-14 06:59

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