ELF(Executable and Linking Format)格式教學文件, #6: 讀 ELF Section(程式列表)

jollen 發表於 December 4, 2006 4:39 PM

範例列表:loader v0.3

/*
 * Copyright(c) 2003,2006 www.jollen.org
 *
 * ELF programming. ver 0.3
 *
 */
#include <stdio.h>
#include <unistd.h>
#include <elf.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int elf_ident(char *ident)
{
   if (*(ident+EI_MAG0) != ELFMAG0) return 0;
   if (*(ident+EI_MAG1) != ELFMAG1) return 0;
   if (*(ident+EI_MAG2) != ELFMAG2) return 0;
   if (*(ident+EI_MAG3) != ELFMAG3) return 0;

   return -1;
}

void parse_ident(char *ident)
{
   printf("ELF Identification\n");

   printf("  Class:     ");
   switch (*(ident+EI_CLASS)) {
      case ELFCLASSNONE: printf("Invalid class\n"); break;
      case ELFCLASS32: printf("32-bit objects\n"); break;
      case ELFCLASS64: printf("64-bit objects\n"); break;
   }
}

void parse_machine(Elf32_Half machine)
{
   printf("Machine:     ");
   switch (machine) {
      case EM_NONE: printf("No machine\n"); break;
      case EM_M32: printf("AT&T WE 32100\n"); break;
      case EM_SPARC: printf("SPARC\n"); break;
      case EM_386: printf("Intel 80386\n"); break;
      case EM_68K: printf("Motorola 68000\n"); break;
      case EM_88K: printf("Motorola 88000\n"); break;
      case EM_860: printf("Intel 80860\n"); break;
      case EM_MIPS: printf("MIPS RS3000 Big-Endian\n"); break;

      default: printf("Unknow\n");
   }
}

void parse_sections(Elf32_Ehdr *hdr, int fd)
{
   int i;
   Elf32_Shdr header[40];
   Elf32_Shdr *strtab;          /* point to string table */

   printf("Num of secionts: %d\n", hdr->e_shnum);
   /* file offset of section header table */
   lseek(fd, hdr->e_shoff, SEEK_SET);

   for (i = 0; i < hdr->e_shnum; i++) {
      read(fd, &header[i], sizeof(Elf32_Shdr));

      /* find out string table ! */
      if (header[i].sh_type == SHT_STRTAB) strtab = &header[i];
   }
}

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

   if (argc != 2) {
      printf("Usage:    loader [filename]\n");
      return -1;
   }

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

   /* Read ELF Header */
   read(fd, &f_header, sizeof(Elf32_Ehdr));

   /* Parse header information */
   if (elf_ident(f_header.e_ident)) {
      parse_ident(f_header.e_ident);
      parse_machine(f_header.e_machine);
      parse_sections(&f_header, fd);
   } else {
      printf("not a ELF binary file\n");
   }

   close(fd);
} 

執行結果

$ ./loader-0.3 ./loader-0.3
ELF Identification
  Class:     32-bit objects
Machine:     Intel 80386
Num of secionts: 34
Also See

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw