原文链接: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 }
代码不难,话不多说了。功能正常。