什麼是 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, 已取得原作者同意並授權使用.
留言列表