/src/yara/libyara/modules.c
Line | Count | Source (jump to first uncovered line) |
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 | 2 | { |
65 | 22 | for (YR_MODULE* module = yr_modules_table; module->initialize != NULL; |
66 | 20 | module++) |
67 | 20 | { |
68 | 20 | int result = module->initialize(module); |
69 | | |
70 | 20 | if (result != ERROR_SUCCESS) |
71 | 0 | return result; |
72 | 20 | } |
73 | | |
74 | 2 | return ERROR_SUCCESS; |
75 | 2 | } |
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 | 4.22k | { |
94 | 4.22k | for (YR_MODULE* module = yr_modules_table; |
95 | 38.0k | module->name != NULL && module->declarations != NULL; |
96 | 33.8k | module++) |
97 | 38.0k | { |
98 | 38.0k | if (strcmp(module->name, module_name) == 0) |
99 | 4.22k | return module->declarations(main_structure); |
100 | 38.0k | } |
101 | | |
102 | 0 | return ERROR_UNKNOWN_MODULE; |
103 | 4.22k | } |
104 | | |
105 | | int yr_modules_load(const char* module_name, YR_SCAN_CONTEXT* context) |
106 | 4.22k | { |
107 | 4.22k | int result; |
108 | | |
109 | 4.22k | YR_MODULE_IMPORT mi; |
110 | | |
111 | 4.22k | YR_OBJECT* module_structure = (YR_OBJECT*) yr_hash_table_lookup( |
112 | 4.22k | 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 | 4.22k | if (module_structure != NULL) |
118 | 0 | return ERROR_SUCCESS; |
119 | | |
120 | | // not loaded yet |
121 | | |
122 | 4.22k | FAIL_ON_ERROR(yr_object_create( |
123 | 4.22k | 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 | 4.22k | yr_object_set_canary(module_structure, context->canary); |
128 | | |
129 | 4.22k | mi.module_name = module_name; |
130 | 4.22k | mi.module_data = NULL; |
131 | 4.22k | mi.module_data_size = 0; |
132 | | |
133 | 4.22k | result = context->callback( |
134 | 4.22k | context, CALLBACK_MSG_IMPORT_MODULE, &mi, context->user_data); |
135 | | |
136 | 4.22k | if (result == CALLBACK_ERROR) |
137 | 0 | { |
138 | 0 | yr_object_destroy(module_structure); |
139 | 0 | return ERROR_CALLBACK_ERROR; |
140 | 0 | } |
141 | | |
142 | 4.22k | FAIL_ON_ERROR_WITH_CLEANUP( |
143 | 4.22k | yr_modules_do_declarations(module_name, module_structure), |
144 | 4.22k | yr_object_destroy(module_structure)); |
145 | | |
146 | 4.22k | FAIL_ON_ERROR_WITH_CLEANUP( |
147 | 4.22k | yr_hash_table_add( |
148 | 4.22k | context->objects_table, module_name, NULL, module_structure), |
149 | 4.22k | yr_object_destroy(module_structure)); |
150 | | |
151 | 4.22k | for (YR_MODULE* module = yr_modules_table; |
152 | 46.4k | module->name != NULL && module->load != NULL; |
153 | 42.2k | module++) |
154 | 42.2k | { |
155 | 42.2k | if (strcmp(module->name, module_name) == 0) |
156 | 4.22k | { |
157 | 4.22k | result = module->load( |
158 | 4.22k | context, module_structure, mi.module_data, mi.module_data_size); |
159 | | |
160 | 4.22k | if (result != ERROR_SUCCESS) |
161 | 0 | return result; |
162 | 4.22k | } |
163 | 42.2k | } |
164 | | |
165 | 4.22k | result = context->callback( |
166 | 4.22k | context, |
167 | 4.22k | CALLBACK_MSG_MODULE_IMPORTED, |
168 | 4.22k | module_structure, |
169 | 4.22k | context->user_data); |
170 | | |
171 | 4.22k | if (result == CALLBACK_ERROR) |
172 | 0 | return ERROR_CALLBACK_ERROR; |
173 | | |
174 | 4.22k | return ERROR_SUCCESS; |
175 | 4.22k | } |
176 | | |
177 | | int yr_modules_unload_all(YR_SCAN_CONTEXT* context) |
178 | 4.22k | { |
179 | 4.22k | for (YR_MODULE* module = yr_modules_table; |
180 | 46.4k | module->name != NULL && module->unload != NULL; |
181 | 42.2k | module++) |
182 | 42.2k | { |
183 | 42.2k | YR_OBJECT* module_structure = (YR_OBJECT*) yr_hash_table_remove( |
184 | 42.2k | context->objects_table, module->name, NULL); |
185 | | |
186 | 42.2k | if (module_structure != NULL) |
187 | 4.22k | { |
188 | 4.22k | module->unload(module_structure); |
189 | 4.22k | yr_object_destroy(module_structure); |
190 | 4.22k | } |
191 | 42.2k | } |
192 | | |
193 | 4.22k | return ERROR_SUCCESS; |
194 | 4.22k | } |
195 | | |
196 | | YR_MODULE* yr_modules_get_table(void) |
197 | 0 | { |
198 | 0 | return yr_modules_table; |
199 | 0 | } |