2
votes

I have a simple cprogram to read the elf execution file,

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

While I am running this, I got output as,

Magic : 7f 45 4c 46 2 1 1 0 0 0 0 0 0 0 0

Class : ELF64

Type : Relocatable

Version : 1

Machine : AMD x86-64 architecture

Entry point address : 0

Start of program headers : 0

Start of section headers : 0

Number of program headers : 0

When I am running the readelf command for corresponding binary file I will get something like this,

ELF Header:

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

Class: ELF64

Data: 2's complement, little endian

Version: 1(current)

OS/ABI: UNIX - System V

ABI Version: 0

Type: EXEC (Executable file)

Machine: Advanced Micro Devices X86-64

Version: 0x1

Entry point address: 0x400780

Start of program headers: 64 (bytes into file)

Start of section headers: 8648 (bytes into file)

Flags: 0x0

Size of this header: 64 (bytes)

Size of program headers: 56 (bytes)

Number of program headers: 9

Size of section headers: 64 (bytes)

Number of section headers: 30

Section header string table index: 27

Why I am getting everything as 0 evenif they are not zero, I failed to find error in my code, I am new to this, please give a solution Thanks in advance,

1
After this 'if(hdr.e_machine==62)', there are three printf with bad format. It has simply 'printf("... %", args)', and the type 'd', 'c' or 'x', etc. is missing.gibertoni
no . It will work for datatype uint32, and also when using d c ,or x is not workinguser4558822
I see. Wasn't aware of this PRIu32 functionality. Maybe then, it is because for a 64-bit ELF file, the header is 64 bytes long, and those 3 fields should be stored in a larger type.gibertoni
Thanks, I will check that nowuser4558822

1 Answers

0
votes

You are trying to read 64 bit elf header to 32 bit header causing the problem. Try to use this,

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;

Or

Just use

Elf64_Ehdr hdr;

in your main instead of re declaring the whole structure.. Hope this will helpful for you