Coverage Report

Created: 2026-05-30 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yara/libyara/modules/elf/elf.c
Line
Count
Source
1
/*
2
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
3
4
Redistribution and use in source and binary forms, with or without modification,
5
are permitted provided that the following conditions are met:
6
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions and the following disclaimer.
9
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions and the following disclaimer in the documentation and/or
12
other materials provided with the distribution.
13
14
3. Neither the name of the copyright holder nor the names of its contributors
15
may be used to endorse or promote products derived from this software without
16
specific prior written permission.
17
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#include <limits.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <tlshc/tlsh.h>
34
#include <yara/elf.h>
35
#include <yara/elf_utils.h>
36
#include <yara/endian.h>
37
#include <yara/mem.h>
38
#include <yara/modules.h>
39
#include <yara/simple_str.h>
40
#include <yara/utils.h>
41
#include "../crypto.h"
42
#include "../exception.h"
43
44
#define MODULE_NAME elf
45
46
50.5k
#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
7.53k
{
286
7.53k
  elf_ident_t* elf_ident;
287
288
7.53k
  if (buffer_length < sizeof(elf_ident_t))
289
16
    return 0;
290
291
7.51k
  elf_ident = (elf_ident_t*) buffer;
292
293
7.51k
  if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
294
7.19k
  {
295
7.19k
    return CLASS_DATA(elf_ident->_class, elf_ident->data);
296
7.19k
  }
297
329
  else
298
329
  {
299
329
    return 0;
300
329
  }
301
7.51k
}
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
5.30M
{
309
5.30M
  return ptr >= base && ptr_size <= size &&
310
5.29M
         ((char*) ptr) + ptr_size <= ((char*) base) + size;
311
5.30M
}
312
313
#define IS_VALID_PTR(base, size, ptr) \
314
5.30M
  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
447k
{
325
447k
  size_t len;
326
447k
  const char* str_entry;
327
328
447k
  if (str_table_base >= str_table_limit)
329
43.6k
    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
403k
  if (*str_table_base != '\0')
334
51.8k
    return NULL;
335
336
351k
  if (index < 0)
337
49.9k
    return NULL;
338
339
301k
  str_entry = str_table_base + index;
340
341
301k
  if (str_entry >= str_table_limit)
342
132k
    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.41k
    return NULL;
349
350
165k
  return str_entry;
351
168k
}
352
353
#define ELF_SIZE_OF_SECTION_TABLE(bits, bo, h) \
354
8.76k
  (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
2.19k
  (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
6.23k
  {                                                                                \
363
6.23k
    if (yr_##bo##16toh(elf_header->type) == ELF_ET_EXEC)                           \
364
6.23k
    {                                                                              \
365
1.39k
      int i;                                                                       \
366
1.39k
                                                                                   \
367
1.39k
      elf##bits##_program_header_t* program;                                       \
368
1.39k
                                                                                   \
369
1.39k
      /* check that ph_offset doesn't wrap when added to SIZE_OF_PROGRAM_TABLE     \
370
1.39k
       */                                                                          \
371
1.39k
                                                                                   \
372
1.39k
      if (ULONG_MAX - yr_##bo##bits##toh(elf_header->ph_offset) <                  \
373
1.39k
          ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, elf_header))                         \
374
1.39k
      {                                                                            \
375
11
        return YR_UNDEFINED;                                                       \
376
11
      }                                                                            \
377
1.39k
                                                                                   \
378
1.39k
      if (yr_##bo##bits##toh(elf_header->ph_offset) == 0 ||                        \
379
1.38k
          yr_##bo##bits##toh(elf_header->ph_offset) > elf_size ||                  \
380
1.38k
          yr_##bo##bits##toh(elf_header->ph_offset) +                              \
381
807
                  ELF_SIZE_OF_PROGRAM_TABLE(bits, bo, elf_header) >                \
382
807
              elf_size ||                                                          \
383
1.38k
          yr_##bo##16toh(elf_header->ph_entry_count) == 0)                         \
384
1.38k
      {                                                                            \
385
709
        return YR_UNDEFINED;                                                       \
386
709
      }                                                                            \
387
1.38k
                                                                                   \
388
1.38k
      program = (elf##bits##_program_header_t*)                                  \
389
671
        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->ph_offset)); \
390
671
                                                                                   \
391
24.6k
      for (i = 0; i < yr_##bo##16toh(elf_header->ph_entry_count); i++)             \
392
24.2k
      {                                                                            \
393
24.2k
        if (rva >= yr_##bo##bits##toh(program->virt_addr) &&                       \
394
24.2k
            rva < yr_##bo##bits##toh(program->virt_addr) +                         \
395
22.1k
                      yr_##bo##bits##toh(program->mem_size))                       \
396
24.2k
        {                                                                          \
397
185
          return yr_##bo##bits##toh(program->offset) +                             \
398
185
                 (rva - yr_##bo##bits##toh(program->virt_addr));                   \
399
185
        }                                                                          \
400
24.2k
                                                                                   \
401
24.2k
        program++;                                                                 \
402
24.0k
      }                                                                            \
403
671
    }                                                                              \
404
6.23k
    else                                                                           \
405
6.23k
    {                                                                              \
406
4.84k
      int i;                                                                       \
407
4.84k
                                                                                   \
408
4.84k
      elf##bits##_section_header_t* section;                                       \
409
4.84k
                                                                                   \
410
4.84k
      /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE     \
411
4.84k
       */                                                                          \
412
4.84k
                                                                                   \
413
4.84k
      if (ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                  \
414
4.84k
          ELF_SIZE_OF_SECTION_TABLE(bits, bo, elf_header))                         \
415
4.84k
      {                                                                            \
416
20
        return YR_UNDEFINED;                                                       \
417
20
      }                                                                            \
418
4.84k
                                                                                   \
419
4.84k
      if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                        \
420
4.82k
          yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                  \
421
4.82k
          yr_##bo##bits##toh(elf_header->sh_offset) +                              \
422
3.91k
                  ELF_SIZE_OF_SECTION_TABLE(bits, bo, elf_header) >                \
423
3.91k
              elf_size ||                                                          \
424
4.82k
          yr_##bo##16toh(elf_header->sh_entry_count) == 0)                         \
425
4.82k
      {                                                                            \
426
1.10k
        return YR_UNDEFINED;                                                       \
427
1.10k
      }                                                                            \
428
4.82k
                                                                                   \
429
4.82k
      section = (elf##bits##_section_header_t*)                                  \
430
3.72k
        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset)); \
431
3.72k
                                                                                   \
432
62.5k
      for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)             \
433
60.4k
      {                                                                            \
434
60.4k
        if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                       \
435
60.4k
            yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                     \
436
60.4k
            rva >= yr_##bo##bits##toh(section->addr) &&                            \
437
60.4k
            rva < yr_##bo##bits##toh(section->addr) +                              \
438
33.9k
                      yr_##bo##bits##toh(section->size))                           \
439
60.4k
        {                                                                          \
440
1.64k
          return yr_##bo##bits##toh(section->offset) +                             \
441
1.64k
                 (rva - yr_##bo##bits##toh(section->addr));                        \
442
1.64k
        }                                                                          \
443
60.4k
                                                                                   \
444
60.4k
        section++;                                                                 \
445
58.7k
      }                                                                            \
446
3.72k
    }                                                                              \
447
6.23k
    return YR_UNDEFINED;                                                           \
448
6.23k
  }
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
6.46k
  {                                                                                       \
459
6.46k
    unsigned int i, j, m;                                                                 \
460
6.46k
    const char* elf_raw = (const char*) elf;                                              \
461
6.46k
    uint16_t str_table_index = yr_##bo##16toh(elf->sh_str_table_index);                   \
462
6.46k
                                                                                          \
463
6.46k
    const char* sym_table = NULL;                                                         \
464
6.46k
    const char* sym_str_table = NULL;                                                     \
465
6.46k
    const char* dyn_sym_table = NULL;                                                     \
466
6.46k
    const char* dyn_sym_str_table = NULL;                                                 \
467
6.46k
                                                                                          \
468
6.46k
    uint##bits##_t sym_table_size = 0;                                                    \
469
6.46k
    uint##bits##_t sym_str_table_size = 0;                                                \
470
6.46k
    uint##bits##_t dyn_sym_table_size = 0;                                                \
471
6.46k
    uint##bits##_t dyn_sym_str_table_size = 0;                                            \
472
6.46k
                                                                                          \
473
6.46k
    elf_data->symtab = elf_data->dynsym = NULL;                                           \
474
6.46k
                                                                                          \
475
6.46k
    elf##bits##_section_header_t* section_table;                                          \
476
6.46k
    elf##bits##_section_header_t* section;                                                \
477
6.46k
    elf##bits##_program_header_t* segment;                                                \
478
6.46k
                                                                                          \
479
6.46k
    yr_set_integer(yr_##bo##16toh(elf->type), elf_obj, "type");                           \
480
6.46k
    yr_set_integer(yr_##bo##16toh(elf->machine), elf_obj, "machine");                     \
481
6.46k
    yr_set_integer(yr_##bo##bits##toh(elf->sh_offset), elf_obj, "sh_offset");             \
482
6.46k
    yr_set_integer(                                                                       \
483
6.46k
        yr_##bo##16toh(elf->sh_entry_size), elf_obj, "sh_entry_size");                    \
484
6.46k
    yr_set_integer(                                                                       \
485
6.46k
        yr_##bo##16toh(elf->sh_entry_count), elf_obj, "number_of_sections");              \
486
6.46k
    yr_set_integer(yr_##bo##bits##toh(elf->ph_offset), elf_obj, "ph_offset");             \
487
6.46k
    yr_set_integer(                                                                       \
488
6.46k
        yr_##bo##16toh(elf->ph_entry_size), elf_obj, "ph_entry_size");                    \
489
6.46k
    yr_set_integer(                                                                       \
490
6.46k
        yr_##bo##16toh(elf->ph_entry_count), elf_obj, "number_of_segments");              \
491
6.46k
                                                                                          \
492
6.46k
    if (yr_##bo##bits##toh(elf->entry) != 0)                                              \
493
6.46k
    {                                                                                     \
494
6.23k
      yr_set_integer(                                                                     \
495
6.23k
          flags& SCAN_FLAGS_PROCESS_MEMORY                                                \
496
6.23k
              ? base_address + yr_##bo##bits##toh(elf->entry)                             \
497
6.23k
              : elf_rva_to_offset_##bits##_##bo(                                          \
498
6.23k
                    elf, yr_##bo##bits##toh(elf->entry), elf_size),                       \
499
6.23k
          elf_obj,                                                                        \
500
6.23k
          "entry_point");                                                                 \
501
6.23k
    }                                                                                     \
502
6.46k
                                                                                          \
503
6.46k
    if (yr_##bo##16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&                        \
504
6.46k
        str_table_index < yr_##bo##16toh(elf->sh_entry_count) &&                          \
505
6.46k
        yr_##bo##bits##toh(elf->sh_offset) < elf_size &&                                  \
506
6.46k
        yr_##bo##bits##toh(elf->sh_offset) +                                              \
507
4.16k
                yr_##bo##16toh(elf->sh_entry_count) *                                     \
508
4.16k
                    sizeof(elf##bits##_section_header_t) <=                               \
509
4.16k
            elf_size)                                                                     \
510
6.46k
    {                                                                                     \
511
3.95k
      const char* str_table = NULL;                                                       \
512
3.95k
                                                                                          \
513
3.95k
      section_table =                                                                     \
514
3.95k
          (elf##bits##_section_header_t*) (elf_raw + yr_##bo##bits##toh(elf->sh_offset)); \
515
3.95k
                                                                                          \
516
3.95k
      if (yr_##bo##bits##toh(section_table[str_table_index].offset) <                     \
517
3.95k
          elf_size)                                                                       \
518
3.95k
      {                                                                                   \
519
2.04k
        str_table = elf_raw +                                                             \
520
2.04k
                    yr_##bo##bits##toh(section_table[str_table_index].offset);            \
521
2.04k
      }                                                                                   \
522
3.95k
                                                                                          \
523
3.95k
      section = section_table;                                                            \
524
3.95k
                                                                                          \
525
835k
      for (i = 0; i < yr_##bo##16toh(elf->sh_entry_count); i++, section++)                \
526
831k
      {                                                                                   \
527
831k
        yr_set_integer(                                                                   \
528
831k
            yr_##bo##32toh(section->type), elf_obj, "sections[%i].type", i);              \
529
831k
        yr_set_integer(                                                                   \
530
831k
            yr_##bo##bits##toh(section->flags),                                           \
531
831k
            elf_obj,                                                                      \
532
831k
            "sections[%i].flags",                                                         \
533
831k
            i);                                                                           \
534
831k
        yr_set_integer(                                                                   \
535
831k
            yr_##bo##bits##toh(section->addr),                                            \
536
831k
            elf_obj,                                                                      \
537
831k
            "sections[%i].address",                                                       \
538
831k
            i);                                                                           \
539
831k
        yr_set_integer(                                                                   \
540
831k
            yr_##bo##bits##toh(section->size),                                            \
541
831k
            elf_obj,                                                                      \
542
831k
            "sections[%i].size",                                                          \
543
831k
            i);                                                                           \
544
831k
        yr_set_integer(                                                                   \
545
831k
            yr_##bo##bits##toh(section->offset),                                          \
546
831k
            elf_obj,                                                                      \
547
831k
            "sections[%i].offset",                                                        \
548
831k
            i);                                                                           \
549
831k
                                                                                          \
550
831k
        if (yr_##bo##32toh(section->name) < elf_size && str_table > elf_raw)              \
551
831k
        {                                                                                 \
552
118k
          const char* section_name = str_table_entry(                                     \
553
118k
              str_table, elf_raw + elf_size, yr_##bo##32toh(section->name));              \
554
118k
                                                                                          \
555
118k
          if (section_name)                                                               \
556
118k
            yr_set_string(section_name, elf_obj, "sections[%i].name", i);                 \
557
118k
        }                                                                                 \
558
831k
                                                                                          \
559
831k
        if (yr_##bo##32toh(section->type) == ELF_SHT_SYMTAB &&                            \
560
831k
            yr_##bo##32toh(section->link) < elf->sh_entry_count)                          \
561
831k
        {                                                                                 \
562
12.0k
          elf##bits##_section_header_t* string_section = section_table +                  \
563
12.0k
                                                         yr_##bo##32toh(                  \
564
12.0k
                                                             section->link);              \
565
12.0k
                                                                                          \
566
12.0k
          if (IS_VALID_PTR(elf, elf_size, string_section) &&                              \
567
12.0k
              yr_##bo##32toh(string_section->type) == ELF_SHT_STRTAB)                     \
568
12.0k
          {                                                                               \
569
6.17k
            sym_table = elf_raw + yr_##bo##bits##toh(section->offset);                    \
570
6.17k
            sym_str_table = elf_raw +                                                     \
571
6.17k
                            yr_##bo##bits##toh(string_section->offset);                   \
572
6.17k
            sym_table_size = yr_##bo##bits##toh(section->size);                           \
573
6.17k
            sym_str_table_size = yr_##bo##bits##toh(string_section->size);                \
574
6.17k
          }                                                                               \
575
12.0k
        }                                                                                 \
576
831k
                                                                                          \
577
831k
        if (yr_##bo##32toh(section->type) == ELF_SHT_DYNSYM &&                            \
578
831k
            yr_##bo##32toh(section->link) < elf->sh_entry_count)                          \
579
831k
        {                                                                                 \
580
5.40k
          elf##bits##_section_header_t* dynstr_section = section_table +                  \
581
5.40k
                                                         yr_##bo##32toh(                  \
582
5.40k
                                                             section->link);              \
583
5.40k
                                                                                          \
584
5.40k
          if (IS_VALID_PTR(elf, elf_size, dynstr_section) &&                              \
585
5.40k
              yr_##bo##32toh(dynstr_section->type) == ELF_SHT_STRTAB)                     \
586
5.40k
          {                                                                               \
587
2.62k
            dyn_sym_table = elf_raw + yr_##bo##bits##toh(section->offset);                \
588
2.62k
            dyn_sym_str_table = elf_raw +                                                 \
589
2.62k
                                yr_##bo##bits##toh(dynstr_section->offset);               \
590
2.62k
            dyn_sym_table_size = yr_##bo##bits##toh(section->size);                       \
591
2.62k
            dyn_sym_str_table_size = yr_##bo##bits##toh(dynstr_section->size);            \
592
2.62k
          }                                                                               \
593
5.40k
        }                                                                                 \
594
831k
      }                                                                                   \
595
3.95k
                                                                                          \
596
3.95k
      if (is_valid_ptr(elf, elf_size, sym_str_table, sym_str_table_size) &&               \
597
3.95k
          is_valid_ptr(elf, elf_size, sym_table, sym_table_size))                         \
598
3.95k
      {                                                                                   \
599
567
        elf##bits##_sym_t* sym = (elf##bits##_sym_t*) sym_table;                          \
600
567
        elf_data->symtab = (ELF_SYMBOL_LIST*) yr_malloc(                                  \
601
567
            sizeof(ELF_SYMBOL_LIST));                                                     \
602
567
                                                                                          \
603
567
        if (elf_data->symtab == NULL)                                                     \
604
567
          return ERROR_INSUFFICIENT_MEMORY;                                               \
605
567
                                                                                          \
606
567
        ELF_SYMBOL** symbol = &(elf_data->symtab->symbols);                               \
607
567
        *symbol = NULL;                                                                   \
608
567
                                                                                          \
609
100k
        for (j = 0; j < sym_table_size / sizeof(elf##bits##_sym_t);                       \
610
99.7k
             j++, sym++)                                                                  \
611
99.7k
        {                                                                                 \
612
99.7k
          *symbol = (ELF_SYMBOL*) yr_malloc(sizeof(ELF_SYMBOL));                          \
613
99.7k
          if (*symbol == NULL)                                                            \
614
99.7k
            return ERROR_INSUFFICIENT_MEMORY;                                             \
615
99.7k
                                                                                          \
616
99.7k
          (*symbol)->name = NULL;                                                         \
617
99.7k
          (*symbol)->next = NULL;                                                         \
618
99.7k
                                                                                          \
619
99.7k
          const char* sym_name = str_table_entry(                                         \
620
99.7k
              sym_str_table,                                                              \
621
99.7k
              sym_str_table + sym_str_table_size,                                         \
622
99.7k
              yr_##bo##32toh(sym->name));                                                 \
623
99.7k
                                                                                          \
624
99.7k
          if (sym_name)                                                                   \
625
99.7k
          {                                                                               \
626
27.8k
            yr_set_string(sym_name, elf_obj, "symtab[%i].name", j);                       \
627
27.8k
            (*symbol)->name = (char*) yr_malloc(strlen(sym_name) + 1);                    \
628
27.8k
            if ((*symbol)->name == NULL)                                                  \
629
27.8k
              return ERROR_INSUFFICIENT_MEMORY;                                           \
630
27.8k
                                                                                          \
631
27.8k
            strcpy((*symbol)->name, sym_name);                                            \
632
27.8k
          }                                                                               \
633
99.7k
                                                                                          \
634
99.7k
          int bind = sym->info >> 4;                                                      \
635
99.7k
          (*symbol)->bind = bind;                                                         \
636
99.7k
          yr_set_integer(bind, elf_obj, "symtab[%i].bind", j);                            \
637
99.7k
                                                                                          \
638
99.7k
          int type = sym->info & 0xf;                                                     \
639
99.7k
          (*symbol)->type = type;                                                         \
640
99.7k
          yr_set_integer(type, elf_obj, "symtab[%i].type", j);                            \
641
99.7k
                                                                                          \
642
99.7k
          int shndx = yr_##bo##16toh(sym->shndx);                                         \
643
99.7k
          (*symbol)->shndx = shndx;                                                       \
644
99.7k
          yr_set_integer(shndx, elf_obj, "symtab[%i].shndx", j);                          \
645
99.7k
                                                                                          \
646
99.7k
          int value = yr_##bo##bits##toh(sym->value);                                     \
647
99.7k
          (*symbol)->value = value;                                                       \
648
99.7k
          yr_set_integer(                                                                 \
649
99.7k
              yr_##bo##bits##toh(sym->value), elf_obj, "symtab[%i].value", j);            \
650
99.7k
                                                                                          \
651
99.7k
          int size = yr_##bo##bits##toh(sym->size);                                       \
652
99.7k
          (*symbol)->size = size;                                                         \
653
99.7k
          yr_set_integer(                                                                 \
654
99.7k
              yr_##bo##bits##toh(sym->size), elf_obj, "symtab[%i].size", j);              \
655
99.7k
                                                                                          \
656
99.7k
          (*symbol)->visibility = sym->other & 0x3;                                       \
657
99.7k
                                                                                          \
658
99.7k
          symbol = &((*symbol)->next);                                                    \
659
99.7k
        }                                                                                 \
660
567
                                                                                          \
661
567
        elf_data->symtab->count = j;                                                      \
662
567
        yr_set_integer(j, elf_obj, "symtab_entries");                                     \
663
567
      }                                                                                   \
664
3.95k
                                                                                          \
665
3.95k
      if (is_valid_ptr(                                                                   \
666
3.95k
              elf, elf_size, dyn_sym_str_table, dyn_sym_str_table_size) &&                \
667
3.95k
          is_valid_ptr(elf, elf_size, dyn_sym_table, dyn_sym_table_size))                 \
668
3.95k
      {                                                                                   \
669
612
        elf##bits##_sym_t* dynsym = (elf##bits##_sym_t*) dyn_sym_table;                   \
670
612
                                                                                          \
671
612
        elf_data->dynsym = (ELF_SYMBOL_LIST*) yr_malloc(                                  \
672
612
            sizeof(ELF_SYMBOL_LIST));                                                     \
673
612
                                                                                          \
674
612
        if (elf_data->dynsym == NULL)                                                     \
675
612
          return ERROR_INSUFFICIENT_MEMORY;                                               \
676
612
                                                                                          \
677
612
        ELF_SYMBOL** symbol = &(elf_data->dynsym->symbols);                               \
678
612
        *symbol = NULL;                                                                   \
679
612
                                                                                          \
680
230k
        for (m = 0; m < dyn_sym_table_size / sizeof(elf##bits##_sym_t);                   \
681
229k
             m++, dynsym++)                                                               \
682
229k
        {                                                                                 \
683
229k
          *symbol = (ELF_SYMBOL*) yr_malloc(sizeof(ELF_SYMBOL));                          \
684
229k
          if (*symbol == NULL)                                                            \
685
229k
            return ERROR_INSUFFICIENT_MEMORY;                                             \
686
229k
                                                                                          \
687
229k
          (*symbol)->name = NULL;                                                         \
688
229k
          (*symbol)->next = NULL;                                                         \
689
229k
                                                                                          \
690
229k
          const char* dynsym_name = str_table_entry(                                      \
691
229k
              dyn_sym_str_table,                                                          \
692
229k
              dyn_sym_str_table + dyn_sym_str_table_size,                                 \
693
229k
              yr_##bo##32toh(dynsym->name));                                              \
694
229k
                                                                                          \
695
229k
          if (dynsym_name)                                                                \
696
229k
          {                                                                               \
697
46.7k
            yr_set_string(dynsym_name, elf_obj, "dynsym[%i].name", m);                    \
698
46.7k
            (*symbol)->name = (char*) yr_malloc(strlen(dynsym_name) + 1);                 \
699
46.7k
            if ((*symbol)->name == NULL)                                                  \
700
46.7k
              return ERROR_INSUFFICIENT_MEMORY;                                           \
701
46.7k
                                                                                          \
702
46.7k
            strcpy((*symbol)->name, dynsym_name);                                         \
703
46.7k
          }                                                                               \
704
229k
                                                                                          \
705
229k
          int bind = dynsym->info >> 4;                                                   \
706
229k
          (*symbol)->bind = bind;                                                         \
707
229k
          yr_set_integer(dynsym->info >> 4, elf_obj, "dynsym[%i].bind", m);               \
708
229k
                                                                                          \
709
229k
          int type = dynsym->info & 0xf;                                                  \
710
229k
          (*symbol)->type = type;                                                         \
711
229k
          yr_set_integer(dynsym->info & 0xf, elf_obj, "dynsym[%i].type", m);              \
712
229k
                                                                                          \
713
229k
          int shndx = yr_##bo##16toh(dynsym->shndx);                                      \
714
229k
          (*symbol)->shndx = shndx;                                                       \
715
229k
          yr_set_integer(                                                                 \
716
229k
              yr_##bo##16toh(dynsym->shndx), elf_obj, "dynsym[%i].shndx", m);             \
717
229k
                                                                                          \
718
229k
          int value = yr_##bo##bits##toh(dynsym->value);                                  \
719
229k
          (*symbol)->value = value;                                                       \
720
229k
          yr_set_integer(                                                                 \
721
229k
              yr_##bo##bits##toh(dynsym->value),                                          \
722
229k
              elf_obj,                                                                    \
723
229k
              "dynsym[%i].value",                                                         \
724
229k
              m);                                                                         \
725
229k
                                                                                          \
726
229k
          int size = yr_##bo##bits##toh(dynsym->size);                                    \
727
229k
          (*symbol)->size = size;                                                         \
728
229k
          yr_set_integer(                                                                 \
729
229k
              yr_##bo##bits##toh(dynsym->size),                                           \
730
229k
              elf_obj,                                                                    \
731
229k
              "dynsym[%i].size",                                                          \
732
229k
              m);                                                                         \
733
229k
                                                                                          \
734
229k
          (*symbol)->visibility = dynsym->other & 0x3;                                    \
735
229k
                                                                                          \
736
229k
          symbol = &((*symbol)->next);                                                    \
737
229k
        }                                                                                 \
738
612
                                                                                          \
739
612
        elf_data->dynsym->count = m;                                                      \
740
612
        yr_set_integer(m, elf_obj, "dynsym_entries");                                     \
741
612
      }                                                                                   \
742
3.95k
    }                                                                                     \
743
6.46k
                                                                                          \
744
6.46k
    if (yr_##bo##16toh(elf->ph_entry_count) > 0 &&                                        \
745
6.46k
        yr_##bo##16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                              \
746
6.46k
        yr_##bo##bits##toh(elf->ph_offset) < elf_size &&                                  \
747
6.46k
        yr_##bo##bits##toh(elf->ph_offset) +                                              \
748
2.42k
                yr_##bo##16toh(elf->ph_entry_count) *                                     \
749
2.42k
                    sizeof(elf##bits##_program_header_t) <=                               \
750
2.42k
            elf_size)                                                                     \
751
6.46k
    {                                                                                     \
752
1.45k
      segment =                                                                           \
753
1.45k
          (elf##bits##_program_header_t*) (elf_raw + yr_##bo##bits##toh(elf->ph_offset)); \
754
1.45k
                                                                                          \
755
822k
      for (i = 0; i < yr_##bo##16toh(elf->ph_entry_count); i++, segment++)                \
756
820k
      {                                                                                   \
757
820k
        yr_set_integer(                                                                   \
758
820k
            yr_##bo##32toh(segment->type), elf_obj, "segments[%i].type", i);              \
759
820k
        yr_set_integer(                                                                   \
760
820k
            yr_##bo##32toh(segment->flags), elf_obj, "segments[%i].flags", i);            \
761
820k
        yr_set_integer(                                                                   \
762
820k
            yr_##bo##bits##toh(segment->offset),                                          \
763
820k
            elf_obj,                                                                      \
764
820k
            "segments[%i].offset",                                                        \
765
820k
            i);                                                                           \
766
820k
        yr_set_integer(                                                                   \
767
820k
            yr_##bo##bits##toh(segment->virt_addr),                                       \
768
820k
            elf_obj,                                                                      \
769
820k
            "segments[%i].virtual_address",                                               \
770
820k
            i);                                                                           \
771
820k
        yr_set_integer(                                                                   \
772
820k
            yr_##bo##bits##toh(segment->phys_addr),                                       \
773
820k
            elf_obj,                                                                      \
774
820k
            "segments[%i].physical_address",                                              \
775
820k
            i);                                                                           \
776
820k
        yr_set_integer(                                                                   \
777
820k
            yr_##bo##bits##toh(segment->file_size),                                       \
778
820k
            elf_obj,                                                                      \
779
820k
            "segments[%i].file_size",                                                     \
780
820k
            i);                                                                           \
781
820k
        yr_set_integer(                                                                   \
782
820k
            yr_##bo##bits##toh(segment->mem_size),                                        \
783
820k
            elf_obj,                                                                      \
784
820k
            "segments[%i].memory_size",                                                   \
785
820k
            i);                                                                           \
786
820k
        yr_set_integer(                                                                   \
787
820k
            yr_##bo##bits##toh(segment->alignment),                                       \
788
820k
            elf_obj,                                                                      \
789
820k
            "segments[%i].alignment",                                                     \
790
820k
            i);                                                                           \
791
820k
                                                                                          \
792
820k
        if (yr_##bo##32toh(segment->type) == ELF_PT_DYNAMIC)                              \
793
820k
        {                                                                                 \
794
16.2k
          j = 0;                                                                          \
795
16.2k
          if (yr_##bo##bits##toh(segment->offset) < elf_size)                             \
796
16.2k
          {                                                                               \
797
8.92k
            elf##bits##_dyn_t* dyn =                                                      \
798
8.92k
                (elf##bits##_dyn_t*) (elf_raw + yr_##bo##bits##toh(segment->offset));     \
799
8.92k
                                                                                          \
800
5.27M
            for (j = 0; IS_VALID_PTR(elf, elf_size, dyn); dyn++, j++)                     \
801
5.27M
            {                                                                             \
802
5.27M
              yr_set_integer(                                                             \
803
5.27M
                  yr_##bo##bits##toh(dyn->tag), elf_obj, "dynamic[%i].type", j);          \
804
5.27M
              yr_set_integer(                                                             \
805
5.27M
                  yr_##bo##bits##toh(dyn->val), elf_obj, "dynamic[%i].val", j);           \
806
5.27M
                                                                                          \
807
5.27M
              if (dyn->tag == ELF_DT_NULL)                                                \
808
5.27M
              {                                                                           \
809
7.53k
                j++;                                                                      \
810
7.53k
                break;                                                                    \
811
7.53k
              }                                                                           \
812
5.27M
            }                                                                             \
813
8.92k
          }                                                                               \
814
16.2k
          yr_set_integer(j, elf_obj, "dynamic_section_entries");                          \
815
16.2k
        }                                                                                 \
816
820k
      }                                                                                   \
817
1.45k
    }                                                                                     \
818
6.46k
    return ERROR_SUCCESS;                                                                 \
819
6.46k
  }
820
821
1.22k
ELF_RVA_TO_OFFSET(32, le);
822
1.91k
ELF_RVA_TO_OFFSET(64, le);
823
1.22k
ELF_RVA_TO_OFFSET(32, be);
824
1.87k
ELF_RVA_TO_OFFSET(64, be);
825
826
1.32k
PARSE_ELF_HEADER(32, le);
827
1.93k
PARSE_ELF_HEADER(64, le);
828
1.28k
PARSE_ELF_HEADER(32, be);
829
1.92k
PARSE_ELF_HEADER(64, be);
830
831
7.54k
begin_declarations
832
7.54k
  declare_integer("ET_NONE");
833
7.54k
  declare_integer("ET_REL");
834
7.54k
  declare_integer("ET_EXEC");
835
7.54k
  declare_integer("ET_DYN");
836
7.54k
  declare_integer("ET_CORE");
837
838
7.54k
  declare_integer("EM_NONE");
839
7.54k
  declare_integer("EM_M32");
840
7.54k
  declare_integer("EM_SPARC");
841
7.54k
  declare_integer("EM_386");
842
7.54k
  declare_integer("EM_68K");
843
7.54k
  declare_integer("EM_88K");
844
7.54k
  declare_integer("EM_860");
845
7.54k
  declare_integer("EM_MIPS");
846
7.54k
  declare_integer("EM_MIPS_RS3_LE");
847
7.54k
  declare_integer("EM_PPC");
848
7.54k
  declare_integer("EM_PPC64");
849
7.54k
  declare_integer("EM_ARM");
850
7.54k
  declare_integer("EM_X86_64");
851
7.54k
  declare_integer("EM_AARCH64");
852
853
7.54k
  declare_integer("SHT_NULL");
854
7.54k
  declare_integer("SHT_PROGBITS");
855
7.54k
  declare_integer("SHT_SYMTAB");
856
7.54k
  declare_integer("SHT_STRTAB");
857
7.54k
  declare_integer("SHT_RELA");
858
7.54k
  declare_integer("SHT_HASH");
859
7.54k
  declare_integer("SHT_DYNAMIC");
860
7.54k
  declare_integer("SHT_NOTE");
861
7.54k
  declare_integer("SHT_NOBITS");
862
7.54k
  declare_integer("SHT_REL");
863
7.54k
  declare_integer("SHT_SHLIB");
864
7.54k
  declare_integer("SHT_DYNSYM");
865
866
7.54k
  declare_integer("SHF_WRITE");
867
7.54k
  declare_integer("SHF_ALLOC");
868
7.54k
  declare_integer("SHF_EXECINSTR");
869
870
7.54k
  declare_integer("type");
871
7.54k
  declare_integer("machine");
872
7.54k
  declare_integer("entry_point");
873
874
7.54k
  declare_integer("number_of_sections");
875
7.54k
  declare_integer("sh_offset");
876
7.54k
  declare_integer("sh_entry_size");
877
878
7.54k
  declare_integer("number_of_segments");
879
7.54k
  declare_integer("ph_offset");
880
7.54k
  declare_integer("ph_entry_size");
881
882
22.6k
  begin_struct_array("sections")
883
7.54k
    declare_integer("type");
884
7.54k
    declare_integer("flags");
885
7.54k
    declare_integer("address");
886
7.54k
    declare_string("name");
887
7.54k
    declare_integer("size");
888
7.54k
    declare_integer("offset");
889
15.0k
  end_struct_array("sections")
890
891
7.54k
  declare_integer("PT_NULL");
892
7.54k
  declare_integer("PT_LOAD");
893
7.54k
  declare_integer("PT_DYNAMIC");
894
7.54k
  declare_integer("PT_INTERP");
895
7.54k
  declare_integer("PT_NOTE");
896
7.54k
  declare_integer("PT_SHLIB");
897
7.54k
  declare_integer("PT_PHDR");
898
7.54k
  declare_integer("PT_TLS");
899
7.54k
  declare_integer("PT_GNU_EH_FRAME");
900
7.54k
  declare_integer("PT_GNU_STACK");
901
902
7.54k
  declare_integer("DT_NULL");
903
7.54k
  declare_integer("DT_NEEDED");
904
7.54k
  declare_integer("DT_PLTRELSZ");
905
7.54k
  declare_integer("DT_PLTGOT");
906
7.54k
  declare_integer("DT_HASH");
907
7.54k
  declare_integer("DT_STRTAB");
908
7.54k
  declare_integer("DT_SYMTAB");
909
7.54k
  declare_integer("DT_RELA");
910
7.54k
  declare_integer("DT_RELASZ");
911
7.54k
  declare_integer("DT_RELAENT");
912
7.54k
  declare_integer("DT_STRSZ");
913
7.54k
  declare_integer("DT_SYMENT");
914
7.54k
  declare_integer("DT_INIT");
915
7.54k
  declare_integer("DT_FINI");
916
7.54k
  declare_integer("DT_SONAME");
917
7.54k
  declare_integer("DT_RPATH");
918
7.54k
  declare_integer("DT_SYMBOLIC");
919
7.54k
  declare_integer("DT_REL");
920
7.54k
  declare_integer("DT_RELSZ");
921
7.54k
  declare_integer("DT_RELENT");
922
7.54k
  declare_integer("DT_PLTREL");
923
7.54k
  declare_integer("DT_DEBUG");
924
7.54k
  declare_integer("DT_TEXTREL");
925
7.54k
  declare_integer("DT_JMPREL");
926
7.54k
  declare_integer("DT_BIND_NOW");
927
7.54k
  declare_integer("DT_INIT_ARRAY");
928
7.54k
  declare_integer("DT_FINI_ARRAY");
929
7.54k
  declare_integer("DT_INIT_ARRAYSZ");
930
7.54k
  declare_integer("DT_FINI_ARRAYSZ");
931
7.54k
  declare_integer("DT_RUNPATH");
932
7.54k
  declare_integer("DT_FLAGS");
933
7.54k
  declare_integer("DT_ENCODING");
934
935
7.54k
  declare_integer("STT_NOTYPE");
936
7.54k
  declare_integer("STT_OBJECT");
937
7.54k
  declare_integer("STT_FUNC");
938
7.54k
  declare_integer("STT_SECTION");
939
7.54k
  declare_integer("STT_FILE");
940
7.54k
  declare_integer("STT_COMMON");
941
7.54k
  declare_integer("STT_TLS");
942
943
7.54k
  declare_integer("STB_LOCAL");
944
7.54k
  declare_integer("STB_GLOBAL");
945
7.54k
  declare_integer("STB_WEAK");
946
947
7.54k
  declare_integer("PF_X");
948
7.54k
  declare_integer("PF_W");
949
7.54k
  declare_integer("PF_R");
950
951
22.6k
  begin_struct_array("segments")
952
7.54k
    declare_integer("type");
953
7.54k
    declare_integer("flags");
954
7.54k
    declare_integer("offset");
955
7.54k
    declare_integer("virtual_address");
956
7.54k
    declare_integer("physical_address");
957
7.54k
    declare_integer("file_size");
958
7.54k
    declare_integer("memory_size");
959
7.54k
    declare_integer("alignment");
960
15.0k
  end_struct_array("segments")
961
962
7.54k
  declare_integer("dynamic_section_entries");
963
22.6k
  begin_struct_array("dynamic")
964
7.54k
    declare_integer("type");
965
7.54k
    declare_integer("val");
966
15.0k
  end_struct_array("dynamic")
967
968
7.54k
  declare_integer("symtab_entries");
969
22.6k
  begin_struct_array("symtab")
970
7.54k
    declare_string("name");
971
7.54k
    declare_integer("value");
972
7.54k
    declare_integer("size");
973
7.54k
    declare_integer("type");
974
7.54k
    declare_integer("bind");
975
7.54k
    declare_integer("shndx");
976
15.0k
  end_struct_array("symtab")
977
978
7.54k
  declare_integer("dynsym_entries");
979
22.6k
  begin_struct_array("dynsym")
980
7.54k
    declare_string("name");
981
7.54k
    declare_integer("value");
982
7.54k
    declare_integer("size");
983
7.54k
    declare_integer("type");
984
7.54k
    declare_integer("bind");
985
7.54k
    declare_integer("shndx");
986
15.0k
  end_struct_array("dynsym")
987
988
7.54k
  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
7.54k
end_declarations
996
997
int module_initialize(YR_MODULE* module)
998
13
{
999
13
  return ERROR_SUCCESS;
1000
13
}
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
7.53k
{
1013
7.53k
  YR_MEMORY_BLOCK* block;
1014
7.53k
  YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
1015
1016
7.53k
  elf32_header_t* elf_header32;
1017
7.53k
  elf64_header_t* elf_header64;
1018
1019
7.53k
  yr_set_integer(ELF_ET_NONE, module_object, "ET_NONE");
1020
7.53k
  yr_set_integer(ELF_ET_REL, module_object, "ET_REL");
1021
7.53k
  yr_set_integer(ELF_ET_EXEC, module_object, "ET_EXEC");
1022
7.53k
  yr_set_integer(ELF_ET_DYN, module_object, "ET_DYN");
1023
7.53k
  yr_set_integer(ELF_ET_CORE, module_object, "ET_CORE");
1024
1025
7.53k
  yr_set_integer(ELF_EM_NONE, module_object, "EM_NONE");
1026
7.53k
  yr_set_integer(ELF_EM_M32, module_object, "EM_M32");
1027
7.53k
  yr_set_integer(ELF_EM_SPARC, module_object, "EM_SPARC");
1028
7.53k
  yr_set_integer(ELF_EM_386, module_object, "EM_386");
1029
7.53k
  yr_set_integer(ELF_EM_68K, module_object, "EM_68K");
1030
7.53k
  yr_set_integer(ELF_EM_88K, module_object, "EM_88K");
1031
7.53k
  yr_set_integer(ELF_EM_860, module_object, "EM_860");
1032
7.53k
  yr_set_integer(ELF_EM_MIPS, module_object, "EM_MIPS");
1033
7.53k
  yr_set_integer(ELF_EM_MIPS_RS3_LE, module_object, "EM_MIPS_RS3_LE");
1034
7.53k
  yr_set_integer(ELF_EM_PPC, module_object, "EM_PPC");
1035
7.53k
  yr_set_integer(ELF_EM_PPC64, module_object, "EM_PPC64");
1036
7.53k
  yr_set_integer(ELF_EM_ARM, module_object, "EM_ARM");
1037
7.53k
  yr_set_integer(ELF_EM_X86_64, module_object, "EM_X86_64");
1038
7.53k
  yr_set_integer(ELF_EM_AARCH64, module_object, "EM_AARCH64");
1039
1040
7.53k
  yr_set_integer(ELF_SHT_NULL, module_object, "SHT_NULL");
1041
7.53k
  yr_set_integer(ELF_SHT_PROGBITS, module_object, "SHT_PROGBITS");
1042
7.53k
  yr_set_integer(ELF_SHT_SYMTAB, module_object, "SHT_SYMTAB");
1043
7.53k
  yr_set_integer(ELF_SHT_STRTAB, module_object, "SHT_STRTAB");
1044
7.53k
  yr_set_integer(ELF_SHT_RELA, module_object, "SHT_RELA");
1045
7.53k
  yr_set_integer(ELF_SHT_HASH, module_object, "SHT_HASH");
1046
7.53k
  yr_set_integer(ELF_SHT_DYNAMIC, module_object, "SHT_DYNAMIC");
1047
7.53k
  yr_set_integer(ELF_SHT_NOTE, module_object, "SHT_NOTE");
1048
7.53k
  yr_set_integer(ELF_SHT_NOBITS, module_object, "SHT_NOBITS");
1049
7.53k
  yr_set_integer(ELF_SHT_REL, module_object, "SHT_REL");
1050
7.53k
  yr_set_integer(ELF_SHT_SHLIB, module_object, "SHT_SHLIB");
1051
7.53k
  yr_set_integer(ELF_SHT_DYNSYM, module_object, "SHT_DYNSYM");
1052
1053
7.53k
  yr_set_integer(ELF_SHF_WRITE, module_object, "SHF_WRITE");
1054
7.53k
  yr_set_integer(ELF_SHF_ALLOC, module_object, "SHF_ALLOC");
1055
7.53k
  yr_set_integer(ELF_SHF_EXECINSTR, module_object, "SHF_EXECINSTR");
1056
1057
7.53k
  yr_set_integer(ELF_PT_NULL, module_object, "PT_NULL");
1058
7.53k
  yr_set_integer(ELF_PT_LOAD, module_object, "PT_LOAD");
1059
7.53k
  yr_set_integer(ELF_PT_DYNAMIC, module_object, "PT_DYNAMIC");
1060
7.53k
  yr_set_integer(ELF_PT_INTERP, module_object, "PT_INTERP");
1061
7.53k
  yr_set_integer(ELF_PT_NOTE, module_object, "PT_NOTE");
1062
7.53k
  yr_set_integer(ELF_PT_SHLIB, module_object, "PT_SHLIB");
1063
7.53k
  yr_set_integer(ELF_PT_PHDR, module_object, "PT_PHDR");
1064
7.53k
  yr_set_integer(ELF_PT_TLS, module_object, "PT_TLS");
1065
7.53k
  yr_set_integer(ELF_PT_GNU_EH_FRAME, module_object, "PT_GNU_EH_FRAME");
1066
7.53k
  yr_set_integer(ELF_PT_GNU_STACK, module_object, "PT_GNU_STACK");
1067
1068
7.53k
  yr_set_integer(ELF_DT_NULL, module_object, "DT_NULL");
1069
7.53k
  yr_set_integer(ELF_DT_NEEDED, module_object, "DT_NEEDED");
1070
7.53k
  yr_set_integer(ELF_DT_PLTRELSZ, module_object, "DT_PLTRELSZ");
1071
7.53k
  yr_set_integer(ELF_DT_PLTGOT, module_object, "DT_PLTGOT");
1072
7.53k
  yr_set_integer(ELF_DT_HASH, module_object, "DT_HASH");
1073
7.53k
  yr_set_integer(ELF_DT_STRTAB, module_object, "DT_STRTAB");
1074
7.53k
  yr_set_integer(ELF_DT_SYMTAB, module_object, "DT_SYMTAB");
1075
7.53k
  yr_set_integer(ELF_DT_RELA, module_object, "DT_RELA");
1076
7.53k
  yr_set_integer(ELF_DT_RELASZ, module_object, "DT_RELASZ");
1077
7.53k
  yr_set_integer(ELF_DT_RELAENT, module_object, "DT_RELAENT");
1078
7.53k
  yr_set_integer(ELF_DT_STRSZ, module_object, "DT_STRSZ");
1079
7.53k
  yr_set_integer(ELF_DT_SYMENT, module_object, "DT_SYMENT");
1080
7.53k
  yr_set_integer(ELF_DT_INIT, module_object, "DT_INIT");
1081
7.53k
  yr_set_integer(ELF_DT_FINI, module_object, "DT_FINI");
1082
7.53k
  yr_set_integer(ELF_DT_SONAME, module_object, "DT_SONAME");
1083
7.53k
  yr_set_integer(ELF_DT_RPATH, module_object, "DT_RPATH");
1084
7.53k
  yr_set_integer(ELF_DT_SYMBOLIC, module_object, "DT_SYMBOLIC");
1085
7.53k
  yr_set_integer(ELF_DT_REL, module_object, "DT_REL");
1086
7.53k
  yr_set_integer(ELF_DT_RELSZ, module_object, "DT_RELSZ");
1087
7.53k
  yr_set_integer(ELF_DT_RELENT, module_object, "DT_RELENT");
1088
7.53k
  yr_set_integer(ELF_DT_PLTREL, module_object, "DT_PLTREL");
1089
7.53k
  yr_set_integer(ELF_DT_DEBUG, module_object, "DT_DEBUG");
1090
7.53k
  yr_set_integer(ELF_DT_TEXTREL, module_object, "DT_TEXTREL");
1091
7.53k
  yr_set_integer(ELF_DT_JMPREL, module_object, "DT_JMPREL");
1092
7.53k
  yr_set_integer(ELF_DT_BIND_NOW, module_object, "DT_BIND_NOW");
1093
7.53k
  yr_set_integer(ELF_DT_INIT_ARRAY, module_object, "DT_INIT_ARRAY");
1094
7.53k
  yr_set_integer(ELF_DT_FINI_ARRAY, module_object, "DT_FINI_ARRAY");
1095
7.53k
  yr_set_integer(ELF_DT_INIT_ARRAYSZ, module_object, "DT_INIT_ARRAYSZ");
1096
7.53k
  yr_set_integer(ELF_DT_FINI_ARRAYSZ, module_object, "DT_FINI_ARRAYSZ");
1097
7.53k
  yr_set_integer(ELF_DT_RUNPATH, module_object, "DT_RUNPATH");
1098
7.53k
  yr_set_integer(ELF_DT_FLAGS, module_object, "DT_FLAGS");
1099
7.53k
  yr_set_integer(ELF_DT_ENCODING, module_object, "DT_ENCODING");
1100
1101
7.53k
  yr_set_integer(ELF_STT_NOTYPE, module_object, "STT_NOTYPE");
1102
7.53k
  yr_set_integer(ELF_STT_OBJECT, module_object, "STT_OBJECT");
1103
7.53k
  yr_set_integer(ELF_STT_FUNC, module_object, "STT_FUNC");
1104
7.53k
  yr_set_integer(ELF_STT_SECTION, module_object, "STT_SECTION");
1105
7.53k
  yr_set_integer(ELF_STT_FILE, module_object, "STT_FILE");
1106
7.53k
  yr_set_integer(ELF_STT_COMMON, module_object, "STT_COMMON");
1107
7.53k
  yr_set_integer(ELF_STT_TLS, module_object, "STT_TLS");
1108
1109
7.53k
  yr_set_integer(ELF_STB_LOCAL, module_object, "STB_LOCAL");
1110
7.53k
  yr_set_integer(ELF_STB_GLOBAL, module_object, "STB_GLOBAL");
1111
7.53k
  yr_set_integer(ELF_STB_WEAK, module_object, "STB_WEAK");
1112
1113
7.53k
  yr_set_integer(ELF_PF_X, module_object, "PF_X");
1114
7.53k
  yr_set_integer(ELF_PF_W, module_object, "PF_W");
1115
7.53k
  yr_set_integer(ELF_PF_R, module_object, "PF_R");
1116
1117
7.53k
  uint64_t parse_result = ERROR_SUCCESS;
1118
1119
7.53k
  foreach_memory_block(iterator, block)
1120
7.53k
  {
1121
7.53k
    const uint8_t* block_data = yr_fetch_block_data(block);
1122
1123
7.53k
    if (block_data == NULL)
1124
0
      continue;
1125
1126
7.53k
    ELF* elf = (ELF*) yr_calloc(1, sizeof(ELF));
1127
7.53k
    if (elf == NULL)
1128
0
      return ERROR_INSUFFICIENT_MEMORY;
1129
1130
7.53k
    module_object->data = elf;
1131
7.53k
    int class_data = get_elf_class_data(block_data, block->size);
1132
1133
7.53k
    if (class_data == CLASS_DATA(ELF_CLASS_32, ELF_DATA_2LSB) &&
1134
1.47k
        block->size > sizeof(elf32_header_t))
1135
1.32k
    {
1136
1.32k
      elf_header32 = (elf32_header_t*) block_data;
1137
1138
1.32k
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1139
0
          yr_le16toh(elf_header32->type) == ELF_ET_EXEC)
1140
1.32k
      {
1141
1.32k
        parse_result = parse_elf_header_32_le(
1142
1.32k
            elf,
1143
1.32k
            elf_header32,
1144
1.32k
            block->base,
1145
1.32k
            block->size,
1146
1.32k
            context->flags,
1147
1.32k
            module_object);
1148
1.32k
        break;
1149
1.32k
      }
1150
6.21k
    } else if (
1151
6.21k
        class_data == CLASS_DATA(ELF_CLASS_32, ELF_DATA_2MSB) &&
1152
1.34k
        block->size > sizeof(elf32_header_t))
1153
1.28k
    {
1154
1.28k
      elf_header32 = (elf32_header_t*) block_data;
1155
1156
1.28k
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1157
0
          yr_be16toh(elf_header32->type) == ELF_ET_EXEC)
1158
1.28k
      {
1159
1.28k
        parse_result = parse_elf_header_32_be(
1160
1.28k
            elf,
1161
1.28k
            elf_header32,
1162
1.28k
            block->base,
1163
1.28k
            block->size,
1164
1.28k
            context->flags,
1165
1.28k
            module_object);
1166
1.28k
        break;
1167
1.28k
      }
1168
4.93k
    } else if (
1169
4.93k
        class_data == CLASS_DATA(ELF_CLASS_64, ELF_DATA_2LSB) &&
1170
2.19k
        block->size > sizeof(elf64_header_t))
1171
1.93k
    {
1172
1.93k
      elf_header64 = (elf64_header_t*) block_data;
1173
1174
1.93k
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1175
0
          yr_le16toh(elf_header64->type) == ELF_ET_EXEC)
1176
1.93k
      {
1177
1.93k
        parse_result = parse_elf_header_64_le(
1178
1.93k
            elf,
1179
1.93k
            elf_header64,
1180
1.93k
            block->base,
1181
1.93k
            block->size,
1182
1.93k
            context->flags,
1183
1.93k
            module_object);
1184
1.93k
        break;
1185
1.93k
      }
1186
2.99k
    } else if (
1187
2.99k
        class_data == CLASS_DATA(ELF_CLASS_64, ELF_DATA_2MSB) &&
1188
2.03k
        block->size > sizeof(elf64_header_t))
1189
1.92k
    {
1190
1.92k
      elf_header64 = (elf64_header_t*) block_data;
1191
1192
1.92k
      if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
1193
0
          yr_be16toh(elf_header64->type) == ELF_ET_EXEC)
1194
1.92k
      {
1195
1.92k
        parse_result = parse_elf_header_64_be(
1196
1.92k
            elf,
1197
1.92k
            elf_header64,
1198
1.92k
            block->base,
1199
1.92k
            block->size,
1200
1.92k
            context->flags,
1201
1.92k
            module_object);
1202
1.92k
        break;
1203
1.92k
      }
1204
1.92k
    }
1205
7.53k
  }
1206
1207
7.53k
  return parse_result;
1208
7.53k
}
1209
1210
int module_unload(YR_OBJECT* module_object)
1211
7.53k
{
1212
7.53k
  ELF* elf = (ELF*) module_object->data;
1213
7.53k
  if (elf == NULL)
1214
0
    return ERROR_SUCCESS;
1215
1216
7.53k
  if (elf->symtab != NULL)
1217
567
  {
1218
567
    ELF_SYMBOL *act = NULL, *next = NULL;
1219
100k
    for (act = elf->symtab->symbols; act != NULL; act = next)
1220
99.7k
    {
1221
99.7k
      next = act->next;
1222
99.7k
      if (act->name != NULL)
1223
27.8k
        yr_free(act->name);
1224
99.7k
      yr_free(act);
1225
99.7k
    }
1226
567
    yr_free(elf->symtab);
1227
567
  }
1228
1229
7.53k
  if (elf->dynsym != NULL)
1230
612
  {
1231
612
    ELF_SYMBOL *act = NULL, *next = NULL;
1232
230k
    for (act = elf->dynsym->symbols; act != NULL; act = next)
1233
229k
    {
1234
229k
      next = act->next;
1235
229k
      if (act->name != NULL)
1236
46.7k
        yr_free(act->name);
1237
229k
      yr_free(act);
1238
229k
    }
1239
612
    yr_free(elf->dynsym);
1240
612
  }
1241
1242
7.53k
  yr_free(elf->telfhash);
1243
7.53k
  yr_free(elf->import_hash);
1244
7.53k
  yr_free(elf);
1245
1246
7.53k
  module_object->data = NULL;
1247
1248
7.53k
  return ERROR_SUCCESS;
1249
7.53k
}