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