dissector.c - Coloured ELF files dissector

原文链接:https://packetstormsecurity.com/files/download/125972/dissector.c

   1 /*
   2  * dissector.c - Coloured ELF files dissector
   3  * By Alejandro Hernandez <nitr0us>
   4  *
   5  * Supported archs: x86 / x86_64
   6  *
   7  * No security in mind (No boundary checkings)
   8  * If a malformed ELF is supplied, it'll definitely segfault
   9  *
  10  * $gcc dissector.c -o dissector -Wall
  11  *
  12  * Mexico
  13  */
  14 
  15 #include <stdio.h>
  16 #include <unistd.h>
  17 #include <string.h>
  18 #include <stdlib.h>
  19 #include <getopt.h>
  20 #include <fcntl.h>
  21 #include <sys/mman.h>
  22 #include <sys/stat.h>
  23 #include <elf.h>
  24 
  25 //#ifdef    COLOURS
  26 #define RED    "\033[31m"
  27 #define WHITE    "\033[01m"
  28 #define YELLOW    "\033[33m"
  29 #define RESET    "\033[00m"
  30 //#else
  31 //#define RED    ""
  32 //#define WHITE    ""
  33 //#define YELLOW    "\033[33m"
  34 //#define RESET    ""
  35 //#endif
  36 
  37 /*** 32 - 64 BITS COMPAT ***/
  38 #if defined(__i386__)        // x86
  39 #define Elf_Half Elf32_Half
  40 #define Elf_Word Elf32_Word
  41 #define Elf_Sword Elf32_Sword
  42 #define Elf_Xword Elf32_Xword
  43 #define Elf_Sxword Elf32_Sxword
  44 #define Elf_Addr Elf32_Addr
  45 #define Elf_Off Elf32_Off
  46 #define Elf_Section Elf32_Section
  47 #define Elf_Ehdr Elf32_Ehdr
  48 #define Elf_Shdr Elf32_Shdr
  49 #define Elf_Sym Elf32_Sym
  50 #define Elf_Rel Elf32_Rel
  51 #define Elf_Rela Elf32_Rela
  52 #define Elf_Phdr Elf32_Phdr
  53 #define Elf_Dyn Elf32_Dyn
  54 #define Elf_Nhdr Elf32_Nhdr
  55 
  56 #define ELF_ST_TYPE ELF32_ST_TYPE
  57 #define ELF_ST_BIND ELF32_ST_BIND
  58 #define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY
  59 
  60 #define ELF_R_TYPE ELF32_R_TYPE
  61 #define ELF_R_SYM ELF32_R_SYM
  62 
  63 #define DEC "%d"
  64 #define HEX "%.8x"
  65 
  66 #define SPACE    ""
  67 
  68 #elif defined(__x86_64__)    // x86_64
  69 #define Elf_Half Elf64_Half
  70 #define Elf_Word Elf64_Word
  71 #define Elf_Sword Elf64_Sword
  72 #define Elf_Xword Elf64_Xword
  73 #define Elf_Sxword Elf64_Sxword
  74 #define Elf_Addr Elf64_Addr
  75 #define Elf_Off Elf64_Off
  76 #define Elf_Section Elf64_Section
  77 #define Elf_Ehdr Elf64_Ehdr
  78 #define Elf_Shdr Elf64_Shdr
  79 #define Elf_Sym Elf64_Sym
  80 #define Elf_Rel Elf64_Rel
  81 #define Elf_Rela Elf64_Rela
  82 #define Elf_Phdr Elf64_Phdr
  83 #define Elf_Dyn Elf64_Dyn
  84 #define Elf_Nhdr Elf64_Nhdr
  85 
  86 #define ELF_ST_TYPE ELF64_ST_TYPE
  87 #define ELF_ST_BIND ELF64_ST_BIND
  88 #define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY
  89 
  90 #define ELF_R_TYPE ELF64_R_TYPE
  91 #define ELF_R_SYM ELF64_R_SYM
  92 
  93 #define DEC "%ld"
  94 #define HEX "%.16lx"
  95 
  96 #define SPACE    "        " // Used to align the view when printing 64 or 32 bit variables
  97 #else
  98 #error  "Unsupported arch"
  99 #endif
 100 /*** 32 - 64 BITS COMPAT ***/
 101 
 102 
 103 /* MODES */
 104 #define    HEADER    (1 << 0)
 105 #define    SECTION    (1 << 1)
 106 #define    PROGRAM    (1 << 2)
 107 #define    SYMBOL    (1 << 3)
 108 #define DYNAMIC (1 << 4)
 109 #define RELOC    (1 << 5)
 110 #define NOTES    (1 << 6)
 111 #define ALL    (HEADER + SECTION + PROGRAM + SYMBOL + DYNAMIC + RELOC + NOTES)
 112 
 113 /* PROTOTYPES */
 114 void usage(const char *);
 115 void banner();
 116 int  elf_identification(int);
 117 void elf_header(Elf_Ehdr);
 118 void sht(char *);
 119 void pht(char *);
 120 void symbols(char *);
 121 void dynamic(char *);
 122 void relocations(char *);
 123 void notes(char *);
 124 
 125 int    numeric = 0;
 126 int    shstrtab_offset = 0;
 127 
 128 int main(int argc, char **argv)
 129 {
 130     int        fd, opt, mode = 0;
 131     char        *elfptr;
 132     struct stat    statinfo;
 133     Elf_Ehdr    header;
 134     Elf_Shdr    shstrtab_section;
 135 
 136     if(argc < 3)
 137         usage(argv[0]);
 138 
 139     while((opt = getopt(argc, argv, "naHSPsDRhN")) != EOF)
 140         switch(opt){
 141                 case 'n':
 142                     numeric = 1;
 143                     break;
 144                 case 'a':
 145                     mode |= ALL;
 146                     break;
 147                 case 'H':
 148                     mode |= HEADER;
 149                     break;
 150                 case 'S':
 151                     mode |= SECTION;
 152                     break;
 153                 case 'P':
 154                     mode |= PROGRAM;
 155                     break;
 156                 case 's':
 157                     mode |= SYMBOL;
 158                     break;
 159                 case 'D':
 160                     mode |= DYNAMIC;
 161                     break;
 162                 case 'R':
 163                     mode |= RELOC;
 164                     break;
 165                 case 'N':
 166                     mode |= NOTES;
 167                     break;
 168                 case 'h':
 169                 default:
 170                     usage(argv[0]);
 171         }
 172 
 173     if(argv[optind] == NULL){
 174         fprintf(stderr, "Give me an ELF file\n");
 175         usage(argv[0]);
 176     }
 177 
 178     if((fd = open(argv[optind], O_RDONLY)) == -1){
 179         perror("open");
 180         exit(-1);
 181     }
 182 
 183     if(!elf_identification(fd)){
 184         fprintf(stderr, "This is not a supported ELF file\n");
 185         exit(-1);
 186     }
 187 
 188     if(fstat(fd, &statinfo) == -1){
 189         perror("stat");
 190         close(fd);
 191         exit(-1);
 192     }
 193 
 194     if((elfptr = (char *) mmap(NULL, statinfo.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED){
 195         perror("mmap");
 196         close(fd);
 197         exit(-1);
 198     }
 199 
 200     close(fd);
 201 
 202     header = *(Elf_Ehdr *) elfptr;
 203     shstrtab_section = *(Elf_Shdr *) (elfptr + header.e_shoff + header.e_shstrndx * sizeof(Elf_Shdr));
 204     if(shstrtab_section.sh_size > 0)
 205         shstrtab_offset  = shstrtab_section.sh_offset;
 206 
 207     if(mode & HEADER){
 208         printf("\n%sELF HEADER:%s\n", RED, RESET);
 209         elf_header(header);
 210     }
 211 
 212     if(mode & SECTION){
 213         printf("\n%sSECTION HEADER TABLE:%s\n", RED, RESET);
 214         if(header.e_shoff == 0)
 215             printf("[%sNO SECTION HEADER TABLE FOUND%s]\n", WHITE, RESET);
 216         else
 217             sht(elfptr);
 218     }
 219 
 220     if(mode & PROGRAM){
 221         printf("\n%sPROGRAM HEADER TABLE:%s\n", RED, RESET);
 222         pht(elfptr);
 223     }
 224 
 225     if(mode & SYMBOL){
 226         printf("\n%sSYMBOL TABLE:%s\n", RED, RESET);
 227         symbols(elfptr);
 228     }
 229 
 230     if(mode & DYNAMIC){
 231         printf("\n%sDYNAMIC INFORMATION:%s\n", RED, RESET);
 232         dynamic(elfptr);
 233     }
 234 
 235     if(mode & RELOC){
 236         printf("\n%sRELOCATIONS:%s\n", RED, RESET);
 237         relocations(elfptr);
 238     }
 239 
 240     if(mode & NOTES){
 241         printf("\n%sNOTES:%s\n", RED, RESET);
 242         notes(elfptr);
 243     }
 244 
 245     munmap(elfptr, statinfo.st_size);
 246     return 0;
 247 }
 248 
 249 void usage(const char *self)
 250 {
 251     banner();
 252 
 253     fprintf(stderr, "Usage: %s [-n] <options> <elf_file>\n", self);
 254     fprintf(stderr, "\tOptions:\n");
 255     fprintf(stderr, "\t-n\tPrint everything in numeric values\n");
 256     fprintf(stderr, "\t-a\tAll(-HSPsdr)\n");
 257     fprintf(stderr, "\t-H\tELF header\n");
 258     fprintf(stderr, "\t-S\tSection headers\n");
 259     fprintf(stderr, "\t-P\tProgram headers\n");
 260     fprintf(stderr, "\t-s\tSymbol Table\n");
 261     fprintf(stderr, "\t-D\tDynamic information\n");
 262     fprintf(stderr, "\t-R\tRelocations\n");
 263     fprintf(stderr, "\t-N\tNotes\n");
 264     fprintf(stderr, "\t-h\tThis help\n");
 265     exit(0);
 266 }
 267 
 268 void banner()
 269 {
 270     printf("%s######################################################%s\n", RED, RESET);
 271     printf("%s##%s%s         ELF ( x86 / x86_64 ) Dissector           %s%s##%s\n", RED, RESET, YELLOW, RESET, RED, RESET);
 272     printf("%s##%s%s                  by nitr0us                      %s%s##%s\n", RED, RESET, YELLOW, RESET, RED, RESET);
 273     printf("%s######################################################%s\n\n", RED, RESET);
 274 }
 275 
 276 int elf_identification(int fd)
 277 {
 278     Elf_Ehdr    header;
 279 
 280     if(read(fd, &header, sizeof(header)) == -1){
 281         perror("elf_identification: read");
 282         return 0;
 283     }
 284 
 285     /* magic number verification */
 286     if(header.e_ident[EI_MAG0] != ELFMAG0 ||
 287             header.e_ident[EI_MAG1] != ELFMAG1 ||
 288             header.e_ident[EI_MAG2] != ELFMAG2 ||
 289             header.e_ident[EI_MAG3] != ELFMAG3){
 290         fprintf(stderr, "elf_identification: Invalid MAGIC Number\n");
 291         return 0;
 292     }
 293 
 294     return 1;
 295 }
 296 
 297 void elf_header(Elf_Ehdr hdr)
 298 {
 299     int        k;
 300 
 301     printf("%se_ident:%s\t\t", WHITE, RESET);
 302     for(k = 0; k < EI_NIDENT; k++)
 303         printf("%.2x ", hdr.e_ident[k]);
 304 
 305     printf("\n%se_ident[EI_CLASS]:%s\t", WHITE, RESET);
 306     if(numeric)
 307         printf("0x%.2x", hdr.e_ident[EI_CLASS]);
 308     else
 309         switch(hdr.e_ident[EI_CLASS]){
 310             case ELFCLASSNONE:
 311                 printf("ELFCLASSNONE");
 312                 break;
 313             case ELFCLASS32:
 314                 printf("ELFCLASS32");
 315                 break;
 316             case ELFCLASS64:
 317                 printf("ELFCLASS64");
 318                 break;
 319             default:
 320                 printf("%sINVALID CLASS%s (0x%x)", RED, RESET, hdr.e_ident[EI_CLASS]);
 321         }
 322 
 323     printf("\n%se_ident[EI_DATA]:%s\t", WHITE, RESET);
 324     if(numeric)
 325         printf("0x%.2x", hdr.e_ident[EI_DATA]);
 326     else
 327         switch(hdr.e_ident[EI_DATA]){
 328             case ELFDATANONE:
 329                 printf("ELFDATANONE");
 330                 break;
 331             case ELFDATA2LSB:
 332                 printf("ELFDATA2LSB");
 333                 break;
 334             case ELFDATA2MSB:
 335                 printf("ELFDATA2MSB");
 336                 break;
 337             default:
 338                 printf("%sINVALID DATA%s (0x%x)", RED, RESET, hdr.e_ident[EI_DATA]);
 339         }
 340 
 341     printf("\n%se_ident[EI_VERSION]:%s\t", WHITE, RESET);
 342     if(numeric)
 343         printf("0x%.2x", hdr.e_ident[EI_VERSION]);
 344     else{
 345         if(hdr.e_ident[EI_VERSION] == EV_CURRENT)
 346             printf("EV_CURRENT");
 347         else
 348             printf("%sINVALID VERSION%s (0x%x)", RED, RESET, hdr.e_ident[EI_VERSION]);
 349     }
 350 
 351     printf("\n%se_ident[EI_OSABI]:%s\t", WHITE, RESET);
 352     if(numeric)
 353         printf("0x%.2x", hdr.e_ident[EI_OSABI]);
 354     else
 355         switch(hdr.e_ident[EI_OSABI]){
 356             case ELFOSABI_SYSV:
 357                 printf("ELFOSABI_SYSV");
 358                 break;
 359             case ELFOSABI_NETBSD:
 360                 printf("ELFOSABI_NETBSD");
 361                 break;
 362             case ELFOSABI_OPENBSD:
 363                 printf("ELFOSABI_OPENBSD");
 364                 break;
 365             case ELFOSABI_FREEBSD:
 366                 printf("ELFOSABI_FREEBSD");
 367                 break;
 368             case ELFOSABI_LINUX:
 369                 printf("ELFOSABI_LINUX");
 370                 break;
 371             case ELFOSABI_SOLARIS:
 372                 printf("ELFOSABI_SOLARIS");
 373                 break;
 374             default:
 375                 printf("%s0x%x%s", RED, hdr.e_ident[EI_OSABI], RESET);
 376         }
 377 
 378     printf("\n%se_ident[EI_ABIVERSION]:%s\t0x%.2x", WHITE, RESET, hdr.e_ident[EI_ABIVERSION]);
 379 
 380     printf("\n%se_type:%s\t\t\t", WHITE, RESET);
 381     if(numeric)
 382         printf("0x%x", hdr.e_type);
 383     else
 384         switch(hdr.e_type){
 385             case ET_NONE:
 386                 printf("ET_NONE");
 387                 break;
 388             case ET_REL:
 389                 printf("ET_REL");
 390                 break;
 391             case ET_EXEC:
 392                 printf("ET_EXEC");
 393                 break;
 394             case ET_DYN:
 395                 printf("ET_DYN");
 396                 break;
 397             case ET_CORE:
 398                 printf("ET_CORE");
 399                 break;
 400             default:
 401                 printf("%s0x%x%s", RED, hdr.e_type, RESET);
 402         }
 403 
 404     printf("\n%se_machine:%s\t\t", WHITE, RESET);
 405     if(numeric)
 406         printf("0x%x", hdr.e_machine);
 407     else
 408         switch(hdr.e_machine){
 409             case EM_NONE:
 410                 printf("EM_NONE");
 411                 break;
 412             case EM_SPARC:
 413                 printf("EM_SPARC");
 414                 break;
 415             case EM_386:
 416                 printf("EM_386");
 417                 break;
 418             case EM_MIPS:
 419                 printf("EM_MIPS");
 420                 break;
 421             case EM_PARISC:
 422                 printf("EM_PARISC");
 423                 break;
 424             case EM_PPC:
 425                 printf("EM_PPC");
 426                 break;
 427             case EM_SPARCV9:
 428                 printf("EM_SPARCV9");
 429                 break;
 430             case EM_X86_64:
 431                 printf("EM_X86_649");
 432                 break;
 433             default:
 434                 printf("%s0x%x%s", RED, hdr.e_machine, RESET);
 435         }
 436 
 437     printf("\n%se_version:%s\t\t", WHITE, RESET);
 438     if(numeric)
 439         printf("0x%x", hdr.e_version);
 440     else
 441         switch(hdr.e_version){
 442             case EV_NONE:
 443                 printf("EV_NONE");
 444                 break;
 445             case EV_CURRENT:
 446                 printf("EV_CURRENT");
 447                 break;
 448             default:
 449                 printf("%s0x%x%s", RED, hdr.e_version, RESET);
 450         }
 451 
 452     printf("\n%se_entry:%s\t\t0x"HEX, WHITE, RESET, hdr.e_entry);
 453     printf("\n%se_phoff:%s\t\t0x"HEX"\t("DEC")", WHITE, RESET, hdr.e_phoff, hdr.e_phoff);
 454     printf("\n%se_shoff:%s\t\t0x"HEX"\t("DEC")", WHITE, RESET, hdr.e_shoff, hdr.e_shoff);
 455     printf("\n%se_flags:%s\t\t0x%x\t(%d)", WHITE, RESET, hdr.e_flags, hdr.e_flags);
 456     printf("\n%se_ehsize:%s\t\t0x%x\t(%d)", WHITE, RESET, hdr.e_ehsize, hdr.e_ehsize);
 457     printf("\n%se_phentsize:%s\t\t0x%x\t(%d)", WHITE, RESET, hdr.e_phentsize, hdr.e_phentsize);
 458     printf("\n%se_phnum:%s\t\t0x%x\t(%d)", WHITE, RESET, hdr.e_phnum, hdr.e_phnum);
 459     printf("\n%se_shentsize:%s\t\t0x%x\t(%d)", WHITE, RESET, hdr.e_shentsize, hdr.e_shentsize);
 460     printf("\n%se_shnum:%s\t\t0x%x\t(%d)", WHITE, RESET, hdr.e_shnum, hdr.e_shnum);
 461     printf("\n%se_shstrndx:%s\t\t0x%x\t(%d)\n", WHITE, RESET, hdr.e_shstrndx, hdr.e_shstrndx);
 462 }
 463 
 464 void sht(char *mem)
 465 {
 466     int        k;
 467     Elf_Ehdr    hdr = *(Elf_Ehdr *) mem;
 468     Elf_Shdr    *sections = (Elf_Shdr *) (mem + hdr.e_shoff);
 469 
 470     printf("%s[NR] sh_name              sh_type          sh_flags    sh_addr    sh_offset sh_size  sh_link sh_info sh_addralign sh_entsize%s\n", WHITE, RESET);
 471 
 472     for(k = 0; k < hdr.e_shnum; k++, sections++){
 473         printf("[%2d] ", k);
 474 
 475         if(numeric)
 476             printf("0x%-18.8x ", sections->sh_name);
 477         else{
 478             if(shstrtab_offset == 0)
 479                 printf("0x%-15.8x ", sections->sh_name);
 480             else
 481                 printf("%-20s ", mem + shstrtab_offset + sections->sh_name);
 482         }
 483 
 484         if(numeric)
 485             printf("0x%-12.8x ", sections->sh_type);
 486         else
 487             switch(sections->sh_type){
 488                 case SHT_NULL:
 489                     printf("%-14s ", "SHT_NULL");
 490                     break;
 491                 case SHT_PROGBITS:
 492                     printf("%-14s ", "SHT_PROGBITS");
 493                     break;
 494                 case SHT_SYMTAB:
 495                     printf("%-14s ", "SHT_SYMTAB");
 496                     break;
 497                 case SHT_STRTAB:
 498                     printf("%-14s ", "SHT_STRTAB");
 499                     break;
 500                 case SHT_RELA:
 501                     printf("%-14s ", "SHT_RELA");
 502                     break;
 503                 case SHT_HASH:
 504                     printf("%-14s ", "SHT_HASH");
 505                     break;
 506                 case SHT_DYNAMIC:
 507                     printf("%-14s ", "SHT_DYNAMIC");
 508                     break;
 509                 case SHT_NOTE:
 510                     printf("%-14s ", "SHT_NOTE");
 511                     break;
 512                 case SHT_GNU_HASH:
 513                     printf("%-14s ", "SHT_GNU_HASH");
 514                     break;
 515                 case SHT_NOBITS:
 516                     printf("%-14s ", "SHT_NOBITS");
 517                     break;
 518                 case SHT_REL:
 519                     printf("%-14s ", "SHT_REL");
 520                     break;
 521                 case SHT_SHLIB:
 522                     printf("%-14s ", "SHT_SHLIB");
 523                     break;
 524                 case SHT_DYNSYM:
 525                     printf("%-14s ", "SHT_DYNSYM");
 526                     break;
 527                 case SHT_INIT_ARRAY:
 528                     printf("%-14s ", "SHT_INIT_ARRAY");
 529                     break;
 530                 case SHT_FINI_ARRAY:
 531                     printf("%-14s ", "SHT_FINI_ARRAY");
 532                     break;
 533                 case SHT_GNU_verdef:
 534                     printf("%-14s ", "SHT_VERDEF");
 535                     break;
 536                 case SHT_GNU_verneed:
 537                     printf("%-14s ", "SHT_VERNEED");
 538                     break;
 539                 case SHT_GNU_versym:
 540                     printf("%-14s ", "SHT_VERSYM");
 541                     break;
 542                 default:
 543                     printf("%s0x%-12.8x%s ", RED, sections->sh_type, RESET);
 544             }
 545 
 546         if(numeric)
 547             printf("  0x%.8x  ", (unsigned int) sections->sh_flags);
 548         else
 549             printf("   %c %c %c      ", /* Needs to be improved. Seen more flags than only those three */
 550                     (sections->sh_type & SHF_WRITE) ? 'W' : ' ',
 551                     (sections->sh_type & SHF_ALLOC) ? 'A' : ' ',
 552                     (sections->sh_type & SHF_EXECINSTR) ? 'X' : ' ');
 553 
 554         printf("0x%.8x ", (unsigned int) sections->sh_addr);
 555         printf("0x%.7x ", (unsigned int) sections->sh_offset);
 556         printf("0x%.6x   ", (unsigned int) sections->sh_size);
 557         printf("0x%.2x  ", sections->sh_link);
 558         printf("0x%.4x  ", sections->sh_info);
 559         printf("0x%.8x   ", (unsigned int) sections->sh_addralign);
 560         printf("0x%.4x\n", (unsigned int) sections->sh_entsize);
 561     }
 562 }
 563 
 564 void pht(char *mem)
 565 {
 566     int        k;
 567     Elf_Ehdr    hdr = *(Elf_Ehdr *) mem;
 568     Elf_Phdr    *phdrs = (Elf_Phdr *) (mem + hdr.e_phoff);
 569 
 570     printf("%s[NR] p_type           p_offset    p_vaddr"SPACE"     p_paddr"SPACE"     p_filesz    p_memsz     p_flags  p_align%s\n", WHITE, RESET);
 571 
 572     for(k = 0; k < hdr.e_phnum; k++, phdrs++){
 573         printf("[%2d] ", k);
 574 
 575         if(numeric)
 576             printf("0x%-14.8x ", phdrs->p_type);
 577         else
 578             switch(phdrs->p_type){
 579                 case PT_NULL:
 580                     printf("%-17s", "PT_NULL");
 581                     break;
 582                 case PT_LOAD:
 583                     printf("%-17s", "PT_LOAD");
 584                     break;
 585                 case PT_DYNAMIC:
 586                     printf("%-17s", "PT_DYNAMIC");
 587                     break;
 588                 case PT_INTERP:
 589                     printf("%-17s", "PT_INTERP");
 590                     break;
 591                 case PT_NOTE:
 592                     printf("%-17s", "PT_NOTE");
 593                     break;
 594                 case PT_SHLIB:
 595                     printf("%-17s", "PT_SHLIB");
 596                     break;
 597                 case PT_TLS:
 598                     printf("%-17s", "PT_TLS");
 599                     break;
 600                 case PT_PHDR:
 601                     printf("%-17s", "PT_PHDR");
 602                     break;
 603                 case PT_GNU_EH_FRAME:
 604                     printf("%-17s", "PT_GNU_EH_FRAME");
 605                     break;
 606                 case PT_GNU_STACK:
 607                     printf("%-17s", "PT_GNU_STACK");
 608                     break;
 609                 case PT_GNU_RELRO:
 610                     printf("%-17s", "PT_GNU_RELRO");
 611                     break;
 612                 default:
 613                     printf("%s0x%-14.8x%s ", RED, phdrs->p_type, RESET);
 614             }
 615 
 616         printf("0x%.8x  ", (unsigned int) phdrs->p_offset);
 617         printf("0x"HEX"  ", phdrs->p_vaddr);
 618         printf("0x"HEX"  ", phdrs->p_paddr);
 619         printf("0x%.8x  ", (unsigned int) phdrs->p_filesz);
 620         printf("0x%.8x  ", (unsigned int) phdrs->p_memsz);
 621 
 622         if(numeric)
 623             printf("0x%.4x   ", phdrs->p_flags);
 624         else
 625             printf(" %c %c %c   ",
 626                     (phdrs->p_type & PF_X) ? 'X' : ' ',
 627                     (phdrs->p_type & PF_W) ? 'W' : ' ',
 628                     (phdrs->p_type & PF_R) ? 'R' : ' ');
 629 
 630         printf("0x%.8x\n", (unsigned int) phdrs->p_align);
 631 
 632         if(phdrs->p_type == PT_INTERP)
 633             printf("[Interpreter: %s%s%s]\n", WHITE, mem + phdrs->p_offset, RESET);
 634     }
 635 }
 636 
 637 void symbols(char *mem)
 638 {
 639     int        k, l, flag = 0, strtab_off;
 640     Elf_Ehdr    hdr = *(Elf_Ehdr *) mem;
 641     Elf_Shdr    *shdr = (Elf_Shdr *) (mem + hdr.e_shoff), *shdr_table, stringtable;
 642     Elf_Sym        *sym;
 643 
 644     shdr_table = shdr;
 645 
 646     for(k = 0; k < hdr.e_shnum; k++, shdr++){
 647         if(shdr->sh_type != SHT_SYMTAB && shdr->sh_type != SHT_DYNSYM)
 648             continue;
 649 
 650         flag = 1;
 651 
 652         printf("Found symbol table [%s%s%s] with %s"DEC"%s entries:\n", YELLOW, mem + shstrtab_offset + shdr->sh_name, RESET, YELLOW, shdr->sh_size / shdr->sh_entsize, RESET);
 653 
 654         sym = (Elf_Sym *) (mem + shdr->sh_offset);
 655         stringtable = *(Elf_Shdr *) (mem + hdr.e_shoff + (shdr->sh_link * sizeof(Elf_Shdr)));
 656         strtab_off  = stringtable.sh_offset;
 657 
 658         printf("%s[ NR ] st_value"SPACE"   st_size     TYPE        BINDING    VISIBILITY     st_shndx    st_name%s\n", WHITE, RESET);
 659 
 660         for(l = 0; l < shdr->sh_size / shdr->sh_entsize; l++, sym++){
 661             printf("[%4d] ", l);
 662 
 663             printf("0x"HEX" ", sym->st_value);
 664             printf("0x%.5x  ", (unsigned int) sym->st_size);
 665 
 666             if(numeric)
 667                 printf("   0x%.2x ", sym->st_info);
 668             else
 669                 switch(ELF_ST_TYPE(sym->st_info)){
 670                     case STT_NOTYPE:
 671                         printf("%-12s  ", "STT_NOTYPE");
 672                         break;
 673                     case STT_OBJECT:
 674                         printf("%-12s  ", "STT_OBJECT");
 675                         break;
 676                     case STT_FUNC:
 677                         printf("%-12s  ", "STT_FUNC");
 678                         break;
 679                     case STT_SECTION:
 680                         printf("%-12s  ", "STT_SECTION");
 681                         break;
 682                     case STT_FILE:
 683                         printf("%-12s  ", "STT_FILE");
 684                         break;
 685                     case STT_COMMON:
 686                         printf("%-12s  ", "STT_COMMON");
 687                         break;
 688                     case STT_TLS:
 689                         printf("%-12s  ", "STT_TLS");
 690                         break;
 691                     case STT_NUM:
 692                         printf("%-12s  ", "STT_NUM");
 693                         break;
 694                     default:
 695                         printf("   %s0x%.2x%s       ", RED, sym->st_info, RESET);
 696                 }
 697 
 698             if(numeric)
 699                 printf("        0x%.2x ", sym->st_info);
 700             else
 701                 switch(ELF_ST_BIND(sym->st_info)){
 702                     case STB_LOCAL:
 703                         printf("%-11s ", "STB_LOCAL");
 704                         break;
 705                     case STB_GLOBAL:
 706                         printf("%-11s ", "STB_GLOBAL");
 707                         break;
 708                     case STB_WEAK:
 709                         printf("%-11s ", "STB_WEAK");
 710                         break;
 711                     case STB_NUM:
 712                         printf("%-11s ", "STB_NUM");
 713                         break;
 714                     default:
 715                         printf("  %s0x%.2x%s       ", RED, sym->st_info, RESET);
 716                 }
 717 
 718             if(numeric)
 719                 printf("        0x%.2x        ", sym->st_other);
 720             else
 721                 switch(ELF_ST_VISIBILITY(sym->st_other)){
 722                     case STV_DEFAULT:
 723                         printf("%-14s ", "STV_DEFAULT");
 724                         break;
 725                     case STV_INTERNAL:
 726                         printf("%-14s ", "STV_INTERNAL");
 727                         break;
 728                     case STV_HIDDEN:
 729                         printf("%-14s ", "STV_HIDDEN");
 730                         break;
 731                     case STV_PROTECTED:
 732                         printf("%-14s ", "STV_PROTECTED");
 733                         break;
 734                     default:
 735                         printf("   %s0x%.2x%s        ", RED, sym->st_other, RESET);    
 736                 }
 737 
 738             if(numeric)
 739                 printf(" 0x%.4x     ", sym->st_shndx);
 740             else
 741                 switch(sym->st_shndx){
 742                     case SHN_UNDEF:
 743                         printf("%-11s ", "SHN_UNDEF");
 744                         break;
 745                     case SHN_ABS:
 746                         printf("%-11s ", "SHN_ABS");
 747                         break;
 748                     case SHN_COMMON:
 749                         printf("%-11s ", "SHN_COMMON");
 750                         break;
 751                     default:
 752                         printf("  0x%.2x      ", sym->st_shndx);
 753                 }
 754 
 755             if(numeric)
 756                 printf("0x%.4x\n", sym->st_name);
 757             else{
 758                 if(ELF_ST_TYPE(sym->st_info) == STT_SECTION)
 759                     printf("%s\n", mem + shstrtab_offset + shdr_table[sym->st_shndx].sh_name);
 760                 else
 761                     printf("%s\n", mem + strtab_off + sym->st_name);
 762             }
 763         }
 764 
 765         putchar('\n');
 766     }
 767 
 768     if(!flag)
 769         printf("[%sNO SYMBOL TABLE FOUND%s]\n", WHITE, RESET);
 770 }
 771 
 772 void dynamic(char *mem)
 773 {
 774     int        k, l, flag = 0, strtab_offset;
 775     Elf_Ehdr    hdr = *(Elf_Ehdr *) mem;
 776     Elf_Shdr    *shdr = (Elf_Shdr *) (mem + hdr.e_shoff), stringtable;
 777     Elf_Dyn        *dyn;
 778 
 779     for(k = 0; k < hdr.e_shnum; k++, shdr++){
 780         if(shdr->sh_type != SHT_DYNAMIC)
 781             continue;
 782 
 783         flag = 1;
 784 
 785         printf("Found Dynamic Section [%s%s%s] with %s"DEC"%s entries:\n", YELLOW, mem + shstrtab_offset + shdr->sh_name, RESET, YELLOW, shdr->sh_size / shdr->sh_entsize, RESET);
 786 
 787         dyn = (Elf_Dyn *) (mem + shdr->sh_offset);
 788         stringtable = *(Elf_Shdr *) (mem + hdr.e_shoff + (shdr->sh_link * sizeof(Elf_Shdr)));
 789         strtab_offset  = stringtable.sh_offset;
 790 
 791         printf("%s[ NR ]  d_tag"SPACE"       TYPE                 NAME/VALUE%s\n", WHITE, RESET);
 792 
 793         for(l = 0; l < shdr->sh_size / shdr->sh_entsize; l++, dyn++){
 794             printf("[%4d]  ", l);
 795 
 796             printf("0x"HEX"  ", dyn->d_tag);
 797 
 798             if(numeric)
 799                 printf("0x%.8x           ", (unsigned int) dyn->d_tag);
 800             else
 801                 switch(dyn->d_tag){
 802                     case DT_NULL:
 803                         printf("%-20s ", "DT_NULL");
 804                         break;
 805                     case DT_NEEDED:
 806                         printf("%-20s ", "DT_NEEDED");
 807                         break;
 808                     case DT_PLTRELSZ:
 809                         printf("%-20s ", "DT_PLTRELSZ");
 810                         break;
 811                     case DT_PLTGOT:
 812                         printf("%-20s ", "DT_PLTGOT");
 813                         break;
 814                     case DT_HASH:
 815                         printf("%-20s ", "DT_HASH");
 816                         break;
 817                     case DT_GNU_HASH:
 818                         printf("%-20s ", "DT_GNU_HASH");
 819                         break;
 820                     case DT_STRTAB:
 821                         printf("%-20s ", "DT_STRTAB");
 822                         break;
 823                     case DT_SYMTAB:
 824                         printf("%-20s ", "DT_SYMTAB");
 825                         break;
 826                     case DT_STRSZ:
 827                         printf("%-20s ", "DT_STRSZ");
 828                         break;
 829                     case DT_SYMENT:
 830                         printf("%-20s ", "DT_SYMENT");
 831                         break;
 832                     case DT_INIT:
 833                         printf("%-20s ", "DT_INIT");
 834                         break;
 835                     case DT_FINI:
 836                         printf("%-20s ", "DT_FINI");
 837                         break;
 838                     case DT_SONAME:
 839                         printf("%-20s ", "DT_SONAME");
 840                         break;
 841                     case DT_RPATH:
 842                         printf("%-20s ", "DT_RPATH");
 843                         break;
 844                     case DT_SYMBOLIC:
 845                         printf("%-20s ", "DT_SYMBOLIC");
 846                         break;
 847                     case DT_REL:
 848                         printf("%-20s ", "DT_REL");
 849                         break;
 850                     case DT_RELSZ:
 851                         printf("%-20s ", "DT_RELSZ");
 852                         break;
 853                     case DT_RELENT:
 854                         printf("%-20s ", "DT_RELENT");
 855                         break;
 856                     case DT_PLTREL:
 857                         printf("%-20s ", "DT_PLTREL");
 858                         break;
 859                     case DT_DEBUG:
 860                         printf("%-20s ", "DT_DEBUG");
 861                         break;
 862                     case DT_TEXTREL:
 863                         printf("%-20s ", "DT_TEXTREL");
 864                         break;
 865                     case DT_JMPREL:
 866                         printf("%-20s ", "DT_JMPREL");
 867                         break;
 868                     case DT_BIND_NOW:
 869                         printf("%-20s ", "DT_BIND_NOW");
 870                         break;
 871                     case DT_INIT_ARRAY:
 872                         printf("%-20s ", "DT_INIT_ARRAY");
 873                         break;
 874                     case DT_FINI_ARRAY:
 875                         printf("%-20s ", "DT_FINI_ARRAY");
 876                         break;
 877                     case DT_INIT_ARRAYSZ:
 878                         printf("%-20s ", "DT_INIT_ARRAYSZ");
 879                         break;
 880                     case DT_FINI_ARRAYSZ:
 881                         printf("%-20s ", "DT_FINI_ARRAYSZ");
 882                         break;
 883                     case DT_VERSYM:
 884                         printf("%-20s ", "DT_VERSYM");
 885                         break;
 886                     case DT_RELCOUNT:
 887                         printf("%-20s ", "DT_RELCOUNT");
 888                         break;
 889                     case DT_VERDEF:
 890                         printf("%-20s ", "DT_VERDEF");
 891                         break;
 892                     case DT_VERDEFNUM:
 893                         printf("%-20s ", "DT_VERDEFNUM");
 894                         break;
 895                     case DT_VERNEED:
 896                         printf("%-20s ", "DT_VERNEED");
 897                         break;
 898                     case DT_VERNEEDNUM:
 899                         printf("%-20s ", "DT_VERNEEDNUM");
 900                         break;
 901                     default:
 902                         printf("%s0x%.8x%s           ", RED, (unsigned int) dyn->d_tag, RESET);
 903                 }
 904 
 905             switch(dyn->d_tag){
 906                 case DT_NEEDED:
 907                 case DT_SONAME:
 908                 case DT_RPATH:
 909                     printf("%s\n", mem + strtab_offset + dyn->d_un.d_val);
 910                     break;
 911                 case DT_PLTGOT:
 912                 case DT_HASH:
 913                 case DT_STRTAB:
 914                 case DT_SYMTAB:
 915                 case DT_INIT:
 916                 case DT_FINI:
 917                 case DT_INIT_ARRAY:
 918                 case DT_FINI_ARRAY:
 919                 case DT_REL:
 920                 case DT_JMPREL:
 921                 case DT_VERSYM:
 922                 case DT_VERNEED:
 923                 case DT_GNU_HASH:
 924                     printf("0x"HEX"\n", dyn->d_un.d_ptr);
 925                     break;
 926                 case DT_PLTRELSZ:
 927                 case DT_STRSZ:
 928                 case DT_SYMENT:
 929                 case DT_RELSZ:
 930                 case DT_RELENT:
 931                 case DT_INIT_ARRAYSZ:
 932                 case DT_FINI_ARRAYSZ:
 933                     printf(HEX" bytes\n", dyn->d_un.d_val);
 934                     break;
 935                 case DT_PLTREL:
 936                     printf("%s\n", (dyn->d_un.d_val == DT_REL) ? "DT_REL" : "DT_RELA");
 937                     break;
 938                 case DT_VERNEEDNUM:
 939                 case DT_DEBUG:
 940                     printf("0x"HEX"\n", dyn->d_un.d_val);
 941                     break;
 942                 default:
 943                     putchar('\n');
 944             }
 945 
 946             if(dyn->d_tag == DT_NULL)    /* End of _DYNAMIC[] */
 947                 break;
 948         }
 949 
 950     }
 951 
 952     if(!flag)
 953         printf("[%sNO DYNAMIC SECTION FOUND%s]\n", WHITE, RESET);
 954 }
 955 
 956 void relocations(char *mem)
 957 {
 958     int        k, l, symndx = 0, flag = 0, symstrtab_offset;
 959     Elf_Ehdr    hdr = *(Elf_Ehdr *) mem;
 960     Elf_Shdr    *shdr = (Elf_Shdr *) (mem + hdr.e_shoff), *shdr_table, symtab_section, stringtable;
 961     Elf_Sym        *sym;
 962     Elf_Rel        *rel;
 963     Elf_Rela    *rela;
 964 
 965     shdr_table = shdr;
 966 
 967     for(k = 0; k < hdr.e_shnum; k++, shdr++){
 968         if(shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA)
 969             continue;
 970 
 971         flag = 1;
 972 
 973         printf("Found Relocation Section [%s%s%s] with %s"DEC" %s%s entries:\n", YELLOW, mem + shstrtab_offset + shdr->sh_name, RESET, YELLOW, shdr->sh_size / shdr->sh_entsize, shdr->sh_type == SHT_REL ? "SHT_REL" : "SHT_RELA", RESET);
 974 
 975         if(shdr->sh_type == SHT_REL)
 976             rel =  (Elf_Rel *)  (mem + shdr->sh_offset);
 977         else
 978             rela = (Elf_Rela *) (mem + shdr->sh_offset);
 979 
 980         symtab_section = shdr_table[shdr->sh_link];
 981         stringtable = *(Elf_Shdr *) (mem + hdr.e_shoff + (symtab_section.sh_link * sizeof(Elf_Shdr)));
 982         symstrtab_offset  = stringtable.sh_offset;
 983         sym = (Elf_Sym *) (mem + symtab_section.sh_offset);
 984 
 985         printf("%s[ NR ] r_offset"SPACE"   r_info      TYPE             SYM[ndx]  SYMBOL NAME + r_addend%s\n", WHITE, RESET);
 986 
 987         for(l = 0; l < shdr->sh_size / shdr->sh_entsize; l++){
 988             printf("[%4d] ", l);
 989 
 990             printf("0x"HEX" ", shdr->sh_type == SHT_REL ? rel->r_offset : rela->r_offset);
 991             printf("0x%.8x  ", shdr->sh_type == SHT_REL ? (unsigned int) rel->r_info : (unsigned int) rela->r_info);
 992 
 993             if(numeric)
 994                 printf("0x%.8x     ", shdr->sh_type == SHT_REL ? (unsigned int) rel->r_info : (unsigned int) rela->r_info);
 995             else
 996                 switch(ELF_R_TYPE(shdr->sh_type == SHT_REL ? rel->r_info : rela->r_info)){
 997                     case R_386_NONE:
 998                         printf("%-14s ", "R_386_NONE");
 999                         break;
1000                     case R_386_32:
1001                         printf("%-14s ", "R_386_32");
1002                         break;
1003                     case R_386_PC32:
1004                         printf("%-14s ", "R_386_PC32");
1005                         break;
1006                     case R_386_GOT32:
1007                         printf("%-14s ", "R_386_GOT32");
1008                         break;
1009                     case R_386_PLT32:
1010                         printf("%-14s ", "R_386_PLT32");
1011                         break;
1012                     case R_386_COPY:
1013                         printf("%-14s ", "R_386_COPY");
1014                         break;
1015                     case R_386_GLOB_DAT:
1016                         printf("%-14s ", "R_386_GLOB_DAT");
1017                         break;
1018                     case R_386_JMP_SLOT:
1019                         printf("%-14s ", "R_386_JMP_SLOT");
1020                         break;
1021                     case R_386_RELATIVE:
1022                         printf("%-14s ", "R_386_RELATIVE");
1023                         break;
1024                     case R_386_GOTOFF:
1025                         printf("%-14s ", "R_386_GOTOFF");
1026                         break;
1027                     case R_386_GOTPC:
1028                         printf("%-14s ", "R_386_GOTPC");
1029                         break;
1030                     default:
1031                         printf("%s0x%.8x%s     ", RED, shdr->sh_type == SHT_REL ? (unsigned int) rel->r_info : (unsigned int) rela->r_info, RESET);
1032                 }
1033 
1034             symndx = ELF_R_SYM(shdr->sh_type == SHT_REL ? rel->r_info : rela->r_info);
1035             printf("    %.4d    ", symndx);
1036 
1037             if(ELF_ST_TYPE(sym[symndx].st_info) == STT_SECTION)
1038                 printf("%s", mem + shstrtab_offset + shdr_table[sym[symndx].st_shndx].sh_name);
1039             else
1040                 printf("%s", mem + symstrtab_offset + sym[symndx].st_name);
1041 
1042             if(shdr->sh_type == SHT_REL){
1043                 putchar('\n');
1044                 rel++;
1045             } else {
1046                 printf(" + 0x%x\n", (unsigned int) rela->r_addend);
1047                 rela++;
1048             }
1049         }
1050 
1051         putchar('\n');
1052     }
1053 
1054     if(!flag)
1055         printf("[%sNO RELOCATIONS FOUND%s]\n", WHITE, RESET);
1056 }
1057 
1058 /* 
1059  * It doesn't loop through the notes.
1060  * It just parses the 1st entry found in every SHT_NOTE section found.
1061  */
1062 void notes(char *mem)
1063 {
1064     int        k, l, flag = 0, *abi;
1065     Elf_Ehdr    hdr = *(Elf_Ehdr *) mem;
1066     Elf_Shdr    *shdr = (Elf_Shdr *) (mem + hdr.e_shoff);
1067     Elf_Nhdr    *note;
1068     char        *note_name;
1069 
1070     for(k = 0; k < hdr.e_shnum; k++, shdr++){
1071         if(shdr->sh_type != SHT_NOTE)
1072             continue;
1073 
1074         flag = 1;
1075 
1076         printf("Found Note Section [%s%s%s] with %s"DEC"%s bytes:\n", YELLOW, mem + shstrtab_offset + shdr->sh_name, RESET, YELLOW, shdr->sh_size, RESET);
1077 
1078         note = (Elf_Nhdr *) (mem + shdr->sh_offset);
1079 
1080         printf("%s[ NR ] n_namesz      n_descsz      n_type%s\n", WHITE, RESET);
1081 
1082         printf("[%4d] ", 0);
1083 
1084         printf("0x%.8x    ", note->n_namesz);
1085         printf("0x%.8x    ", note->n_descsz);
1086 
1087         if(numeric)
1088             printf("0x%.8x\n", note->n_type);
1089 
1090         switch(note->n_type){
1091             case NT_GNU_ABI_TAG:
1092                 note_name = (char *) (void *) note + sizeof(*note);
1093                 printf("%s", numeric ? "" : strcmp(note_name, ELF_NOTE_GNU) == 0 ? "NT_GNU_ABI_TAG\n" : "NT_VERSION\n");
1094 
1095                 printf("\tName:\t%s\n", note_name);
1096 
1097                 if(strcmp(note_name, ELF_NOTE_GNU))
1098                     break;
1099 
1100                 abi = (int *) ((void *) note + sizeof(*note) + note->n_namesz);
1101 
1102                 putchar('\t');
1103 
1104                 if(numeric){
1105                     printf("OS:\t0x%.8x\n", *(abi++));
1106                     printf("\tABI:\tMajor: 0x%.8x   ",  *(abi++));
1107                     printf("Minor: 0x%.8x   ",  *(abi++));
1108                     printf("Subminor: 0x%.8x\n", *(abi));
1109                 } else {
1110                     switch(*abi){
1111                         case ELF_NOTE_OS_LINUX:
1112                             printf("OS:\tELF_NOTE_OS_LINUX\n");
1113                             break;
1114                         case ELF_NOTE_OS_GNU:
1115                             printf("OS:\tELF_NOTE_OS_GNU\n");
1116                             break;
1117                         case ELF_NOTE_OS_SOLARIS2:
1118                             printf("OS:\tELF_NOTE_OS_SOLARIS2\n");
1119                             break;
1120                         case ELF_NOTE_OS_FREEBSD:
1121                             printf("OS:\tELF_NOTE_OS_FREEBSD\n");
1122                             break;
1123                         default:
1124                             printf("OS:\t%s0x%.8x%s\n", RED, *abi, RESET);
1125                     }
1126 
1127                     printf("\tABI:\t%d.", *(++abi));
1128                     printf("%d.", *(++abi));
1129                     printf("%d\n",*(++abi));
1130                 }
1131                 break;
1132             case NT_GNU_HWCAP:
1133                 printf("%s", numeric ? "" : "NT_GNU_HWCAP\n");
1134                 break;
1135             case NT_GNU_BUILD_ID:
1136                 printf("%s", numeric ? "" : "NT_GNU_BUILD_ID\n");
1137                 printf("\tName:\t%s\n", (char *) ((void *) note + sizeof(*note)));
1138 
1139                 printf("\tBuildID: ");
1140 
1141                 char *desc = (char *) (void *) note + sizeof(*note) + note->n_namesz;
1142 
1143                 for(l = 0; l < note->n_descsz; l++)
1144                     printf("%.2x", (*(desc++) & 0xff));
1145 
1146                 putchar('\n');
1147 
1148                 break;
1149             case NT_GNU_GOLD_VERSION:
1150                 printf("%s", numeric ? "" : "NT_GNU_GOLD_VERSION\n");
1151                 break;
1152             default:
1153                 printf("%s0x%.8x%s\n", RED, note->n_type, RESET);
1154         }
1155 
1156         putchar('\n');
1157     }
1158 
1159     if(!flag)
1160         printf("[%sNO NOTES FOUND%s]\n", WHITE, RESET);
1161 }

代码不难,话不多说了。功能正常。

上一篇:list


下一篇:BYOL与SimSiam的区别,为什么SimSiam不退化?