什麼是 ELF ( Executable and Linking ) Format 呢?jollen寫的相當清楚只是在看時發現他原本的 sample code 好像已經抓不下來了, 一方面也是自己很久沒有寫 code了, 所以照他的範例自己實作了一些東西,不過大體上是相同的.

/*
 * Copyright (C) 2009 http://sakbk.pixnet.net/blog
 *
 * ELF Sample code.
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <elf.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>

void READ_SECTION(Elf32_Ehdr *pEhdr, int fd) {
    Elf32_Shdr header[pEhdr->e_shnum];
    unsigned char *p_Shdr;

    int i, stroff, idx;
    printf("<Section Header>\n");

    //move to section header entry point offset
    lseek(fd, pEhdr->e_shoff, SEEK_SET);

    for (i = 0; i < pEhdr->e_shnum; i++) {
         read(fd, &header[i], sizeof(Elf32_Shdr));
         if (i == pEhdr->e_shstrndx ) {
             stroff = header[i].sh_offset;
             idx = i;
         }
    } 
   
    lseek(fd, stroff, SEEK_SET);
    p_Shdr=(unsigned char *)malloc(header[idx].sh_size);
    read(fd, p_Shdr, header[idx].sh_size);

    for (i = 1; i < pEhdr->e_shnum; i++)
         printf("\t[%.2d] - %-15.30s \t%.8x\n", i, &p_Shdr[header[i].sh_name], header[i].sh_offset);
}

void ELF_ARCH(Elf64_Half machine) {
  switch (machine) {
     case EM_M32:
          printf("\tARCH:\tAT&T WE 32100\n");
          break;
     case EM_SPARC:
          printf("\tARCH:\tSUN SPARCn");
          break;
     case EM_386:
          printf("\tARCH:\tIntel 80386\n");
          break;
     case EM_68K:
          printf("\tARCH:\tMotorola m68k family\n");
          break;
     case EM_88K:
          printf("\tARCH:\tMotorola m88k family\n");
          break;
     case EM_860:
          printf("\tARCH:\tIntel 80860 \n");
          break;
     default:
          printf("\tARCH:\tUnkown\n");
  } 
}

void ELF_TYPE(Elf32_Half type) {
  switch (type) {
     case ET_NONE:
          printf("\tTYPE:\tET_NONE\n");
          break;
     case ET_REL:
          printf("\tTYPE:\tET_REL\n");
          break;
     case ET_EXEC:
          printf("\tTYPE:\tET_EXEC\n");
          break;
     case ET_DYN:
          printf("\tTYPE:\tET_DYN\n");
          break;
  }
}

int ELF_CLASS(unsigned char *idx) {
   switch ( *( idx + EI_CLASS ) ) {
      case ELFCLASSNONE:
           printf("\tCLASS:\tNONE\n");
           break;
      case ELFCLASS32:
           printf("\tCLASS:\tELF32\n");
           break;
      case ELFCLASS64:
           printf("\tCLASS:\tELF64\n");
           break;
   } 
}

int IS_ELF(unsigned char *idx) {
   if( *( idx + EI_MAG0 ) !=  ELFMAG0 || \
       *( idx + EI_MAG1 ) !=  ELFMAG1 || \
       *( idx + EI_MAG2 ) !=  ELFMAG2 || \
       *( idx + EI_MAG3 ) !=  ELFMAG3
     ) {
        return 0;
   }
        return 1;
}

int usage(char *argv) {
   printf("Usage: %s filename\n", argv);
}

int main(int argc, char *argv[]) {
   int fd;
   Elf32_Ehdr e_hdr;

   if(argc < 2) {
      usage(*argv);
      return -1;
   }

   fd = open(argv[1], S_IRUSR);
   if(fd < 0) {
      printf("file open error\n");
      return -1;
   }

   read(fd, &e_hdr, sizeof(Elf32_Ehdr));
 
   if(IS_ELF(e_hdr.e_ident)) {
     printf("<ELF headers>\n");
     ELF_CLASS(e_hdr.e_ident);
     ELF_TYPE(e_hdr.e_type);
     ELF_ARCH(e_hdr.e_machine);
     READ_SECTION(&e_hdr, fd);
   }
   else {
     printf("Invalid ELF file\n");
   }
}

參考資料:

http://www.jollen.org/EmbeddedLinux/Executable_Linking_Format.html

本文出處: http://www.jollen.org, 已取得原作者同意並授權使用.

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 sakbk 的頭像
    sakbk

    sakbk

    sakbk 發表在 痞客邦 留言(0) 人氣()