欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

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

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


最近在学ELF文件相关知识,感觉学得不是很透彻,欢迎大家前来讨论。
程序源代码贴在最后。

#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;

}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功