Coverage Report

Created: 2025-10-10 06:41

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