?? read_elf.cpp
字號:
/*************************************************************************
Copyright (C) 2002,2003,2004,2005 Wei Qin
See file COPYING for more information.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*************************************************************************/
#include <read_elf.h>
#include <stdlib.h>
#include <string.h>
#define SwapHalf(a) (((a & 0x00ff) << 8) | ((a & 0xff00) >> 8))
#define SwapWord(a) (((a & 0xff000000) >> 24) | ((a & 0x00ff0000) >> 8) | ((a & 0x0000ff00) << 8) | ((a & 0x000000ff) << 24))
#define SwapAddr(a) SwapWord(a)
#define SwapOff(a) SwapWord(a)
int LittleEndian()
{
Elf32_Word a = 0x01020304;
return *(char *) &a == 0x04;
}
void SwapElfHeader(Elf32_Ehdr *hdr)
{
hdr->e_type = SwapHalf(hdr->e_type);
hdr->e_machine = SwapHalf(hdr->e_machine);
hdr->e_version = SwapWord(hdr->e_version);
hdr->e_entry = SwapAddr(hdr->e_entry);
hdr->e_phoff = SwapOff(hdr->e_phoff);
hdr->e_shoff = SwapOff(hdr->e_shoff);
hdr->e_flags = SwapWord(hdr->e_flags);
hdr->e_ehsize = SwapHalf(hdr->e_ehsize);
hdr->e_phentsize = SwapHalf(hdr->e_phentsize);
hdr->e_phnum = SwapHalf(hdr->e_phnum);
hdr->e_shentsize = SwapHalf(hdr->e_shentsize);
hdr->e_shnum = SwapHalf(hdr->e_shnum);
hdr->e_shstrndx = SwapHalf(hdr->e_shstrndx);
}
void SwapProgramHeader(Elf32_Phdr *phdr)
{
phdr->p_type = SwapWord(phdr->p_type);
phdr->p_offset = SwapOff(phdr->p_offset);
phdr->p_vaddr = SwapAddr(phdr->p_vaddr);
phdr->p_paddr = SwapAddr(phdr->p_paddr);
phdr->p_filesz = SwapWord(phdr->p_filesz);
phdr->p_memsz = SwapWord(phdr->p_memsz);
phdr->p_flags = SwapWord(phdr->p_flags);
phdr->p_align = SwapWord(phdr->p_align);
}
void SwapSectionHeader(Elf32_Shdr *shdr)
{
shdr->sh_name = SwapWord(shdr->sh_name);
shdr->sh_type = SwapWord(shdr->sh_type);
shdr->sh_flags = SwapWord(shdr->sh_flags);
shdr->sh_addr = SwapAddr(shdr->sh_addr);
shdr->sh_offset = SwapOff(shdr->sh_offset);
shdr->sh_size = SwapWord(shdr->sh_size);
shdr->sh_link = SwapWord(shdr->sh_link);
shdr->sh_info = SwapWord(shdr->sh_info);
shdr->sh_addralign = SwapWord(shdr->sh_addralign);
shdr->sh_entsize = SwapWord(shdr->sh_entsize);
}
void AdjustElfHeader(Elf32_Ehdr *hdr)
{
switch(hdr->e_ident[EI_DATA])
{
case ELFDATA2LSB:
if(!LittleEndian())
SwapElfHeader(hdr);
break;
case ELFDATA2MSB:
if(LittleEndian())
SwapElfHeader(hdr);
break;
}
}
void AdjustProgramHeader(Elf32_Ehdr *hdr, Elf32_Phdr *phdr)
{
switch(hdr->e_ident[EI_DATA])
{
case ELFDATA2LSB:
if(!LittleEndian())
SwapProgramHeader(phdr);
break;
case ELFDATA2MSB:
if(LittleEndian())
SwapProgramHeader(phdr);
break;
}
}
void AdjustSectionHeader(Elf32_Ehdr *hdr, Elf32_Shdr *shdr)
{
switch(hdr->e_ident[EI_DATA])
{
case ELFDATA2LSB:
if(!LittleEndian())
SwapSectionHeader(shdr);
break;
case ELFDATA2MSB:
if(LittleEndian())
SwapSectionHeader(shdr);
break;
}
}
Elf32_Ehdr *ReadElfHeader(FILE *f)
{
Elf32_Ehdr *hdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr));
if(fseek(f, 0, SEEK_SET) != 0)
{
free(hdr);
return NULL;
}
if(fread(hdr, sizeof(Elf32_Ehdr), 1, f) != 1)
{
free(hdr);
return NULL;
}
if(hdr->e_ident[EI_MAG0] != 0x7f ||
hdr->e_ident[EI_MAG1] != 'E' ||
hdr->e_ident[EI_MAG2] != 'L' ||
hdr->e_ident[EI_MAG3] != 'F')
{
free(hdr);
return NULL;
}
hdr = (Elf32_Ehdr *) realloc(hdr, hdr->e_ehsize);
AdjustElfHeader(hdr);
return hdr;
}
Elf32_Phdr *ReadProgramHeaders(Elf32_Ehdr *hdr, FILE *f)
{
int i;
unsigned long sz = hdr->e_phnum * hdr->e_phentsize;
Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sz);
fseek(f, hdr->e_phoff, SEEK_SET);
fread(phdr, sz, 1, f);
for(i = 0; i < hdr->e_phnum; i++)
AdjustProgramHeader(hdr, phdr + i);
return phdr;
}
Elf32_Shdr *ReadSectionHeaders(Elf32_Ehdr *hdr, FILE *f)
{
int i;
unsigned long sz = hdr->e_shnum * hdr->e_shentsize;
Elf32_Shdr *shdr = (Elf32_Shdr *) malloc(sz);
if(fseek(f, hdr->e_shoff, SEEK_SET) != 0)
{
free(shdr);
return NULL;
}
if(fread(shdr, sz, 1, f) != 1)
{
free(shdr);
return NULL;
}
for(i = 0; i < hdr->e_shnum; i++)
AdjustSectionHeader(hdr, shdr + i);
return shdr;
}
char *LoadStringTable(Elf32_Ehdr *hdr, Elf32_Shdr *shdr_table, FILE *f)
{
Elf32_Shdr *shdr = shdr_table + hdr->e_shstrndx;
char *string_table;
string_table = (char *) malloc(shdr->sh_size);
fseek(f, shdr->sh_offset, SEEK_SET);
fread(string_table, shdr->sh_size, 1, f);
return string_table;
}
void DumpElfHeader(Elf32_Ehdr *hdr)
{
printf("--- Elf Header ---");
printf("\nClass : ");
switch(hdr->e_ident[EI_CLASS])
{
case ELFCLASSNONE : printf("Invalid class"); break;
case ELFCLASS32 : printf("32-bit objects"); break;
case ELFCLASS64 : printf("64-bit objects"); break;
default : printf("?"); break;
}
printf("\nData encoding : ");
switch(hdr->e_ident[EI_DATA])
{
case ELFDATANONE : printf("Invalid data encoding"); break;
case ELFDATA2LSB : printf("2's complement, little endian"); break;
case ELFDATA2MSB : printf("2's complement, big endian"); break;
}
printf("\nVersion : %u", (unsigned int) hdr->e_ident[EI_VERSION]);
/* printf("\nOS ABI identification : "); */
/* switch(hdr->e_ident[EI_OSABI]) */
/* { */
/* case ELFOSABI_SYSV : printf("UNIX System V ABI"); break; */
/* case ELFOSABI_HPUX : printf("HP-UX"); break; */
/* case ELFOSABI_ARM : printf("ARM"); break; */
/* case ELFOSABI_STANDALONE : printf("Standalone (embedded) application"); */
/* default : printf("?"); */
/* } */
printf("\nObject File Type : ");
switch(hdr->e_type)
{
case ET_NONE : printf("No file type"); break;
case ET_REL : printf("Relocatable file"); break;
case ET_EXEC : printf("Executable file"); break;
case ET_DYN : printf("Shared object file"); break;
case ET_CORE : printf("Core file"); break;
case ET_NUM : printf("Number of defined types"); break;
case ET_LOPROC : printf("Processor-specific"); break;
case ET_HIPROC : printf("Processor-specific"); break;
default : printf("?");
}
printf("\nTarget machine : ");
/* switch(hdr->e_machine) */
/* { */
/* case EM_NONE : printf("No machine"); break; */
/* case EM_M32 : printf("AT&T WE 32100"); break; */
/* case EM_SPARC : printf("SUN SPARC"); break; */
/* case EM_386 : printf("Intel 80386"); break; */
/* case EM_68K : printf("Motorola m68k family"); break; */
/* case EM_88K : printf("Motorola m88k family"); break; */
/* case EM_486 : printf("Intel 80486"); break; */
/* case EM_860 : printf("Intel 80860"); break; */
/* case EM_MIPS : printf("MIPS R3000 big-endian"); break; */
/* case EM_S370 : printf("Amdahl"); break; */
/* case EM_MIPS_RS4_BE : printf("MIPS R4000 big-endian"); break; */
/* case EM_RS6000 : printf("RS6000"); break; */
/* case EM_PARISC : printf("HPPA"); break; */
/* case EM_nCUBE : printf("nCUBE"); break; */
/* case EM_VPP500 : printf("Fujitsu VPP500"); break; */
/* case EM_SPARC32PLUS : printf("Sun v8plus"); break; */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -