首页
社区
课程
招聘
[原创]ELF文件格式学习笔记2: .symtab格式解析
发表于: 2017-12-27 00:42 6498

[原创]ELF文件格式学习笔记2: .symtab格式解析

2017-12-27 00:42
6498
#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,&sectionHeaders[i].sh_name,sizeof(sectionHeaders[i].sh_name));
        read(fd,&sectionHeaders[i].sh_type,sizeof(sectionHeaders[i].sh_type));
        read(fd,&sectionHeaders[i].sh_flags,sizeof(sectionHeaders[i].sh_flags));
        read(fd,&sectionHeaders[i].sh_addr,sizeof(sectionHeaders[i].sh_addr));
        read(fd,&sectionHeaders[i].sh_offset,sizeof(sectionHeaders[i].sh_offset));
        read(fd,&sectionHeaders[i].sh_size,sizeof(sectionHeaders[i].sh_size));
        read(fd,&sectionHeaders[i].sh_link,sizeof(sectionHeaders[i].sh_link));
        read(fd,&sectionHeaders[i].sh_info,sizeof(sectionHeaders[i].sh_info));
        read(fd,&sectionHeaders[i].sh_addralign,sizeof(sectionHeaders[i].sh_addralign));
        read(fd,&sectionHeaders[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;
}



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 341
活跃值: (138)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
谢谢分享代码
2017-12-27 09:16
0
雪    币: 47147
活跃值: (20420)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
建议直接将PDF文件帖到论坛里,效果会更好。
2018-1-2 11:09
0
游客
登录 | 注册 方可回帖
返回
//