/* Chrysalide - Outil d'analyse de fichiers binaires
* header.c - annotation des en-têtes de binaires ELF
*
* Copyright (C) 2015 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* OpenIDA 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 3 of the License, or
* (at your option) any later version.
*
* OpenIDA 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.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see .
*/
#include "header.h"
#include
#include
#include
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
* *
* Description : Charge tous les symboles de l'en-tête ELF. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool annotate_elf_header(GElfFormat *format)
{
GBinContent *content; /* Contenu binaire à lire */
const elf_header *header; /* En-tête principale */
SourceEndian endian; /* Boutisme utilisé */
vmpa2t pos; /* Tête de lecture des symboles*/
vmpa2t start; /* Localisation des symboles */
GArchInstruction *instr; /* Instruction décodée */
GArchOperand *operand; /* Opérande à venir modifier */
GDbComment *comment; /* Définition de commentaire */
GBinSymbol *symbol; /* Symbole à intégrer */
const char *text; /* Texte constant à insérer */
content = g_binary_format_get_content(G_BIN_FORMAT(format));
header = g_elf_format_get_header(format);
endian = g_elf_format_get_endianness(format);
if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos))
return false;
/* ELFMAG (0) */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR);
SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR);
SET_IMM_DISPLAY(instr, operand, 3, IOD_CHAR);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("ELF magic number"));
/* EI_CLASS (4) */
switch (header->hdr32.e_ident[EI_CLASS])
{
case EV_NONE:
text = _("File class: invalid");
break;
case ELFCLASS32:
text = _("File class: 32-bit objects");
break;
case ELFCLASS64:
text = _("File class: 64-bit objects");
break;
default:
text = _("File class: unknown");
break;
}
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text);
/* EI_DATA (5) */
switch (header->hdr32.e_ident[EI_DATA])
{
case ELFDATANONE:
text = _("Data encoding: invalid");
break;
case ELFDATA2LSB:
text = _("Data encoding: 2's complement, little endian");
break;
case ELFDATA2MSB:
text = _("Data encoding: 2's complement, big endian");
break;
default:
text = _("Data encoding: unknown");
break;
}
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text);
/* EI_VERSION (6) */
switch (header->hdr32.e_ident[EI_VERSION])
{
case EV_NONE:
text = _("File version: invalid");
break;
case EV_CURRENT:
text = _("File version: current");
break;
default:
text = _("File version: unknown");
break;
}
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text);
/* EI_OSABI (7) */
switch (header->hdr32.e_ident[EI_OSABI])
{
case ELFOSABI_SYSV:
text = _("OS ABI: UNIX System V");
break;
case ELFOSABI_HPUX:
text = _("OS ABI: HP-UX");
break;
case ELFOSABI_NETBSD:
text = _("OS ABI: NetBSD");
break;
case ELFOSABI_GNU:
text = _("OS ABI: object uses GNU ELF extensions");
break;
case ELFOSABI_SOLARIS:
text = _("OS ABI: Sun Solaris");
break;
case ELFOSABI_AIX:
text = _("OS ABI: IBM AIX");
break;
case ELFOSABI_IRIX:
text = _("OS ABI: SGI Irix");
break;
case ELFOSABI_FREEBSD:
text = _("OS ABI: FreeBSD");
break;
case ELFOSABI_TRU64:
text = _("OS ABI: Compaq TRU64 UNIX");
break;
case ELFOSABI_MODESTO:
text = _("OS ABI: Novell Modesto");
break;
case ELFOSABI_OPENBSD:
text = _("OS ABI: OpenBSD");
break;
case ELFOSABI_ARM_AEABI:
text = _("OS ABI: ARM EABI");
break;
case ELFOSABI_ARM:
text = _("OS ABI: ARM");
break;
case ELFOSABI_STANDALONE:
text = _("OS ABI: standalone (embedded) application");
break;
default:
text = _("OS ABI: unknown");
break;
}
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text);
/* EI_ABIVERSION (8) */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("ABI version"));
/* Padding */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_8_BITS, 7, &pos, endian);
g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Padding"));
/* Champ "e_type" */
switch (header->hdr32.e_type)
{
case ET_NONE:
text = _("Object file type: no file type");
break;
case ET_REL:
text = _("Object file type: relocatable file");
break;
case ET_EXEC:
text = _("Object file type: executable file");
break;
case ET_DYN:
text = _("Object file type: shared object file");
break;
case ET_CORE:
text = _("Object file type: core file");
break;
case ET_LOOS ... ET_HIOS:
text = _("Object file type: OS-specific");
break;
case ET_LOPROC ... ET_HIPROC:
text = _("Object file type: processor-specific");
break;
default:
text = _("Object file type: unkown");
break;
}
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text);
/* Champ "e_machine" */
switch (header->hdr32.e_machine)
{
case EM_NONE: text = _("Architecture: No machine"); break;
case EM_M32: text = _("Architecture: AT&T WE 32100"); break;
case EM_SPARC: text = _("Architecture: SUN SPARC"); break;
case EM_386: text = _("Architecture: Intel 80386"); break;
case EM_68K: text = _("Architecture: Motorola m68k family"); break;
case EM_88K: text = _("Architecture: Motorola m88k family"); break;
case EM_860: text = _("Architecture: Intel 80860"); break;
case EM_MIPS: text = _("Architecture: MIPS R3000 big-endian"); break;
case EM_S370: text = _("Architecture: IBM System/370"); break;
case EM_MIPS_RS3_LE:text = _("Architecture: MIPS R3000 little-endian"); break;
case EM_PARISC: text = _("Architecture: HPPA"); break;
case EM_VPP500: text = _("Architecture: Fujitsu VPP500"); break;
case EM_SPARC32PLUS:text = _("Architecture: Sun's \"v8plus\""); break;
case EM_960: text = _("Architecture: Intel 80960"); break;
case EM_PPC: text = _("Architecture: PowerPC"); break;
case EM_PPC64: text = _("Architecture: PowerPC 64-bit"); break;
case EM_S390: text = _("Architecture: IBM S390"); break;
case EM_V800: text = _("Architecture: NEC V800 series"); break;
case EM_FR20: text = _("Architecture: Fujitsu FR20"); break;
case EM_RH32: text = _("Architecture: TRW RH-32"); break;
case EM_RCE: text = _("Architecture: Motorola RCE"); break;
case EM_ARM: text = _("Architecture: ARM"); break;
case EM_FAKE_ALPHA: text = _("Architecture: Digital Alpha"); break;
case EM_SH: text = _("Architecture: Hitachi SH"); break;
case EM_SPARCV9: text = _("Architecture: SPARC v9 64-bit"); break;
case EM_TRICORE: text = _("Architecture: Siemens Tricore"); break;
case EM_ARC: text = _("Architecture: Argonaut RISC Core"); break;
case EM_H8_300: text = _("Architecture: Hitachi H8/300"); break;
case EM_H8_300H: text = _("Architecture: Hitachi H8/300H"); break;
case EM_H8S: text = _("Architecture: Hitachi H8S"); break;
case EM_H8_500: text = _("Architecture: Hitachi H8/500"); break;
case EM_IA_64: text = _("Architecture: Intel Merced"); break;
case EM_MIPS_X: text = _("Architecture: Stanford MIPS-X"); break;
case EM_COLDFIRE: text = _("Architecture: Motorola Coldfire"); break;
case EM_68HC12: text = _("Architecture: Motorola M68HC12"); break;
case EM_MMA: text = _("Architecture: Fujitsu MMA Multimedia Accelerator"); break;
case EM_PCP: text = _("Architecture: Siemens PCP"); break;
case EM_NCPU: text = _("Architecture: Sony nCPU embeeded RISC"); break;
case EM_NDR1: text = _("Architecture: Denso NDR1 microprocessor"); break;
case EM_STARCORE: text = _("Architecture: Motorola Start*Core processor"); break;
case EM_ME16: text = _("Architecture: Toyota ME16 processor"); break;
case EM_ST100: text = _("Architecture: STMicroelectronic ST100 processor"); break;
case EM_TINYJ: text = _("Architecture: Advanced Logic Corp. Tinyj emb.fam"); break;
case EM_X86_64: text = _("Architecture: AMD x86-64 architecture"); break;
case EM_PDSP: text = _("Architecture: Sony DSP Processor"); break;
case EM_FX66: text = _("Architecture: Siemens FX66 microcontroller"); break;
case EM_ST9PLUS: text = _("Architecture: STMicroelectronics ST9+ 8/16 mc"); break;
case EM_ST7: text = _("Architecture: STmicroelectronics ST7 8 bit mc"); break;
case EM_68HC16: text = _("Architecture: Motorola MC68HC16 microcontroller"); break;
case EM_68HC11: text = _("Architecture: Motorola MC68HC11 microcontroller"); break;
case EM_68HC08: text = _("Architecture: Motorola MC68HC08 microcontroller"); break;
case EM_68HC05: text = _("Architecture: Motorola MC68HC05 microcontroller"); break;
case EM_SVX: text = _("Architecture: Silicon Graphics SVx"); break;
case EM_ST19: text = _("Architecture: STMicroelectronics ST19 8 bit mc"); break;
case EM_VAX: text = _("Architecture: Digital VAX"); break;
case EM_CRIS: text = _("Architecture: Axis Communications 32-bit embedded processor"); break;
case EM_JAVELIN: text = _("Architecture: Infineon Technologies 32-bit embedded processor"); break;
case EM_FIREPATH: text = _("Architecture: Element 14 64-bit DSP Processor"); break;
case EM_ZSP: text = _("Architecture: LSI Logic 16-bit DSP Processor"); break;
case EM_MMIX: text = _("Architecture: Donald Knuth's educational 64-bit processor"); break;
case EM_HUANY: text = _("Architecture: Harvard University machine-independent object files"); break;
case EM_PRISM: text = _("Architecture: SiTera Prism"); break;
case EM_AVR: text = _("Architecture: Atmel AVR 8-bit microcontroller"); break;
case EM_FR30: text = _("Architecture: Fujitsu FR30"); break;
case EM_D10V: text = _("Architecture: Mitsubishi D10V"); break;
case EM_D30V: text = _("Architecture: Mitsubishi D30V"); break;
case EM_V850: text = _("Architecture: NEC v850"); break;
case EM_M32R: text = _("Architecture: Mitsubishi M32R"); break;
case EM_MN10300: text = _("Architecture: Matsushita MN10300"); break;
case EM_MN10200: text = _("Architecture: Matsushita MN10200"); break;
case EM_PJ: text = _("Architecture: picoJava"); break;
case EM_OPENRISC: text = _("Architecture: OpenRISC 32-bit embedded processor"); break;
case EM_ARC_A5: text = _("Architecture: ARC Cores Tangent-A5"); break;
case EM_XTENSA: text = _("Architecture: Tensilica Xtensa Architecture"); break;
case EM_AARCH64: text = _("Architecture: ARM AARCH64"); break;
case EM_TILEPRO: text = _("Architecture: Tilera TILEPro"); break;
case EM_MICROBLAZE: text = _("Architecture: Xilinx MicroBlaze"); break;
case EM_TILEGX: text = _("Architecture: Tilera TILE-Gx"); break;
default: text = _("Architecture: unknown"); break;
}
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text);
/* Champ "e_version" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Object file version"));
if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32)
{
/* Champ "e_entry" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Entry point virtual address"));
/* Champ "e_phoff" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Program header table file offset"));
/* Champ "e_shoff" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Section header table file offset"));
}
else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64)
{
/* Champ "e_entry" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Entry point virtual address"));
/* Champ "e_phoff" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Program header table file offset"));
/* Champ "e_shoff" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Section header table file offset"));
}
else return false;
/* Champ "e_flags" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
//SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Processor-specific flags"));
/* Champ "e_ehsize" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("ELF header size in bytes"));
/* Champ "e_phentsize" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Program header table entry size"));
/* Champ "e_phnum" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Program header table entry count"));
/* Champ "e_shentsize" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Section header table entry size"));
/* Champ "e_shnum" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Section header table entry count"));
/* Champ "e_shstrndx" */
copy_vmpa(&start, &pos);
instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Section header string table index"));
g_object_unref(G_OBJECT(content));
return true;
}