• dissector.c


    原文链接: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    "33[31m"
      27 #define WHITE    "33[01m"
      28 #define YELLOW    "33[33m"
      29 #define RESET    "33[00m"
      30 //#else
      31 //#define RED    ""
      32 //#define WHITE    ""
      33 //#define YELLOW    "33[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
    ");
     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
    ");
     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("
    %sELF HEADER:%s
    ", RED, RESET);
     209         elf_header(header);
     210     }
     211 
     212     if(mode & SECTION){
     213         printf("
    %sSECTION HEADER TABLE:%s
    ", RED, RESET);
     214         if(header.e_shoff == 0)
     215             printf("[%sNO SECTION HEADER TABLE FOUND%s]
    ", WHITE, RESET);
     216         else
     217             sht(elfptr);
     218     }
     219 
     220     if(mode & PROGRAM){
     221         printf("
    %sPROGRAM HEADER TABLE:%s
    ", RED, RESET);
     222         pht(elfptr);
     223     }
     224 
     225     if(mode & SYMBOL){
     226         printf("
    %sSYMBOL TABLE:%s
    ", RED, RESET);
     227         symbols(elfptr);
     228     }
     229 
     230     if(mode & DYNAMIC){
     231         printf("
    %sDYNAMIC INFORMATION:%s
    ", RED, RESET);
     232         dynamic(elfptr);
     233     }
     234 
     235     if(mode & RELOC){
     236         printf("
    %sRELOCATIONS:%s
    ", RED, RESET);
     237         relocations(elfptr);
     238     }
     239 
     240     if(mode & NOTES){
     241         printf("
    %sNOTES:%s
    ", 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>
    ", self);
     254     fprintf(stderr, "	Options:
    ");
     255     fprintf(stderr, "	-n	Print everything in numeric values
    ");
     256     fprintf(stderr, "	-a	All(-HSPsdr)
    ");
     257     fprintf(stderr, "	-H	ELF header
    ");
     258     fprintf(stderr, "	-S	Section headers
    ");
     259     fprintf(stderr, "	-P	Program headers
    ");
     260     fprintf(stderr, "	-s	Symbol Table
    ");
     261     fprintf(stderr, "	-D	Dynamic information
    ");
     262     fprintf(stderr, "	-R	Relocations
    ");
     263     fprintf(stderr, "	-N	Notes
    ");
     264     fprintf(stderr, "	-h	This help
    ");
     265     exit(0);
     266 }
     267 
     268 void banner()
     269 {
     270     printf("%s######################################################%s
    ", RED, RESET);
     271     printf("%s##%s%s         ELF ( x86 / x86_64 ) Dissector           %s%s##%s
    ", RED, RESET, YELLOW, RESET, RED, RESET);
     272     printf("%s##%s%s                  by nitr0us                      %s%s##%s
    ", RED, RESET, YELLOW, RESET, RED, RESET);
     273     printf("%s######################################################%s
    
    ", 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
    ");
     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		", WHITE, RESET);
     302     for(k = 0; k < EI_NIDENT; k++)
     303         printf("%.2x ", hdr.e_ident[k]);
     304 
     305     printf("
    %se_ident[EI_CLASS]:%s	", 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("
    %se_ident[EI_DATA]:%s	", 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("
    %se_ident[EI_VERSION]:%s	", 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("
    %se_ident[EI_OSABI]:%s	", 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("
    %se_ident[EI_ABIVERSION]:%s	0x%.2x", WHITE, RESET, hdr.e_ident[EI_ABIVERSION]);
     379 
     380     printf("
    %se_type:%s			", 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("
    %se_machine:%s		", 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("
    %se_version:%s		", 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("
    %se_entry:%s		0x"HEX, WHITE, RESET, hdr.e_entry);
     453     printf("
    %se_phoff:%s		0x"HEX"	("DEC")", WHITE, RESET, hdr.e_phoff, hdr.e_phoff);
     454     printf("
    %se_shoff:%s		0x"HEX"	("DEC")", WHITE, RESET, hdr.e_shoff, hdr.e_shoff);
     455     printf("
    %se_flags:%s		0x%x	(%d)", WHITE, RESET, hdr.e_flags, hdr.e_flags);
     456     printf("
    %se_ehsize:%s		0x%x	(%d)", WHITE, RESET, hdr.e_ehsize, hdr.e_ehsize);
     457     printf("
    %se_phentsize:%s		0x%x	(%d)", WHITE, RESET, hdr.e_phentsize, hdr.e_phentsize);
     458     printf("
    %se_phnum:%s		0x%x	(%d)", WHITE, RESET, hdr.e_phnum, hdr.e_phnum);
     459     printf("
    %se_shentsize:%s		0x%x	(%d)", WHITE, RESET, hdr.e_shentsize, hdr.e_shentsize);
     460     printf("
    %se_shnum:%s		0x%x	(%d)", WHITE, RESET, hdr.e_shnum, hdr.e_shnum);
     461     printf("
    %se_shstrndx:%s		0x%x	(%d)
    ", 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
    ", 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
    ", (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
    ", 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
    ", (unsigned int) phdrs->p_align);
     631 
     632         if(phdrs->p_type == PT_INTERP)
     633             printf("[Interpreter: %s%s%s]
    ", 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:
    ", 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
    ", 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
    ", sym->st_name);
     757             else{
     758                 if(ELF_ST_TYPE(sym->st_info) == STT_SECTION)
     759                     printf("%s
    ", mem + shstrtab_offset + shdr_table[sym->st_shndx].sh_name);
     760                 else
     761                     printf("%s
    ", mem + strtab_off + sym->st_name);
     762             }
     763         }
     764 
     765         putchar('
    ');
     766     }
     767 
     768     if(!flag)
     769         printf("[%sNO SYMBOL TABLE FOUND%s]
    ", 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:
    ", 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
    ", 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
    ", 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"
    ", 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
    ", dyn->d_un.d_val);
     934                     break;
     935                 case DT_PLTREL:
     936                     printf("%s
    ", (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"
    ", dyn->d_un.d_val);
     941                     break;
     942                 default:
     943                     putchar('
    ');
     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]
    ", 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:
    ", 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
    ", 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('
    ');
    1044                 rel++;
    1045             } else {
    1046                 printf(" + 0x%x
    ", (unsigned int) rela->r_addend);
    1047                 rela++;
    1048             }
    1049         }
    1050 
    1051         putchar('
    ');
    1052     }
    1053 
    1054     if(!flag)
    1055         printf("[%sNO RELOCATIONS FOUND%s]
    ", 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:
    ", 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
    ", 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
    ", 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
    " : "NT_VERSION
    ");
    1094 
    1095                 printf("	Name:	%s
    ", 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('	');
    1103 
    1104                 if(numeric){
    1105                     printf("OS:	0x%.8x
    ", *(abi++));
    1106                     printf("	ABI:	Major: 0x%.8x   ",  *(abi++));
    1107                     printf("Minor: 0x%.8x   ",  *(abi++));
    1108                     printf("Subminor: 0x%.8x
    ", *(abi));
    1109                 } else {
    1110                     switch(*abi){
    1111                         case ELF_NOTE_OS_LINUX:
    1112                             printf("OS:	ELF_NOTE_OS_LINUX
    ");
    1113                             break;
    1114                         case ELF_NOTE_OS_GNU:
    1115                             printf("OS:	ELF_NOTE_OS_GNU
    ");
    1116                             break;
    1117                         case ELF_NOTE_OS_SOLARIS2:
    1118                             printf("OS:	ELF_NOTE_OS_SOLARIS2
    ");
    1119                             break;
    1120                         case ELF_NOTE_OS_FREEBSD:
    1121                             printf("OS:	ELF_NOTE_OS_FREEBSD
    ");
    1122                             break;
    1123                         default:
    1124                             printf("OS:	%s0x%.8x%s
    ", RED, *abi, RESET);
    1125                     }
    1126 
    1127                     printf("	ABI:	%d.", *(++abi));
    1128                     printf("%d.", *(++abi));
    1129                     printf("%d
    ",*(++abi));
    1130                 }
    1131                 break;
    1132             case NT_GNU_HWCAP:
    1133                 printf("%s", numeric ? "" : "NT_GNU_HWCAP
    ");
    1134                 break;
    1135             case NT_GNU_BUILD_ID:
    1136                 printf("%s", numeric ? "" : "NT_GNU_BUILD_ID
    ");
    1137                 printf("	Name:	%s
    ", (char *) ((void *) note + sizeof(*note)));
    1138 
    1139                 printf("	BuildID: ");
    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('
    ');
    1147 
    1148                 break;
    1149             case NT_GNU_GOLD_VERSION:
    1150                 printf("%s", numeric ? "" : "NT_GNU_GOLD_VERSION
    ");
    1151                 break;
    1152             default:
    1153                 printf("%s0x%.8x%s
    ", RED, note->n_type, RESET);
    1154         }
    1155 
    1156         putchar('
    ');
    1157     }
    1158 
    1159     if(!flag)
    1160         printf("[%sNO NOTES FOUND%s]
    ", WHITE, RESET);
    1161 }

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

    人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。
  • 相关阅读:
    mosquitto配置文件说明
    Mac 下 Mosquitto 安装和配置 (Mosquitto为开源的mqtt服务器)
    transfer learning
    NP问题
    旋转矩阵与四元数
    在数学中一个非凸的最优化问题是什么意思?
    国产操作系统优麒麟安装步骤
    齐次坐标
    反走样
    数据分析师
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/15255406.html
Copyright © 2020-2023  润新知