Coverage Report

Created: 2026-07-16 06:12

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