读取精灵结构给出零值

时间:2015-02-12 12:10:40

标签: c linker elf

我有一个简单的cprogram来读取elf执行文件,

#include <stdint.h>
#include <inttypes.h>
#include <elf.h>
#include <stdio.h> 
#include <stdlib.h>

#pragma pack(push,1)

typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t uint8; 

typedef struct
{
  uint8  e_ident[16];
  uint16 e_type;
  uint16 e_machine;
  uint32 e_version;
  uint32 e_entry;
  uint32 e_phoff;
  uint32 e_shoff;
  uint32 e_flags;
  uint16 e_ehsize;
  uint16 e_phentsize;
  uint16 e_phnum;
  uint16 e_shentsize;
  uint16 e_shnum;
  uint16 e_shstrndx;
} Elf32Hdr;

typedef struct
{
  uint32 sh_name;
  uint32 sh_type;
  uint32 sh_flags;
  uint32 sh_addr;
  uint32 sh_offset;
  uint32 sh_size;
  uint32 sh_link;
  uint32 sh_info;
  uint32 sh_addralign;
  uint32 sh_entsize;
} Elf32SectHdr;

#pragma pack(pop)

main()
{

    printf ("Main()");
    char mystring [100];
    FILE* ElfFile = NULL;
    FILE* ofile = NULL;
    char* SectNames = NULL;
    Elf32Hdr hdr;
    Elf32SectHdr shdr;
    uint idx;

    ElfFile = fopen ( "test.o" , "rb" );  
    if (ElfFile==NULL) 
    {
        printf ("\nFile error"); 
        exit (1);
    }

    if (1 != fread(&hdr, sizeof(hdr), 1, ElfFile))
    {
            printf("failed to read elf header\n");
            exit(1);
    }
    int i; 

    printf("\nMagic  :");
    for(i=0;i<15;++i) 
        printf("   %x",hdr.e_ident[i]);

    char *class; 
    if(hdr.e_ident[4]==2)
        class = "64";
    if(hdr.e_ident[4]==1)
        class = "32";
    if(hdr.e_ident[4]==0)
        class = "Inavalid Class";

    printf("\nClass :\t\t\t%c%c%c%s",hdr.e_ident[1],hdr.e_ident[2],hdr.e_ident[3],class);  

    printf("\nType :\t\t\t ");
    if(hdr.e_type == 1)
        printf("Relocatable\n");
    else if(hdr.e_type == 2)
        printf("Executable\n");
    else if(hdr.e_type == 3)
        printf("Shared Object\n");
    else
        printf("Unknown\n");  

    printf("\nVersion :\t\t\tt%"PRIu32,hdr.e_version);

    if(hdr.e_machine==62)
        printf("\nMachine :\t\t\t AMD x86-64 architecture");
    printf("\nEntry point address :\t\t\t %"PRIu32,hdr.e_entry);
    printf("\nStart of program headers :\t\t\t  %"PRIu32,hdr.e_phoff);
    printf("\nStart of section headers :\t\t\t %"PRIu32,hdr.e_shoff); 


    printf("\nNumber of program headers :\t\t\t %d\n", hdr.e_phnum); 

    fseek(ElfFile, hdr.e_shoff + hdr.e_shstrndx * sizeof shdr, SEEK_SET);
    if (1 != fread(&shdr, 1, sizeof shdr, ElfFile)) 
    {
            printf("failed to read elf section header\n");
            exit(1);
    } 
} 

我在运行时,输出为

  

魔术:7f 45 4c 46 2 1 1 0 0 0 0 0 0 0 0

     

班级:ELF64

     

类型:可重定位

     

版本:1

     

机器:AMD x86-64架构

     

入口点地址:0

     

程序标题的开头:0

     

部分标题的开头:0

     

程序头数:0

当我运行相应二进制文件的readelf命令时,我将得到类似的内容,

  

ELF标题:

     

Magic:7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00

     

班级:ELF64

     

数据:2&#39;补充,小端

     

版本:1(当前)

     

OS / ABI:UNIX - System V

     

ABI版本:0

     

键入:EXEC(可执行文件)

     

机器:Advanced Micro Devices X86-64

     

版本:0x1

     

入口点地址:0x400780

     

程序头的开始:64(字节到文件)

     

节标题的开头:8648(字节到文件)

     

标志:0x0

     

此标题的大小:64(字节)

     

程序头大小:56(字节)

     

节目标题数:9

     

节标题的大小:64(字节)

     

节标题数量:30

     

节头字符串表索引:27

为什么我将所有内容都设为0,即使它们不为零,我在代码中找不到错误,我是新手,请给出一个解决方案 提前谢谢,

1 个答案:

答案 0 :(得分:0)

您正在尝试将64位elf标头读取到32位标头,从而导致出现此问题。 尝试使用它,

typedef struct elf64_hdr {
unsigned char e_ident[16];      /* ELF "magic number" */
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;     /* Entry point virtual address */
Elf64_Off e_phoff;      /* Program header table file offset */
Elf64_Off e_shoff;      /* Section header table file offset */
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;

或者

只需使用

Elf64_Ehdr hdr;

在你的主要而不是重新声明整个结构..希望这对你有帮助