/*************************************************************************** main.c - core dump debugger ------------------- begin : Sun Aug 1 20:46:02 EDT 2003 copyright : (C) 2003 by Atanas Dimitrov email : atanas_dimitrov@bobcat.gcsu.edu ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define EMPTY 0 #define MAX_NOTES 10 /* to avoid implicit declaration warnings generated by -Wall */ extern char *ctime(const time_t *timep); typedef struct { long int ebx; long int ecx; long int edx; long int esi; long int edi; long int ebp; long int eax; long int xds; long int xes; long int xfs; long int xgs; long int orig_eax; long int eip; long int xcs; long int eflags; long int esp; long int xss; }user_regs_struct; /* need to replace this with include/elf.h: Elf32_Nhdr ... wish I saw it earlier*/ /* this does work out pretty good for the 32 bit arch and accounts for the Note structure. */ /* definition is next to processing section */ typedef struct { Elf32_Word namesz; Elf32_Word descsz; Elf32_Word type; }Elf32_Note_Part; int main(int argc, char *argv[]) { int fdin; char *acctime, *modtime, *chtime; char *longarray; struct stat statbuf; int os_abi_unknown; Elf32_Ehdr *elfhdr, *elfhdr1; Elf32_Phdr *proghdr; int noteoffsets[MAX_NOTES]; int chk_phoff=0, chk_phentsize=0, chk_phnum=0; int count, next_off=0; int note_sect_counter=0; /* number of note sections */ int prstatus_bool=0, prpsinfo_bool=0; /* check for necessary number of command line arguments */ if(argc !=2) { printf("Usage: %s \n", argv[0]); exit(1); } /* check for successful binary file opening */ if ((fdin = open(argv[1], O_RDONLY)) == -1) { perror("open"); exit(2); } /* get the attributes of the file but first check for errors */ if ((fstat(fdin, &statbuf)) < 0) { perror("fstat"); exit(3); } /* display some attributes */ printf("\n.: FILE STATUS INFORMATION :.\n"); printf("hard links: %d\n", statbuf.st_nlink); printf("uid: %d\n", statbuf.st_uid); printf("gid: %d\n", statbuf.st_gid); printf("size: %d\n", statbuf.st_size); printf("block size: %d\n", statbuf.st_blksize); printf("block count: %d\n", statbuf.st_blocks); acctime = (char *) ctime(&statbuf.st_atime); printf("last access: %s", acctime); modtime = (char *) ctime(&statbuf.st_mtime); printf("last mod: %s", modtime); chtime = (char *) ctime(&statbuf.st_ctime); printf("last change: %s", chtime); //printf("\nstarting to modify output...\n"); fflush(stdout); //sleep(1); longarray = mmap(0, statbuf.st_size, PROT_READ, \ MAP_FILE | MAP_SHARED, fdin, 0); //perror("\nstatus of memory mapping"); /* use memcmp to compare the first 4 bytes from file to first 4 bytes of standard ELF header's first entry - Elf32_Ehdr.e_ident[EI_IDENT] basically do byte comparison at already defined indexes and/or offsets. (see include/elf.h for definitions) all this to verify the ELF type */ if (memcmp(longarray, ELFMAG, SELFMAG) == 0) { //printf("ELF file type accepted\n"); fflush(stdout); } else { printf("error: unrecognized file type\n"); fflush(stdout); exit(5); } /* initialize the elf header structure as defined in include/elf.h */ elfhdr = (Elf32_Ehdr *) ((unsigned char *) &longarray[0x0]); printf("\n.: CORE ELF HEADER INFORMATION :.\n"); /* determine file class */ if (elfhdr->e_ident[EI_CLASS] == ELFCLASS32) printf("capacity: 32 bit (ELFCLASS32) [%d]\n", \ elfhdr->e_ident[EI_CLASS]); else if (elfhdr->e_ident[EI_CLASS] == ELFCLASS64) printf("capacity: 64 bit (ELFCLASS64) [%d]\n", \ elfhdr->e_ident[EI_CLASS]); else if (elfhdr->e_ident[EI_CLASS] == ELFCLASSNONE) printf("capacity: none (ELFCLASSNONE) [%d]\n", \ elfhdr->e_ident[EI_CLASS]); else printf("error: capacity not defined within ELF header [%d]\n", \ elfhdr->e_ident[EI_CLASS]); /* determine data encoding type */ if (elfhdr->e_ident[EI_DATA] == ELFDATA2LSB) printf("data encoding type: 2's comp, little endian (ELFDATA2LSB) [%d]\n",\ elfhdr->e_ident[EI_DATA]); else if (elfhdr->e_ident[EI_DATA] == ELFDATA2MSB) printf("data encoding type: 2's comp, big endian (ELFDATA2MSB) [%d]\n", \ elfhdr->e_ident[EI_DATA]); else if (elfhdr->e_ident[EI_DATA] == ELFDATANONE) printf("data encoding type: none (ELFCLASSNONE) [%d]\n", \ elfhdr->e_ident[EI_DATA]); else printf("data encoding type: not defined within ELF header [%d]\n",\ elfhdr->e_ident[EI_DATA]); /* determine version number (1 is current) and this is a must */ if (elfhdr->e_ident[EI_VERSION] == EV_CURRENT) printf("file version: current (EV_CURRENT) [%d]\n", \ elfhdr->e_ident[EI_VERSION]); else printf("file version: illegal version [%d]\n", \ elfhdr->e_ident[EI_VERSION]); /* determine OS ABI identification (application binary interface) */ if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_NONE || elfhdr->e_ident[EI_OSABI] == ELFOSABI_SYSV) printf("OS ABI: Unix System V ABI [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_HPUX) printf("OS ABI: HP-UX (ELFOSABI_HPUX) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_NETBSD) printf("OS ABI: NetBSD (ELFOSABI_NETBSD) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_LINUX) printf("OS ABI: Linux (ELFOSABI_LINUX) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) printf("OS ABI: Solaris (ELFOSABI_SOLARIS) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_AIX) printf("OS ABI: AIX (ELFOSABI_AIX) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_IRIX) printf("OS ABI: Irix (ELFOSABI_IRIX) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_FREEBSD) printf("OS ABI: FreeBSD (ELFOSABI_FREEBSD) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_TRU64) printf("OS ABI: Compaq TRU64 Unix (ELFOSABI_HPUX) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_MODESTO) printf("OS ABI: Novell Modesto (ELFOSABI_MODESTO) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_OPENBSD) printf("OS ABI: OpenBSD (ELFOSABI_OPENBSD) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_ARM) printf("OS ABI: ARM (ELFOSABI_ARM) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_STANDALONE) printf("OS ABI: Standalone (Embedded) Application (ELFOSABI_STANDALONE) [%d]\n", \ elfhdr->e_ident[EI_OSABI]); else { printf("OS ABI: unknown [%d]\n", elfhdr->e_ident[EI_OSABI]); os_abi_unknown = TRUE; } /* determine ABI version if aplicable */ if (!os_abi_unknown) printf("ABI version: %d\n", elfhdr->e_ident[EI_ABIVERSION]); else printf("ABI version: unknown [%d]\n", elfhdr->e_ident[EI_ABIVERSION]); /* display number of padding bytes */ printf("padding bytes: %d\n", elfhdr->e_ident[EI_PAD]); /* determine object file type */ if (elfhdr->e_type == ET_NONE) printf("object file type: no file type (ET_NONE) [%d]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_REL) printf("object file type: relocatable file (ET_REL) [%d]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_EXEC) printf("object file type: executable file (ET_EXEC) [%d]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_DYN) printf("object file type: shared object file (ET_DYN) [%d]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_CORE) printf("object file type: core file (ET_CORE) [%d]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_NUM) printf("object file type: number of defined types (ET_NUM) [%d]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_LOOS) printf("object file type: OS-specific range start (ET_LOOS) [%4x]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_HIOS) printf("object file type: OS-specific range end (ET_HIOS) [%4x]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_LOPROC) printf("object file type: Processor-specific range start (ET_LOPROC) [%4x]\n", \ elfhdr->e_type); else if (elfhdr->e_type == ET_HIPROC) printf("object file type: Processor-specific range end (ET_HIPROC) [%4x]\n", \ elfhdr->e_type); else printf("object file type: undefined [%4x]\n", elfhdr->e_type); /* determine architecture */ /* 100 definitions enter here... just 3 for right now*/ if (elfhdr->e_machine == EM_NONE) printf("architecture: none (EM_NONE) [%d]\n", \ elfhdr->e_machine); else if (elfhdr->e_machine == EM_386) printf("architecture: Intel 80386 (EM_NONE) [%d]\n", \ elfhdr->e_machine); else if (elfhdr->e_machine == EM_SPARC) printf("architecture: Sun SPARC (EM_SPARC) [%d]\n", \ elfhdr->e_machine); else printf("architecture: unknown [%d]\n", elfhdr->e_machine); /* determine object file version */ if (elfhdr->e_version == EV_NONE) printf("object file version: invalid ELF version (EV_NONE) [%d]\n", \ elfhdr->e_version); else if (elfhdr->e_version == EV_CURRENT) printf("object file version: current (EV_CURRENT) [%d]\n", \ elfhdr->e_version); else printf("object file version: unknown [%d]\n", elfhdr->e_version); /* display the entry point virtual address */ printf("entry point virtual address: %#x\n", elfhdr->e_entry); /* display the program header table file offset */ printf("program header table file offset: %#x\n", elfhdr->e_phoff); if (elfhdr->e_phoff > 0) chk_phoff=1; /* display section header table file offset */ printf("section header table file offset: %#x\n", elfhdr->e_shoff); /* display processor-specific flags */ printf("processor speciffic flags: %#x\n", elfhdr->e_flags); /* display ELF header size in bytes */ printf("ELF header size: %d bytes\n", elfhdr->e_ehsize); /* display program header table entry size */ printf("program header table entry size: %d bytes\n", \ elfhdr->e_phentsize); if (elfhdr->e_phentsize > 0) chk_phentsize=1; /* display program header table entry count */ printf("program header table entry count: %d\n", \ elfhdr->e_phnum); if (elfhdr->e_phnum > 0) chk_phnum=1; /* display section header table entry size */ printf("section header table entry size: %d bytes\n", \ elfhdr->e_shentsize); /* display section header table entry count */ printf("section header table entry count: %d\n", \ elfhdr->e_shnum); /* display section header string table index */ printf("section header string table index: %d\n", \ elfhdr->e_shstrndx); /* check if we can work with program headers */ /* for CORE rest will be empty */ /* add other checks here if intentions to work with ELF in general */ /* if value is zero this means that it doesn't hold an entry */ /* unless ... pretty self explanatory */ if (chk_phoff && chk_phentsize && chk_phnum) { /* table headers */ printf("\n.: SEGMENT INFORMATION :.\n"); printf("type offset vaddress paddress "); printf("size(file) size(mem) RWX align\n"); printf("==================================="); printf("=========================================\n"); /* loop through all segments */ for(count=0; count < elfhdr->e_phnum; ++count) { /* set the offset appropriately */ proghdr = (Elf32_Phdr *) ((unsigned char *) \ &longarray[(unsigned int) \ (next_off + elfhdr->e_phoff)]); /* display all members as specified by table columns */ /* determine segment type */ if (proghdr->p_type == PT_NULL) printf("NULL"); else if (proghdr->p_type == PT_LOAD) printf("LOAD"); else if (proghdr->p_type == PT_DYNAMIC) printf("DYNAMIC"); else if (proghdr->p_type == PT_INTERP) printf("INTERP"); else if (proghdr->p_type == PT_NOTE) { /* if a note then store the offset into array later this array will be processed */ printf("NOTE"); noteoffsets[note_sect_counter]=proghdr->p_offset; note_sect_counter++; } else if (proghdr->p_type == PT_SHLIB) printf("SHLIB"); else if (proghdr->p_type == PT_PHDR) printf("PHDR"); else if (proghdr->p_type == PT_TLS) printf("TLS"); else if (proghdr->p_type == PT_NUM) printf("NUM"); else if (proghdr->p_type == PT_LOOS) printf("LOOS"); else if (proghdr->p_type == PT_GNU_EH_FRAME) printf("GNU_EH_FRAME"); else if (proghdr->p_type == PT_LOSUNW) printf("LOSUNW"); else if (proghdr->p_type == PT_SUNWBSS) printf("SUNWBSS"); else if (proghdr->p_type == PT_SUNWSTACK) printf("SUNWSTACK"); else if (proghdr->p_type == PT_HISUNW) printf("HISUNW"); else if (proghdr->p_type == PT_HIOS) printf("HIOS"); else if (proghdr->p_type == PT_LOPROC) printf("LOPROC"); else if (proghdr->p_type == PT_HIPROC) printf("HIPROC"); else printf("UNKNOWN"); /* print the rest */ printf(" %#7x ", proghdr->p_offset); printf("%#10x ", proghdr->p_vaddr); printf("%#9x ", proghdr->p_paddr); printf("%11d ", proghdr->p_filesz); printf("%12d ", proghdr->p_memsz); printf("%#7x ", proghdr->p_flags); printf("%#9x ", proghdr->p_align); /* next row */ printf("\n"); /* increase offset to next program header table entry */ next_off+=elfhdr->e_phentsize; } /* will try to make this with pointers */ noteoffsets[note_sect_counter]='\0'; } /* need to get rid of this declaration and use more dynamic way of obtaining it */ #define NOTE_PADDING 4 /* determine if there are any note sections recorded contained in the program header */ if (note_sect_counter != 0) { /* note sections counter */ int noteprcnt; printf("\n.: NOTES INFORMATION :.\n"); unsigned int note_next_note_off=0; //next note offset initially 0 /* go through each note section and display all the notes in it */ for(noteprcnt=0; noteprcnt< note_sect_counter; ++noteprcnt) { unsigned int note_sect_off = noteoffsets[noteprcnt]; printf("\n### found note section at offset: %#x ###\n", note_sect_off); int i=0; int note_counter=0; /* stupid loop this should contain a logical end of the notes int he section */ while( i < 3 ) { int j=0; char *note_name; /* note name storage */ unsigned int note_begin_off=0; /* beginning of the next note in the note section */ unsigned int note_name_begin_off=0; /* location of the note name member */ unsigned int note_desc_begin_off=0; /* location of description member */ unsigned int note_part_total=0; /* size of note header */ unsigned int note_name_total=0; /* size of name */ unsigned int note_desc_total=0; /* size of desc */ /* advance to the next note within the section */ //printf("%#x\n", note_next_note_off); note_begin_off = (unsigned int) note_sect_off + note_next_note_off; printf("\n--- note %d at offset %#x ---\n", note_counter, note_begin_off); /* the structure of a note in an ELF 0 1 2 3 -th byte a |-----------| s | namesz | c |-----------| appropriate padding is used for first 3 fields e | descsz | rest are limited by the upper n |-----------| for 64 bit arch i would assume we will d | type | have 8 byte padding instead of 4 |-----------| | | name | | |-----------| | | desc | V |-----------| */ /* find the note */ Elf32_Note_Part *elfnote = (Elf32_Note_Part *) ((unsigned char *) &longarray[note_begin_off]); /* includes terminating character */ printf("padding: %d bytes\n", NOTE_PADDING); printf("note name size: %#x bytes\n", elfnote->namesz); printf("note description size: %#x bytes\n", elfnote->descsz); /* total bytes of the partial elf note */ note_part_total = (unsigned int) (sizeof(elfnote->namesz) + sizeof(elfnote->descsz) + sizeof(elfnote->type)); /* calculate the name offset */ note_name_begin_off = note_begin_off + note_part_total; /* get note name and display it */ note_name = &longarray[note_name_begin_off]; printf ("note name: %s\n", note_name); /* padding must be accounted for */ note_name_total = (unsigned int) ( elfnote->namesz + \ (NOTE_PADDING - ((elfnote->namesz) % NOTE_PADDING))); /* padding must be accounted for */ /*note_desc_begin_off = note_name_begin_off + (unsigned int) ( strlen(note_name) + 1 + \ (NOTE_PADDING - ((strlen(note_name) +1) % NOTE_PADDING))); */ note_desc_begin_off = note_name_begin_off + note_name_total; switch (elfnote->type) { case NT_PRSTATUS: printf("note type: PRSTATUS [%d]\n", elfnote->type); prstatus_bool = TRUE; /* now initialize the prstatus structure */ struct elf_prstatus *prstat = (struct elf_prstatus *) ( (unsigned char *) &longarray[note_desc_begin_off]); /* display members as defined in sys/procfs.h */ /* signal info */ printf("signal number: %d\n", prstat->pr_info.si_signo); printf("extra code: %d\n", prstat->pr_info.si_code); printf("errno: %d\n", prstat->pr_info.si_errno); /* continue with prstatus */ printf("current signal: %d\n", prstat->pr_cursig); printf("set of pending signals: %#lx\n", prstat->pr_sigpend); printf("set of held signals: %#lx\n", prstat->pr_sigpend); printf("pid: %d\n", prstat->pr_pid); printf("ppid: %d\n", prstat->pr_pid); printf("pgrp: %d\n", prstat->pr_pgrp); printf("sid: %d\n", prstat->pr_sid); printf("user time: %d.%d sec\n", prstat->pr_utime.tv_sec, prstat->pr_utime.tv_usec); printf("system time: %d.%d sec\n", prstat->pr_stime.tv_sec, prstat->pr_stime.tv_usec); printf("cumulative user time: %d.%d sec\n", prstat->pr_cutime.tv_sec, prstat->pr_cutime.tv_usec); printf("cumulative system time: %d.%d sec\n", prstat->pr_cstime.tv_sec, prstat->pr_cstime.tv_usec); /* print out boolean that indicates TRUE if math copro being used */ printf("bool pr_fpvalid: %d\n", prstat->pr_fpvalid); /* display GP (general purpose) registers' values */ /* the user_regs struct has been converted as an array of long int for some reason */ /* size of this array is stored in ELF_NGREG ...why all this??? */ /* let's change it */ user_regs_struct *u_regs = (user_regs_struct *) ((unsigned char *) prstat->pr_reg); /* print the values */ printf("\ngeneral purpose registers:\n"); printf("ebx: %#10lx\t\t", u_regs->ebx); printf("ecx: %#10lx\t\t", u_regs->ecx); printf("edx: %#10lx\n", u_regs->edx); printf("esi: %#10lx\t\t", u_regs->esi); printf("edi: %#10lx\t\t", u_regs->edi); printf("ebp: %#10lx\n", u_regs->ebp); printf("eax: %#10lx\t\t", u_regs->eax); printf("xds: %#10lx\t\t", u_regs->xds); printf("xes: %#10lx\n", u_regs->xes); printf("xfs: %#10lx\t\t", u_regs->xfs); printf("xgs: %#10lx\t\t", u_regs->xgs); printf("orig_eax: %#10lx\n", u_regs->orig_eax); printf("eip: %#10lx\t\t", u_regs->eip); printf("xcs: %#10lx\t\t", u_regs->xcs); printf("eflags: %#12lx\n", u_regs->eflags); printf("esp: %#10lx\t\t", u_regs->esp); printf("xss: %#10lx\t\t\n", u_regs->xss); note_desc_total = (unsigned int) sizeof(struct elf_prstatus); note_next_note_off = (unsigned int) note_next_note_off + (note_part_total + note_name_total + note_desc_total); /*end of prstatus note handling section */ break; case NT_FPREGSET: printf("note type: FPREGSET [%d]\n", elfnote->type); break; case NT_PRPSINFO: printf("note type: PRPSINFO [%d]\n", elfnote->type); prpsinfo_bool = TRUE; struct elf_prpsinfo *prpsinfo = (struct elf_prpsinfo *) ( (unsigned char *) &longarray[note_desc_begin_off]); printf("numeric process state: %c\n", prpsinfo->pr_state); printf("char for pr_state: %c\n", prpsinfo->pr_sname); printf("zombie: %c\n", prpsinfo->pr_zomb); printf("nice val: %c\n", prpsinfo->pr_nice); printf("flag 1: %#lx\n", prpsinfo->pr_state); printf("uid: %d\n", prpsinfo->pr_uid); printf("gid: %d\n", prpsinfo->pr_gid); printf("pid: %d\n", prpsinfo->pr_pid); printf("ppid: %d\n", prpsinfo->pr_ppid); printf("pgrp: %d\n", prpsinfo->pr_pgrp); printf("sid: %d\n", prpsinfo->pr_sid); printf("filename or executable: %s\n", prpsinfo->pr_fname); //for (j=0; j < ELF_PRARGSZ; ++j) //{ // printf("argument list : %c\n", prpsinfo->pr_psargs[i]); //} note_desc_total = (unsigned int) sizeof(struct elf_prpsinfo); note_next_note_off = (unsigned int) note_next_note_off + (note_part_total + note_name_total + note_desc_total); break; case NT_PRXREG: printf("note type: PRXREG [%d]\n", elfnote->type); note_desc_total = elfnote->descsz; //next note offset for now note_next_note_off = (unsigned int) note_next_note_off + note_part_total + note_name_total + note_desc_total; printf("next note at %#x\n", note_next_note_off); break; //for completeness /*case NT_TASKSTRUCT: printf("note type: TASKSTRUCT [%d]\n", elfnote->type); break; */ case NT_PLATFORM: printf("note type: PLATFORM [%d]\n", elfnote->type); break; case NT_AUXV: printf("note type: AUXV [%d]\n", elfnote->type); break; case NT_GWINDOWS: printf("note type: GWINDOWS [%d]\n", elfnote->type); break; case NT_ASRS: printf("note type: ASRS [%d]\n", elfnote->type); break; case NT_PSTATUS: printf("note type: PSTATUS [%d]\n", elfnote->type); break; case NT_PSINFO: printf("note type: PSINFO [%d]\n", elfnote->type); break; case NT_PRCRED: printf("note type: PRCRED [%d]\n", elfnote->type); break; case NT_UTSNAME: printf("note type: UTSNAME [%d]\n", elfnote->type); break; case NT_LWPSTATUS: printf("note type: LWPSTATUS [%d]\n", elfnote->type); break; case NT_LWPSINFO: printf("note type: LWPSINFO [%d]\n", elfnote->type); break; case NT_PRFPXREG: printf("note type: PRFPXREG [%d]\n", elfnote->type); break; default: printf("note type: not recognized [%d]\n", elfnote->type); break; } ++i; ++note_counter; } } /* dump file contents onto stdout remove comment if necessary ... just for debugging write(fileno(stdout), longarray, statbuf.st_size); */ /* Section header processing */ } /* Section header processing */ elfhdr1 = (Elf32_Ehdr *) ((unsigned char *) &longarray[0x1000]); printf("\n.: ENCLOSED ELF HEADER INFORMATION at 0x1000 :.\n"); /* determine file class */ if (elfhdr1->e_ident[EI_CLASS] == ELFCLASS32) printf("capacity: 32 bit (ELFCLASS32) [%d]\n", \ elfhdr1->e_ident[EI_CLASS]); else if (elfhdr1->e_ident[EI_CLASS] == ELFCLASS64) printf("capacity: 64 bit (ELFCLASS64) [%d]\n", \ elfhdr1->e_ident[EI_CLASS]); else if (elfhdr1->e_ident[EI_CLASS] == ELFCLASSNONE) printf("capacity: none (ELFCLASSNONE) [%d]\n", \ elfhdr1->e_ident[EI_CLASS]); else printf("error: capacity not defined within ELF header [%d]\n", \ elfhdr1->e_ident[EI_CLASS]); /* determine data encoding type */ if (elfhdr1->e_ident[EI_DATA] == ELFDATA2LSB) printf("data encoding type: 2's comp, little endian (ELFDATA2LSB) [%d]\n",\ elfhdr1->e_ident[EI_DATA]); else if (elfhdr1->e_ident[EI_DATA] == ELFDATA2MSB) printf("data encoding type: 2's comp, big endian (ELFDATA2MSB) [%d]\n", \ elfhdr1->e_ident[EI_DATA]); else if (elfhdr1->e_ident[EI_DATA] == ELFDATANONE) printf("data encoding type: none (ELFCLASSNONE) [%d]\n", \ elfhdr1->e_ident[EI_DATA]); else printf("data encoding type: not defined within ELF header [%d]\n",\ elfhdr1->e_ident[EI_DATA]); /* determine version number (1 is current) and this is a must */ if (elfhdr1->e_ident[EI_VERSION] == EV_CURRENT) printf("file version: current (EV_CURRENT) [%d]\n", \ elfhdr1->e_ident[EI_VERSION]); else printf("file version: illegal version [%d]\n", \ elfhdr1->e_ident[EI_VERSION]); /* determine OS ABI identification (application binary interface) */ if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_NONE || elfhdr1->e_ident[EI_OSABI] == ELFOSABI_SYSV) printf("OS ABI: Unix System V ABI [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_HPUX) printf("OS ABI: HP-UX (ELFOSABI_HPUX) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_NETBSD) printf("OS ABI: NetBSD (ELFOSABI_NETBSD) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_LINUX) printf("OS ABI: Linux (ELFOSABI_LINUX) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_SOLARIS) printf("OS ABI: Solaris (ELFOSABI_SOLARIS) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_AIX) printf("OS ABI: AIX (ELFOSABI_AIX) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_IRIX) printf("OS ABI: Irix (ELFOSABI_IRIX) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_FREEBSD) printf("OS ABI: FreeBSD (ELFOSABI_FREEBSD) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_TRU64) printf("OS ABI: Compaq TRU64 Unix (ELFOSABI_HPUX) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_MODESTO) printf("OS ABI: Novell Modesto (ELFOSABI_MODESTO) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_OPENBSD) printf("OS ABI: OpenBSD (ELFOSABI_OPENBSD) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_ARM) printf("OS ABI: ARM (ELFOSABI_ARM) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else if (elfhdr1->e_ident[EI_OSABI] == ELFOSABI_STANDALONE) printf("OS ABI: Standalone (Embedded) Application (ELFOSABI_STANDALONE) [%d]\n", \ elfhdr1->e_ident[EI_OSABI]); else { printf("OS ABI: unknown [%d]\n", elfhdr1->e_ident[EI_OSABI]); os_abi_unknown = TRUE; } /* determine ABI version if aplicable */ if (!os_abi_unknown) printf("ABI version: %d\n", elfhdr1->e_ident[EI_ABIVERSION]); else printf("ABI version: unknown [%d]\n", elfhdr1->e_ident[EI_ABIVERSION]); /* display number of padding bytes */ printf("padding bytes: %d\n", elfhdr1->e_ident[EI_PAD]); /* determine object file type */ if (elfhdr1->e_type == ET_NONE) printf("object file type: no file type (ET_NONE) [%d]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_REL) printf("object file type: relocatable file (ET_REL) [%d]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_EXEC) printf("object file type: executable file (ET_EXEC) [%d]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_DYN) printf("object file type: shared object file (ET_DYN) [%d]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_CORE) printf("object file type: core file (ET_CORE) [%d]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_NUM) printf("object file type: number of defined types (ET_NUM) [%d]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_LOOS) printf("object file type: OS-specific range start (ET_LOOS) [%4x]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_HIOS) printf("object file type: OS-specific range end (ET_HIOS) [%4x]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_LOPROC) printf("object file type: Processor-specific range start (ET_LOPROC) [%4x]\n", \ elfhdr1->e_type); else if (elfhdr1->e_type == ET_HIPROC) printf("object file type: Processor-specific range end (ET_HIPROC) [%4x]\n", \ elfhdr1->e_type); else printf("object file type: undefined [%4x]\n", elfhdr1->e_type); /* determine architecture */ /* 100 definitions enter here... just 3 for right now*/ if (elfhdr1->e_machine == EM_NONE) printf("architecture: none (EM_NONE) [%d]\n", \ elfhdr1->e_machine); else if (elfhdr1->e_machine == EM_386) printf("architecture: Intel 80386 (EM_NONE) [%d]\n", \ elfhdr1->e_machine); else if (elfhdr1->e_machine == EM_SPARC) printf("architecture: Sun SPARC (EM_SPARC) [%d]\n", \ elfhdr1->e_machine); else printf("architecture: unknown [%d]\n", elfhdr1->e_machine); /* determine object file version */ if (elfhdr1->e_version == EV_NONE) printf("object file version: invalid ELF version (EV_NONE) [%d]\n", \ elfhdr1->e_version); else if (elfhdr1->e_version == EV_CURRENT) printf("object file version: current (EV_CURRENT) [%d]\n", \ elfhdr1->e_version); else printf("object file version: unknown [%d]\n", elfhdr1->e_version); /* display the entry point virtual address */ printf("entry point virtual address: %#x\n", elfhdr1->e_entry); /* display the program header table file offset */ printf("program header table file offset: %#x\n", elfhdr1->e_phoff); if (elfhdr1->e_phoff > 0) chk_phoff=1; /* display section header table file offset */ printf("section header table file offset: %#x\n", elfhdr1->e_shoff); /* display processor-specific flags */ printf("processor speciffic flags: %#x\n", elfhdr1->e_flags); /* display ELF header size in bytes */ printf("ELF header size: %d bytes\n", elfhdr1->e_ehsize); /* display program header table entry size */ printf("program header table entry size: %d bytes\n", \ elfhdr1->e_phentsize); if (elfhdr1->e_phentsize > 0) chk_phentsize=1; /* display program header table entry count */ printf("program header table entry count: %d\n", \ elfhdr1->e_phnum); if (elfhdr1->e_phnum > 0) chk_phnum=1; /* display section header table entry size */ printf("section header table entry size: %d bytes\n", \ elfhdr1->e_shentsize); /* display section header table entry count */ printf("section header table entry count: %d\n", \ elfhdr1->e_shnum); /* display section header string table index */ printf("section header string table index: %d\n", \ elfhdr1->e_shstrndx); /* unmap file; free the memory */ munmap(&longarray, statbuf.st_size); return(1); }