readelf 程序头节

从图中可以看出该目标文件包含8个程序头节,当然在程序编写时,需要先从elf头中获取该程序头节的个数和大小,我以此为例,并且假设程序头节的个数为8,大致解析程序如下(稍有不同 但足矣):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <fcntl.h>
#include <elf.h>
#include <unistd.h>




#define elf_file_path            "/home/code/test/main"
#define MA                      1
#define PHDR_SIZE                8


int main(int argc, char** argv) {


#ifdef __x86_64__
#if MA  
    Elf64_Phdr *phdrs = malloc(sizeof (Elf64_Phdr)*PHDR_SIZE);
    if (phdrs == NULL) {
        perror("malloc error");
    }
#else
    Elf64_Phdr phdrs[PHDR_SIZE];
#endif
#else
#if MA  
    Elf32_Phdr *phdrs = malloc(sizeof(Elf32_Phdr)*PHDR_SIZE);
    if (phdrs == NULL) {
        perror("malloc error");
    }
#else
    Elf32_Phdr phdrs[PHDR_SIZE];
#endif
#endif


#ifdef __x86_64__
    memset(phdrs, 0, sizeof (Elf64_Phdr)*PHDR_SIZE);
#else
    memset(phdrs, 0, sizeof (Elf32_Phdr)*PHDR_SIZE);
#endif


    int fd = open(elf_file_path, O_RDONLY);
    if (fd < 0) {
        perror("open elf file failed");
    }


#ifdef __x86_64__
    lseek(fd, 64, SEEK_SET);
    int ret;
    if ((ret = read(fd, phdrs, sizeof (Elf64_Phdr)*PHDR_SIZE)) < 1) {
        perror("read elf file failed");
    }
#else
    lseek(fd, 52, SEEK_SET);
    int ret;
    if ((ret = read(fd, phdrs, sizeof (Elf32_Phdr)*PHDR_SIZE)) < 1) {
        perror("read elf file failed");
    }
#endif


    int i = 0;
    printf("Type           Offset       VirtAddr        PhysAddr        FileSiz         MemSiz          Flg             Align\n");
#if 1
    for (; i < PHDR_SIZE; i++) {
#ifdef __x86_64__
#if MA
        Elf64_Phdr *phdr = phdrs++;
#else
        Elf64_Phdr *phdr = &phdrs[i];
#endif 
#else
#if MA
        Elf32_Phdr *phdr = phdrs++;
#else
        Elf32_Phdr *phdr = &phdrs[i];
#endif    
#endif


        switch (phdr->p_type) {
            case PT_NULL:
                printf("%s      ", "NULL");
                break;
            case PT_LOAD:
                printf("%s      ", "LOAD");
                break;
            case PT_DYNAMIC:
                printf("%s      ", "DYNA");
                break;
            case PT_INTERP:
                printf("%s      ", "INTERP");
                break;
            case PT_NOTE:
                printf("%s      ", "NOTE");
                break;
            case PT_SHLIB:
                printf("%s      ", "SHLIB");
                break;
            case PT_PHDR:
                printf("%s      ", "PHDR");
                break;
            case PT_TLS:
                printf("%s      ", "TLS");
                break;
            case PT_NUM:
                printf("%s      ", "NUM");
                break;
            case PT_LOOS:
                printf("%s      ", "LOOS");
                break;
            case PT_GNU_EH_FRAME:
                printf("%s      ", "GNU_EH_FRAME");
                break;
            case PT_GNU_STACK:
                printf("%s      ", "GNU_STACK");
                break;
            default:
                printf("%s      ", "OTHER");
                break;
        }
        printf("     0x%-6X     0x%-8X      0x%-8X      0x%-6X        0x%-6X",
                (phdr)->p_offset,
                (phdr)->p_vaddr,
                (phdr)->p_paddr,
                (phdr)->p_filesz,
                (phdr)->p_memsz);




        switch ((phdr)->p_flags) {
            case PF_W:
                printf("        %s", " W ");
                break;
            case PF_R:
                printf("        %s", "R  ");
                break;
            case (PF_W + PF_R):
                printf("        %s", "RW ");
                break;
            case PF_X:
                printf("        %s", "  E");
                break;
            case (PF_X + PF_R):
                printf("        %s", "R E");
                break;
            case (PF_X + PF_W):
                printf("        %s", " WE");
                break;
            case (PF_X + PF_W + PF_R):
                printf("        %s", "RWE");
                break;
            case (PF_MASKOS):
                printf("        %s", "MASKOS");
                break;
            case (PF_MASKPROC):
                printf("        %s", "MASKPROC");
                break;
            default:
                printf("        %s", " ");
                break;
        }


        printf("               0x%-4X\n", (phdr)->p_align);
    }
#if MA
    
    if (phdrs != NULL){
        phdrs = phdrs - PHDR_SIZE;
        free(phdrs);
    }
        
#endif
#endif
    close(fd);


    return (EXIT_SUCCESS);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值