Coverage Report

Created: 2025-12-14 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yara/libyara/modules.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 <yara/exec.h>
31
#include <yara/libyara.h>
32
#include <yara/modules.h>
33
34
#define MODULE(name)                             \
35
  int name##__declarations(YR_OBJECT* module);   \
36
  int name##__load(                              \
37
      YR_SCAN_CONTEXT* context,                  \
38
      YR_OBJECT* module,                         \
39
      void* module_data,                         \
40
      size_t module_data_size);                  \
41
  int name##__unload(YR_OBJECT* main_structure); \
42
  int name##__initialize(YR_MODULE* module);     \
43
  int name##__finalize(YR_MODULE* module);
44
45
#include <modules/module_list>
46
47
#undef MODULE
48
49
#define MODULE(name)     \
50
  {#name,                \
51
   name##__declarations, \
52
   name##__load,         \
53
   name##__unload,       \
54
   name##__initialize,   \
55
   name##__finalize},
56
57
YR_MODULE yr_modules_table[] = {
58
#include <modules/module_list>
59
    {NULL, NULL, NULL, NULL, NULL, NULL}};
60
61
#undef MODULE
62
63
int yr_modules_initialize()
64
11
{
65
121
  for (YR_MODULE* module = yr_modules_table; module->initialize != NULL;
66
110
       module++)
67
110
  {
68
110
    int result = module->initialize(module);
69
70
110
    if (result != ERROR_SUCCESS)
71
0
      return result;
72
110
  }
73
74
11
  return ERROR_SUCCESS;
75
11
}
76
77
int yr_modules_finalize()
78
0
{
79
0
  for (YR_MODULE* module = yr_modules_table; module->finalize != NULL; module++)
80
0
  {
81
0
    int result = module->finalize(module);
82
83
0
    if (result != ERROR_SUCCESS)
84
0
      return result;
85
0
  }
86
87
0
  return ERROR_SUCCESS;
88
0
}
89
90
int yr_modules_do_declarations(
91
    const char* module_name,
92
    YR_OBJECT* main_structure)
93
25.8k
{
94
25.8k
  for (YR_MODULE* module = yr_modules_table;
95
127k
       module->name != NULL && module->declarations != NULL;
96
102k
       module++)
97
127k
  {
98
127k
    if (strcmp(module->name, module_name) == 0)
99
25.6k
      return module->declarations(main_structure);
100
127k
  }
101
102
231
  return ERROR_UNKNOWN_MODULE;
103
25.8k
}
104
105
int yr_modules_load(const char* module_name, YR_SCAN_CONTEXT* context)
106
25.4k
{
107
25.4k
  int result;
108
109
25.4k
  YR_MODULE_IMPORT mi;
110
111
25.4k
  YR_OBJECT* module_structure = (YR_OBJECT*) yr_hash_table_lookup(
112
25.4k
      context->objects_table, module_name, NULL);
113
114
  // if module_structure != NULL, the module was already
115
  // loaded, return successfully without doing nothing.
116
117
25.4k
  if (module_structure != NULL)
118
0
    return ERROR_SUCCESS;
119
120
  // not loaded yet
121
122
25.4k
  FAIL_ON_ERROR(yr_object_create(
123
25.4k
      OBJECT_TYPE_STRUCTURE, module_name, NULL, &module_structure));
124
125
  // initialize canary for module's top-level structure, every other object
126
  // within the module inherits the same canary.
127
25.4k
  yr_object_set_canary(module_structure, context->canary);
128
129
25.4k
  mi.module_name = module_name;
130
25.4k
  mi.module_data = NULL;
131
25.4k
  mi.module_data_size = 0;
132
133
25.4k
  result = context->callback(
134
25.4k
      context, CALLBACK_MSG_IMPORT_MODULE, &mi, context->user_data);
135
136
25.4k
  if (result == CALLBACK_ERROR)
137
0
  {
138
0
    yr_object_destroy(module_structure);
139
0
    return ERROR_CALLBACK_ERROR;
140
0
  }
141
142
25.4k
  FAIL_ON_ERROR_WITH_CLEANUP(
143
25.4k
      yr_modules_do_declarations(module_name, module_structure),
144
25.4k
      yr_object_destroy(module_structure));
145
146
25.4k
  FAIL_ON_ERROR_WITH_CLEANUP(
147
25.4k
      yr_hash_table_add(
148
25.4k
          context->objects_table, module_name, NULL, module_structure),
149
25.4k
      yr_object_destroy(module_structure));
150
151
25.4k
  for (YR_MODULE* module = yr_modules_table;
152
279k
       module->name != NULL && module->load != NULL;
153
254k
       module++)
154
254k
  {
155
254k
    if (strcmp(module->name, module_name) == 0)
156
25.4k
    {
157
25.4k
      result = module->load(
158
25.4k
          context, module_structure, mi.module_data, mi.module_data_size);
159
160
25.4k
      if (result != ERROR_SUCCESS)
161
0
        return result;
162
25.4k
    }
163
254k
  }
164
165
25.4k
  result = context->callback(
166
25.4k
      context,
167
25.4k
      CALLBACK_MSG_MODULE_IMPORTED,
168
25.4k
      module_structure,
169
25.4k
      context->user_data);
170
171
25.4k
  if (result == CALLBACK_ERROR)
172
0
    return ERROR_CALLBACK_ERROR;
173
174
25.4k
  return ERROR_SUCCESS;
175
25.4k
}
176
177
int yr_modules_unload_all(YR_SCAN_CONTEXT* context)
178
25.4k
{
179
25.4k
  for (YR_MODULE* module = yr_modules_table;
180
279k
       module->name != NULL && module->unload != NULL;
181
254k
       module++)
182
254k
  {
183
254k
    YR_OBJECT* module_structure = (YR_OBJECT*) yr_hash_table_remove(
184
254k
        context->objects_table, module->name, NULL);
185
186
254k
    if (module_structure != NULL)
187
25.4k
    {
188
25.4k
      module->unload(module_structure);
189
25.4k
      yr_object_destroy(module_structure);
190
25.4k
    }
191
254k
  }
192
193
25.4k
  return ERROR_SUCCESS;
194
25.4k
}
195
196
YR_MODULE* yr_modules_get_table(void)
197
0
{
198
0
  return yr_modules_table;
199
0
}