elf_extractor.c (20814B)
1 /* 2 This file is part of libextractor. 3 Copyright (C) 2012 Vidyut Samanta and Christian Grothoff 4 5 libextractor is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 libextractor is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with libextractor; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file plugins/elf_extractor.c 22 * @brief plugin to support ELF files 23 * @author Christian Grothoff 24 */ 25 #include "platform.h" 26 #include "extractor.h" 27 #include "pack.h" 28 #include <stdint.h> 29 30 31 typedef uint32_t Elf32_Addr; 32 typedef uint16_t Elf32_Half; 33 typedef uint32_t Elf32_Off; 34 typedef int32_t Elf32_Sword; 35 typedef uint32_t Elf32_Word; 36 37 typedef uint16_t Elf64_Half; 38 typedef uint32_t Elf64_Word; 39 typedef uint64_t Elf64_Addr; 40 typedef uint64_t Elf64_Off; 41 42 /* first 4 bytes of the ELF header */ 43 static char elfMagic[] = { 0x7f, 'E', 'L', 'F' }; 44 45 #define EI_CLASS 4 46 #define EI_DATA 5 47 #define EI_VERSION 6 48 #define EI_OSABI 7 49 #define EI_NIDENT 16 50 51 typedef struct 52 { 53 Elf32_Half e_type; 54 Elf32_Half e_machine; 55 Elf32_Word e_version; 56 Elf32_Addr e_entry; 57 Elf32_Off e_phoff; 58 Elf32_Off e_shoff; /* offset of the section header table */ 59 Elf32_Word e_flags; 60 Elf32_Half e_ehsize; 61 Elf32_Half e_phensize; 62 Elf32_Half e_phnum; 63 Elf32_Half e_shentsize; /* size of each entry in SH table */ 64 Elf32_Half e_shnum; /* how many entries in section header table */ 65 Elf32_Half e_shstrndx; /* section header's sh_name member is index into this string table! */ 66 } Elf32_Ehdr; 67 68 /* elf-header minus e_ident */ 69 #define ELF_HEADER_SIZE sizeof (Elf32_Ehdr) 70 71 #define ELF_HEADER_FIELDS(p) \ 72 & (p)->e_type, \ 73 &(p)->e_machine, \ 74 &(p)->e_version, \ 75 &(p)->e_entry, \ 76 &(p)->e_phoff, \ 77 &(p)->e_shoff, \ 78 &(p)->e_flags, \ 79 &(p)->e_ehsize, \ 80 &(p)->e_phensize, \ 81 &(p)->e_phnum, \ 82 &(p)->e_shentsize, \ 83 &(p)->e_shnum, \ 84 &(p)->e_shstrndx 85 static const char *ELF_HEADER_SPECS[] = { 86 "hhwwwwwhhhhhh", 87 "HHWWWWWHHHHHH", 88 }; 89 90 typedef struct 91 { 92 Elf64_Half e_type; 93 Elf64_Half e_machine; 94 Elf64_Word e_version; 95 Elf64_Addr e_entry; 96 Elf64_Off e_phoff; 97 Elf64_Off e_shoff; 98 Elf64_Word e_flags; 99 Elf64_Half e_ehsize; 100 Elf64_Half e_phensize; 101 Elf64_Half e_phnum; 102 Elf64_Half e_shentsize; 103 Elf64_Half e_shnum; 104 Elf64_Half e_shstrndx; 105 } Elf64_Ehdr; 106 107 /* elf-header minus e_ident */ 108 #define ELF64_HEADER_SIZE sizeof (Elf64_Ehdr) 109 110 #define ELF64_HEADER_FIELDS(p) \ 111 & (p)->e_type, \ 112 &(p)->e_machine, \ 113 &(p)->e_version, \ 114 &(p)->e_entry, \ 115 &(p)->e_phoff, \ 116 &(p)->e_shoff, \ 117 &(p)->e_flags, \ 118 &(p)->e_ehsize, \ 119 &(p)->e_phensize, \ 120 &(p)->e_phnum, \ 121 &(p)->e_shentsize, \ 122 &(p)->e_shnum, \ 123 &(p)->e_shstrndx 124 static const char *ELF64_HEADER_SPECS[] = { 125 "hhwxxxwhhhhhh", 126 "HHWXXXWHHHHHH", 127 }; 128 129 130 typedef struct 131 { 132 Elf32_Word sh_name; 133 Elf32_Word sh_type; 134 Elf32_Word sh_flags; 135 Elf32_Addr sh_addr; /* where loaded */ 136 Elf32_Off sh_offset; /* where in image (! sh_type==SHT_NOBITS) */ 137 Elf32_Word sh_size; /* section size in bytes */ 138 Elf32_Word sh_link; /* for symbol table: section header index of the associated string table! */ 139 Elf32_Word sh_info; /* "one greater than the symbol table index of the last local symbol _STB_LOCAL_" */ 140 Elf32_Word sh_addralign; 141 Elf32_Word sh_entsize; 142 } Elf32_Shdr; 143 #define ELF_SECTION_SIZE 40 144 145 #define ELF_SECTION_FIELDS(p) \ 146 & (p)->sh_name, \ 147 &(p)->sh_type, \ 148 &(p)->sh_flags, \ 149 &(p)->sh_addr, \ 150 &(p)->sh_offset, \ 151 &(p)->sh_size, \ 152 &(p)->sh_link, \ 153 &(p)->sh_info, \ 154 &(p)->sh_addralign, \ 155 &(p)->sh_entsize 156 static const char *ELF_SECTION_SPECS[] = { 157 "wwwwwwwwww", 158 "WWWWWWWWWW", 159 }; 160 161 typedef struct 162 { 163 Elf32_Word p_type; 164 Elf32_Off p_offset; 165 Elf32_Addr p_vaddr; 166 Elf32_Addr p_paddr; 167 Elf32_Word p_filesz; 168 Elf32_Word p_memsz; 169 Elf32_Word p_flags; 170 Elf32_Word p_align; 171 } Elf32_Phdr; 172 #define ELF_PDHR_SIZE 32 173 #define ELF_PHDR_FIELDS(p) \ 174 & (p)->p_type, \ 175 &(p)->p_offset, \ 176 &(p)->p_vaddr, \ 177 &(p)->p_paddr, \ 178 &(p)->p_filesz, \ 179 &(p)->p_memsz, \ 180 &(p)->p_flags, \ 181 &(p)->p_align 182 static const char *ELF_PHDR_SPECS[] = { 183 "wwwwwwww", 184 "WWWWWWWW", 185 }; 186 187 typedef struct 188 { 189 Elf32_Sword d_tag; 190 union 191 { 192 Elf32_Word d_val; 193 Elf32_Addr d_ptr; 194 } d_un; 195 } Elf32_Dyn; 196 #define ELF_DYN_SIZE 8 197 #define ELF_DYN_FIELDS(p) \ 198 & (p)->d_tag, \ 199 &(p)->d_un 200 static const char *ELF_DYN_SPECS[] = { 201 "ww", 202 "WW", 203 }; 204 205 #define ET_NONE 0 206 #define ET_REL 1 207 #define ET_EXEC 2 208 #define ET_DYN 3 209 #define ET_CORE 4 210 #define ET_LOPROC 0xff00 211 #define ET_HIPROC 0xffff 212 213 #define EM_NONE 0 214 #define EM_M32 1 215 #define EM_SPARC 2 216 #define EM_386 3 217 #define EM_68K 4 218 #define EM_88K 5 219 #define EM_860 7 220 #define EM_MIPS 8 221 #define EM_PPC 20 222 #define EM_PPC64 21 223 #define EM_S390 22 224 #define EM_ARM 40 225 #define EM_ALPHA 41 226 #define EM_IA_64 50 227 #define EM_X86_64 62 228 #define EM_CUDA 190 229 230 #define ELFOSABI_NETBSD 2 231 #define ELFOSABI_LINUX 3 232 #define ELFOSABI_IRIX 8 233 #define ELFOSABI_FREEBSD 9 234 #define ELFOSABI_OPENBSD 12 235 236 #define EV_NONE 0 237 #define EV_CURRENT 1 238 239 #define SHT_NULL 0 240 #define SHT_PROGBITS 1 241 #define SHT_SYMTAB 2 242 /* string table! */ 243 #define SHT_STRTAB 3 244 #define SHT_RELA 4 245 #define SHT_HASH 5 246 /* dynamic linking info! */ 247 #define SHT_DYNAMIC 6 248 #define SHT_NOTE 7 249 #define SHT_NOBITS 8 250 #define SHT_REL 9 251 #define SHT_SHLIB 10 252 #define SHT_DYNSYM 11 253 #define SHT_LOPROC 0x70000000 254 #define SHT_HIPROC 0x7fffffff 255 #define SHT_LOUSER 0x80000000 256 #define SHT_HIUSER 0xffffffff 257 258 #define SHF_WRITE 0x1 259 #define SHF_ALLOC 0x2 260 #define SHF_EXECINSTR 0x4 261 #define SHF_MASKPROC 0xf000000 262 263 #define DT_NULL 0 264 /* name of a needed library, offset into table 265 recorded in DT_STRTAB entry */ 266 #define DT_NEEDED 1 267 #define DT_PLTRELSZ 2 268 #define DT_PLTGOT 3 269 #define DT_HASH 4 270 /* address of the string table from where symbol 271 names, library names, etc for this DT come from */ 272 #define DT_STRTAB 5 273 #define DT_SYMTAB 6 274 #define DT_SYMENT 7 275 #define DT_RELA 7 276 #define DT_RELASZ 8 277 #define DT_RELAENT 9 278 /* size of the string-table in bytes */ 279 #define DT_STRSZ 10 280 /* fixme 11 */ 281 #define DT_INIT 12 282 #define DT_FINI 13 283 /* string-table offset giving the name of the shared object */ 284 #define DT_SONAME 14 285 /* string-table offset of a null-terminated library search path */ 286 #define DT_RPATH 15 287 #define DT_SYMBOLIC 16 288 289 290 #define PT_NULL 0 291 #define PT_LOAD 1 292 #define PT_DYNAMIC 2 293 #define PT_INTERP 3 294 #define PT_NOTE 4 295 #define PT_SHLIB 5 296 #define PT_PHDR 6 297 #define PT_LOPROC 0x70000000 298 #define PT_HIPROC 0x7fffffff 299 300 301 #define ELFCLASSNONE 0 302 #define ELFCLASS32 1 303 #define ELFCLASS64 2 304 305 #define ELFDATANONE 0 306 /* little endian */ 307 #define ELFDATA2LSB 1 308 /* big endian */ 309 #define ELFDATA2MSB 2 310 311 /** 312 * @param ei_data ELFDATA2LSB or ELFDATA2MSB 313 * @return 0 for little-endian ELF (use lowercase pack specs), 314 * 1 for big-endian ELF (use uppercase pack specs) 315 */ 316 static unsigned int 317 get_byte_order (char ei_data) 318 { 319 return (ei_data == ELFDATA2LSB) ? 0 : 1; 320 } 321 322 323 /** 324 * 325 * @return 0 on success, -1 on error 326 */ 327 static int 328 get_section_header (struct EXTRACTOR_ExtractContext *ec, 329 unsigned int bo, 330 const Elf32_Ehdr *ehdr, 331 Elf32_Half idx, 332 Elf32_Shdr *ret) 333 { 334 ssize_t size; 335 uint64_t max; 336 int64_t off; 337 void *data; 338 339 if (ehdr->e_shnum <= idx) 340 return -1; 341 max = ec->get_size (ec->cls); 342 if (ehdr->e_shoff + ehdr->e_shentsize * idx + sizeof (*ret) > max) 343 return -1; 344 off = ec->seek (ec->cls, 345 ehdr->e_shoff + ehdr->e_shentsize * idx, 346 SEEK_SET); 347 if (-1 == off) 348 return -1; 349 size = ec->read (ec->cls, 350 &data, 351 sizeof (*ret)); 352 if (size < (ssize_t) sizeof (*ret)) 353 return -1; 354 EXTRACTOR_common_cat_unpack (data, 355 ELF_SECTION_SPECS[bo], 356 ELF_SECTION_FIELDS (ret)); 357 return 0; 358 } 359 360 361 /** 362 * 363 * @return 0 on success, -1 on error 364 */ 365 static int 366 getDynTag (struct EXTRACTOR_ExtractContext *ec, 367 unsigned int bo, 368 const Elf32_Ehdr *ehdr, 369 Elf32_Off off, 370 Elf32_Word osize, 371 unsigned int idx, 372 Elf32_Dyn *ret) 373 { 374 ssize_t size; 375 uint64_t max; 376 int64_t soff; 377 void *data; 378 379 max = ec->get_size (ec->cls); 380 if ( (off + osize > max) || 381 ((idx + 1) * ELF_DYN_SIZE > osize) ) 382 return -1; 383 if (off + idx * ELF_DYN_SIZE + sizeof (*ret) > max) 384 return -1; 385 soff = ec->seek (ec->cls, 386 off + idx * ELF_DYN_SIZE, 387 SEEK_SET); 388 if (-1 == soff) 389 return -1; 390 size = ec->read (ec->cls, 391 &data, 392 sizeof (*ret)); 393 if (size < (ssize_t) sizeof (*ret)) 394 return -1; 395 EXTRACTOR_common_cat_unpack (data, 396 ELF_DYN_SPECS[bo], 397 ELF_DYN_FIELDS (ret)); 398 return 0; 399 } 400 401 402 /** 403 * 404 * @return 0 on success, -1 on error 405 */ 406 static int 407 getProgramHdr (struct EXTRACTOR_ExtractContext *ec, 408 unsigned int bo, 409 const Elf32_Ehdr *ehdr, 410 Elf32_Half idx, 411 Elf32_Phdr *ret) 412 { 413 void *data; 414 ssize_t size; 415 int64_t off; 416 417 if (ehdr->e_phnum <= idx) 418 return -1; 419 off = ec->seek (ec->cls, 420 ehdr->e_phoff + ehdr->e_phensize * idx, 421 SEEK_SET); 422 if (-1 == off) 423 return -1; 424 size = ec->read (ec->cls, 425 &data, 426 sizeof (*ret)); 427 if (size < (ssize_t) sizeof (*ret)) 428 return -1; 429 EXTRACTOR_common_cat_unpack (data, 430 ELF_PHDR_SPECS[bo], 431 ELF_PHDR_FIELDS (ret)); 432 return 0; 433 } 434 435 436 /** 437 * @return the string, NULL on error; the caller must free() it 438 */ 439 static char * 440 readStringTable (struct EXTRACTOR_ExtractContext *ec, 441 unsigned int bo, 442 const Elf32_Ehdr *ehdr, 443 Elf32_Half strTableOffset, 444 Elf32_Word sh_name) 445 { 446 Elf32_Shdr shrd; 447 char *data; 448 ssize_t size; 449 int64_t off; 450 451 if (-1 == get_section_header (ec, 452 bo, 453 ehdr, 454 strTableOffset, 455 &shrd)) 456 return NULL; 457 if ((shrd.sh_type != SHT_STRTAB) || 458 (shrd.sh_size <= sh_name) ) 459 return NULL; 460 off = ec->seek (ec->cls, 461 shrd.sh_offset, 462 SEEK_SET); 463 if (-1 == off) 464 return NULL; 465 size = ec->read (ec->cls, 466 (void **) &data, 467 shrd.sh_size); 468 if (size < shrd.sh_size) 469 return NULL; 470 if (data[shrd.sh_size - 1] != '\0') 471 return NULL; 472 return strdup (&data[sh_name]); 473 } 474 475 476 #define ADD(s, type) do { \ 477 if (0!=ec->proc (ec->cls, "elf", type, \ 478 EXTRACTOR_METAFORMAT_UTF8, "text/plain", \ 479 s, strlen (s) + 1)) \ 480 { \ 481 return; \ 482 } \ 483 } while (0) 484 485 /** 486 * Like ADD(), but for a heap-allocated @a s that must be released on 487 * every path. ADD()'s early return -- taken whenever the application 488 * asks extraction to stop -- would otherwise jump over the free(). 489 */ 490 #define ADD_FREE(s, type) do { \ 491 int stop_ = (0 != ec->proc (ec->cls, "elf", type, \ 492 EXTRACTOR_METAFORMAT_UTF8, "text/plain", \ 493 s, strlen (s) + 1)); \ 494 free (s); \ 495 if (stop_) \ 496 { \ 497 return; \ 498 } \ 499 } while (0) 500 501 502 /** 503 * Main entry method for the 'application/x-executable' extraction plugin. 504 * 505 * @param ec extraction context provided to the plugin 506 */ 507 void 508 EXTRACTOR_elf_extract_method (struct EXTRACTOR_ExtractContext *ec); 509 510 void 511 EXTRACTOR_elf_extract_method (struct EXTRACTOR_ExtractContext *ec) 512 { 513 Elf32_Ehdr ehdr; 514 Elf64_Ehdr ehdr64; 515 int ret; 516 unsigned int bo; 517 char *data; 518 ssize_t size; 519 uint64_t max; 520 size_t want; 521 522 max = ec->get_size (ec->cls); 523 want = sizeof (ehdr); 524 if (sizeof (ehdr64) > want) 525 want = sizeof (ehdr64); 526 want += EI_NIDENT; 527 if (max < want) 528 return; 529 size = ec->read (ec->cls, 530 (void**) &data, 531 max); 532 if (size < EI_NIDENT) 533 return; 534 if (0 != memcmp (data, 535 elfMagic, 536 sizeof (elfMagic))) 537 return; /* not an elf */ 538 switch (data[EI_CLASS]) 539 { 540 case ELFCLASS32: 541 if (size < sizeof (Elf32_Ehdr) + EI_NIDENT) 542 return; 543 bo = get_byte_order (data[EI_DATA]); 544 EXTRACTOR_common_cat_unpack (&data[EI_NIDENT], 545 ELF_HEADER_SPECS[bo], 546 ELF_HEADER_FIELDS (&ehdr)); 547 /* e_shentsize and e_shnum are 16 bit, so both promote to `int' and 548 their product overflows for large values; compute the bound in 549 64 bit unsigned arithmetic so that the check cannot be bypassed. */ 550 if ((uint64_t) ehdr.e_shoff 551 + (uint64_t) ehdr.e_shentsize * (uint64_t) ehdr.e_shnum > max) 552 return; /* invalid offsets... */ 553 if (ehdr.e_shentsize < ELF_SECTION_SIZE) 554 return; /* huh? */ 555 if ((uint64_t) ehdr.e_phoff 556 + (uint64_t) ehdr.e_phensize * (uint64_t) ehdr.e_phnum > max) 557 return; 558 ret = 0; 559 bo = get_byte_order (data[EI_DATA]); 560 break; 561 case ELFCLASS64: 562 if (size < sizeof (Elf64_Ehdr) + EI_NIDENT) 563 return; 564 bo = get_byte_order (data[EI_DATA]); 565 EXTRACTOR_common_cat_unpack (&data[EI_NIDENT], 566 ELF64_HEADER_SPECS[bo], 567 ELF64_HEADER_FIELDS (&ehdr64)); 568 if ((uint64_t) ehdr64.e_shoff 569 + (uint64_t) ehdr64.e_shentsize * (uint64_t) ehdr64.e_shnum > max) 570 return; /* invalid offsets... */ 571 if ((uint64_t) ehdr64.e_phoff 572 + (uint64_t) ehdr64.e_phensize * (uint64_t) ehdr64.e_phnum > max) 573 return; 574 bo = get_byte_order (data[EI_DATA]); 575 ret = 1; 576 break; 577 default: 578 return; 579 } 580 581 ADD ("application/x-executable", 582 EXTRACTOR_METATYPE_MIMETYPE); 583 switch ( ((unsigned char*) data)[EI_OSABI]) 584 { 585 case ELFOSABI_LINUX: 586 ADD ("Linux", 587 EXTRACTOR_METATYPE_TARGET_OS); 588 break; 589 case ELFOSABI_FREEBSD: 590 ADD ("FreeBSD", 591 EXTRACTOR_METATYPE_TARGET_OS); 592 break; 593 case ELFOSABI_NETBSD: 594 ADD ("NetBSD", 595 EXTRACTOR_METATYPE_TARGET_OS); 596 break; 597 case ELFOSABI_OPENBSD: 598 ADD ("OpenBSD", 599 EXTRACTOR_METATYPE_TARGET_OS); 600 break; 601 case ELFOSABI_IRIX: 602 ADD ("IRIX", 603 EXTRACTOR_METATYPE_TARGET_OS); 604 break; 605 default: 606 break; 607 } 608 switch ( (0 == ret) ? ehdr.e_type : ehdr64.e_type) 609 { 610 case ET_REL: 611 ADD ("Relocatable file", 612 EXTRACTOR_METATYPE_RESOURCE_TYPE); 613 break; 614 case ET_EXEC: 615 ADD ("Executable file", 616 EXTRACTOR_METATYPE_RESOURCE_TYPE); 617 break; 618 case ET_DYN: 619 ADD ("Shared object file", 620 EXTRACTOR_METATYPE_RESOURCE_TYPE); 621 break; 622 case ET_CORE: 623 ADD ("Core file", 624 EXTRACTOR_METATYPE_RESOURCE_TYPE); 625 break; 626 default: 627 break; /* unknown */ 628 } 629 switch ( (0 == ret) ? ehdr.e_machine : ehdr64.e_machine) 630 { 631 case EM_M32: 632 ADD ("M32", 633 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 634 break; 635 case EM_386: 636 ADD ("i386", 637 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 638 break; 639 case EM_68K: 640 ADD ("68K", 641 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 642 break; 643 case EM_88K: 644 ADD ("88K", 645 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 646 break; 647 case EM_SPARC: 648 ADD ("Sparc", 649 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 650 break; 651 case EM_860: 652 ADD ("960", 653 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 654 break; 655 case EM_MIPS: 656 ADD ("MIPS", 657 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 658 break; 659 case EM_PPC: 660 ADD ("PPC", 661 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 662 break; 663 case EM_PPC64: 664 ADD ("PPC64", 665 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 666 break; 667 case EM_S390: 668 ADD ("S390", 669 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 670 break; 671 case EM_ARM: 672 ADD ("ARM", 673 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 674 break; 675 case EM_ALPHA: 676 ADD ("ALPHA", 677 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 678 break; 679 case EM_IA_64: 680 ADD ("IA-64", 681 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 682 break; 683 case EM_X86_64: 684 ADD ("x86_64", 685 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 686 break; 687 case EM_CUDA: 688 ADD ("NVIDIA CUDA", 689 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 690 break; 691 default: 692 break; /* oops */ 693 } 694 695 if (0 != ret) 696 return; /* FIXME: full support for 64-bit ELF... */ 697 for (Elf32_Half idx = 0; idx < ehdr.e_phnum; idx++) 698 { 699 Elf32_Phdr phdr; 700 701 if (0 != getProgramHdr (ec, 702 bo, 703 &ehdr, 704 idx, 705 &phdr)) 706 return; 707 if (phdr.p_type == PT_DYNAMIC) 708 { 709 unsigned int dc = phdr.p_filesz / ELF_DYN_SIZE; 710 Elf32_Addr stringPtr; 711 Elf32_Half stringIdx; 712 Elf32_Half six; 713 714 stringPtr = 0; 715 for (unsigned int id = 0; id < dc; id++) 716 { 717 Elf32_Dyn dyn; 718 719 if (0 != getDynTag (ec, 720 bo, 721 &ehdr, 722 phdr.p_offset, 723 phdr.p_filesz, 724 id, 725 &dyn)) 726 return; 727 if (DT_STRTAB == dyn.d_tag) 728 { 729 stringPtr = dyn.d_un.d_ptr; 730 break; 731 } 732 } 733 if (0 == stringPtr) 734 return; 735 for (six = 0; six < ehdr.e_shnum; six++) 736 { 737 Elf32_Shdr sec; 738 739 if (-1 == get_section_header (ec, 740 bo, 741 &ehdr, 742 six, 743 &sec)) 744 return; 745 if ( (sec.sh_addr == stringPtr) && 746 (sec.sh_type == SHT_STRTAB) ) 747 { 748 stringIdx = six; 749 break; 750 } 751 } 752 if (six == ehdr.e_shnum) 753 return; /* stringIdx not found */ 754 755 for (unsigned int id = 0; id < dc; id++) 756 { 757 Elf32_Dyn dyn; 758 759 if (0 != getDynTag (ec, 760 bo, 761 &ehdr, 762 phdr.p_offset, 763 phdr.p_filesz, 764 id, 765 &dyn)) 766 return; 767 switch (dyn.d_tag) 768 { 769 case DT_RPATH: 770 { 771 char *rpath; 772 773 rpath = readStringTable (ec, 774 bo, 775 &ehdr, 776 stringIdx, 777 dyn.d_un.d_val); 778 /* "source" of the dependencies: path 779 to dynamic libraries */ 780 if (NULL != rpath) 781 ADD_FREE (rpath, 782 EXTRACTOR_METATYPE_LIBRARY_SEARCH_PATH); 783 break; 784 } 785 case DT_NEEDED: 786 { 787 char *needed; 788 789 needed = readStringTable (ec, 790 bo, 791 &ehdr, 792 stringIdx, 793 dyn.d_un.d_val); 794 if (NULL != needed) 795 ADD_FREE (needed, 796 EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY); 797 break; 798 } 799 } 800 } 801 } 802 } 803 } 804 805 806 /* end of elf_extractor.c */