#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<elf.h>
const char *symtype[]={"STT_NOTYPE","STT_OBJECT","STT_FUNC","STT_SECTION","STT_FILE","STT_COMMON","STT_TLS"};
const char *symbind[]={"STB_LOCAL","STB_GLOBAL","STB_WEAK"};
const char *symvisual[]={"STV_DEFAULT","STV_INTERNAL","STV_HIDDEN","STV_PROTECTED"};
int fd=-1;
Elf64_Ehdr elfhdr;
Elf64_Shdr *sectionHeaders=NULL;
unsigned char **sectionsPtr=NULL;
//节名字符串表下标
unsigned int shstrsecInd=-1;
//.bss节下标
unsigned int bsssecInd=-1;
//.strtab节下标
unsigned int strtabInd=-1;
//.symtab节下标
unsigned int symtabInd=-1;
void getElfHeader(void)
{
read(fd,elfhdr.e_ident,EI_NIDENT);
read(fd,&elfhdr.e_type,sizeof(elfhdr.e_type));
read(fd,&elfhdr.e_machine,sizeof(elfhdr.e_machine));
read(fd,&elfhdr.e_version,sizeof(elfhdr.e_version));
read(fd,&elfhdr.e_entry,sizeof(elfhdr.e_entry));
read(fd,&elfhdr.e_phoff,sizeof(elfhdr.e_phoff));
read(fd,&elfhdr.e_shoff,sizeof(elfhdr.e_shoff));
read(fd,&elfhdr.e_flags,sizeof(elfhdr.e_flags));
read(fd,&elfhdr.e_ehsize,sizeof(elfhdr.e_ehsize));
read(fd,&elfhdr.e_phentsize,sizeof(elfhdr.e_phentsize));
read(fd,&elfhdr.e_phnum,sizeof(elfhdr.e_phnum));
read(fd,&elfhdr.e_shentsize,sizeof(elfhdr.e_shentsize));
read(fd,&elfhdr.e_shnum,sizeof(elfhdr.e_shnum));
read(fd,&elfhdr.e_shstrndx,sizeof(elfhdr.e_shstrndx));
}
void getSectionHeaders(void)
{
sectionHeaders=(Elf64_Shdr *)calloc(elfhdr.e_shnum,sizeof(Elf64_Shdr));
lseek(fd,elfhdr.e_shoff,SEEK_SET);
int i=0;
for(i=0;i<elfhdr.e_shnum;i++)
{
read(fd,§ionHeaders[i].sh_name,sizeof(sectionHeaders[i].sh_name));
read(fd,§ionHeaders[i].sh_type,sizeof(sectionHeaders[i].sh_type));
read(fd,§ionHeaders[i].sh_flags,sizeof(sectionHeaders[i].sh_flags));
read(fd,§ionHeaders[i].sh_addr,sizeof(sectionHeaders[i].sh_addr));
read(fd,§ionHeaders[i].sh_offset,sizeof(sectionHeaders[i].sh_offset));
read(fd,§ionHeaders[i].sh_size,sizeof(sectionHeaders[i].sh_size));
read(fd,§ionHeaders[i].sh_link,sizeof(sectionHeaders[i].sh_link));
read(fd,§ionHeaders[i].sh_info,sizeof(sectionHeaders[i].sh_info));
read(fd,§ionHeaders[i].sh_addralign,sizeof(sectionHeaders[i].sh_addralign));
read(fd,§ionHeaders[i].sh_entsize,sizeof(sectionHeaders[i].sh_entsize));
}
}
void getSections(void)
{
int i=0;
sectionsPtr=(unsigned char **)calloc(elfhdr.e_shnum,sizeof(unsigned char *));
for(i=0;i<elfhdr.e_shnum;i++)
{
if(sectionsPtr[i]!=NULL)
free(sectionsPtr[i]);
sectionsPtr[i]=(unsigned char *)calloc(sectionHeaders[i].sh_size,1);
if(sectionsPtr[i]==NULL)
{
printf("i=%u\tsh_size=%lu\n",i,sectionHeaders[i].sh_size);
perror("calloc:");
exit(1);
}
lseek(fd,sectionHeaders[i].sh_offset,SEEK_SET);
read(fd,sectionsPtr[i],sectionHeaders[i].sh_size);
}
for(i=0;i<elfhdr.e_shnum;i++)
{
if(strcmp(sectionsPtr[elfhdr.e_shstrndx]+sectionHeaders[i].sh_name,".strtab")==0)
{
strtabInd=i;
}
else if(strcmp(sectionsPtr[elfhdr.e_shstrndx]+sectionHeaders[i].sh_name,".symtab")==0)
{
symtabInd=i;
}
}
}
void prtSymbols(void)
{
printf("**************************符号信息*********************************\n");
printf("\t%-8s %16s %-9s %-16s %-11s %-16s %-10s %-40s\n","序号","符号值","BIND","type","可见状态","size","SHNDX","符号名称");
unsigned int i;
for(i=0;i<sectionHeaders[symtabInd].sh_size/sectionHeaders[symtabInd].sh_entsize;i++)
{
Elf64_Sym tmpsym;
memcpy(&tmpsym.st_name,sectionsPtr[symtabInd]+i*24,4);
memcpy(&tmpsym.st_info,sectionsPtr[symtabInd]+i*24+4,1);
memcpy(&tmpsym.st_other,sectionsPtr[symtabInd]+i*24+5,1);
memcpy(&tmpsym.st_shndx,sectionsPtr[symtabInd]+i*24+6,2);
memcpy(&tmpsym.st_value,sectionsPtr[symtabInd]+i*24+8,8);
memcpy(&tmpsym.st_size,sectionsPtr[symtabInd]+i*24+16,8);
printf("\t%-8d %-16x %-9s %-16s %-11s %-16x %-10x %-40s\n\n",\
i,
tmpsym.st_value,
symbind[ELF64_ST_BIND(tmpsym.st_info)],
symtype[ELF64_ST_TYPE(tmpsym.st_info)],
symvisual[tmpsym.st_other],
tmpsym.st_size,
tmpsym.st_shndx,
sectionsPtr[strtabInd]+tmpsym.st_name);
}
}
int main(int argc,char *argv[])
{
if(argc==1)
fd=open(argv[0],O_RDONLY);
else
fd=open(argv[1],O_RDONLY);
getElfHeader();
getSectionHeaders();
getSections();
unsigned int i=0;
printf("节名称\n");
for(i=0;i<elfhdr.e_shnum;i++)
{
printf("\t%s\n",sectionsPtr[elfhdr.e_shstrndx]+sectionHeaders[i].sh_name);
}
prtSymbols();
return 0;
}