diff options
Diffstat (limited to 'plugins/readelf/section.c')
-rw-r--r-- | plugins/readelf/section.c | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c new file mode 100644 index 0000000..3884818 --- /dev/null +++ b/plugins/readelf/section.c @@ -0,0 +1,441 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * header.c - annotation des en-têtes de section 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 <http://www.gnu.org/licenses/>. + */ + + +#include "section.h" + + +#include <i18n.h> +#include <arch/raw.h> +#include <common/extstr.h> +#include <format/symbol.h> +#include <format/elf/elf-int.h> +#include <format/elf/section.h> + + + +/* Charge tous les symboles liés à un en-tête de section ELF. */ +static bool annotate_elf_section_header(GElfFormat *, SourceEndian, const elf_shdr *, vmpa2t *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* endian = boutisme présentement utilisé. * +* strings = section renvoyant vers des chaînes de caractères. * +* pos = tête de lecture à déplacer. [OUT] * +* * +* Description : Charge tous les symboles liés à un en-tête de section ELF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian, const elf_shdr *strings, vmpa2t *pos) +{ + elf_shdr shdr; /* En-tête de programme ELF */ + GBinContent *content; /* Contenu binaire à lire */ + const char *secname; /* Nom d'une section analysée */ + ImmOperandDisplay disp; /* Afficahge de valeur */ + const char *text; /* Texte constant à insérer */ + 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 */ + char *dtext; /* Texte dynamique à créer */ + bool filled; /* Suivi de mise en place */ + + if (!read_elf_section_header(format, get_phy_addr(pos), &shdr)) + return false; + + content = g_binary_format_get_conten_(G_BIN_FORMAT(format)); + + /* Champ "sh_name" */ + + secname = extract_name_from_elf_string_section(format, strings, + ELF_SHDR(format, shdr, sh_name)); + + if (secname == NULL) + dtext = strdup(_("Section name: <invalid>")); + else + { + dtext = strdup(_("Section name: '")); + dtext = stradd(dtext, secname); + dtext = stradd(dtext, "'"); + } + + 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, dtext); + + free(dtext); + + /* Champ "sh_type" */ + + disp = IOD_DEC; + + switch (ELF_SHDR(format, shdr, sh_type)) + { + case SHT_NULL: + text = _("Section type: unused"); + break; + case SHT_PROGBITS: + text = _("Section type: program data"); + break; + case SHT_SYMTAB: + text = _("Section type: symbol table"); + break; + case SHT_STRTAB: + text = _("Section type: string table"); + break; + case SHT_RELA: + text = _("Section type: relocation entries with addends"); + break; + case SHT_HASH: + text = _("Section type: symbol hash table"); + break; + case SHT_DYNAMIC: + text = _("Section type: dynamic linking information"); + break; + case SHT_NOTE: + text = _("Section type: notes"); + break; + case SHT_NOBITS: + text = _("Section type: program space with no data (bss)"); + break; + case SHT_REL: + text = _("Section type: relocation entries, no addends"); + break; + case SHT_SHLIB: + text = _("Section type: reserved"); + break; + case SHT_DYNSYM: + text = _("Section type: dynamic linker symbol table"); + break; + case SHT_INIT_ARRAY: + text = _("Section type: array of constructors"); + break; + case SHT_FINI_ARRAY: + text = _("Section type: array of destructors"); + break; + case SHT_PREINIT_ARRAY: + text = _("Section type: array of pre-constructors"); + break; + case SHT_GROUP: + text = _("Section type: section group"); + break; + case SHT_SYMTAB_SHNDX: + text = _("Section type: extended section indeces"); + break; + case SHT_LOOS ... SHT_HIOS: + disp = IOD_HEX; + switch (ELF_SHDR(format, shdr, sh_type)) + { + case SHT_GNU_ATTRIBUTES: + text = _("Section type: object attributes"); + break; + case SHT_GNU_HASH: + text = _("Section type: GNU-style hash table"); + break; + case SHT_GNU_LIBLIST: + text = _("Section type: prelink library list"); + break; + case SHT_CHECKSUM: + text = _("Section type: checksum for DSO content"); + break; + case SHT_LOSUNW ... SHT_HISUNW: + switch (ELF_SHDR(format, shdr, sh_type)) + { + case SHT_SUNW_move: + text = _("Section type: SHT_SUNW_move"); + break; + case SHT_SUNW_COMDAT: + text = _("Section type: SHT_SUNW_COMDAT"); + break; + case SHT_SUNW_syminfo: + text = _("Section type: SHT_SUNW_syminfo"); + break; + case SHT_GNU_verdef: + text = _("Section type: version definition section"); + break; + case SHT_GNU_verneed: + text = _("Section type: version needs section"); + break; + case SHT_GNU_versym: + text = _("Section type: version symbol table"); + break; + default: + text = _("Section type: Sun-specific"); + break; + } + break; + default: + text = _("Section type: OS-specific"); + break; + } + break; + case SHT_LOPROC ... SHT_HIPROC: + disp = IOD_HEX; + text = _("Section type: processor-specific"); + break; + case SHT_LOUSER ... SHT_HIUSER: + disp = IOD_HEX; + text = _("Section type: application-specific"); + break; + default: + disp = IOD_HEX; + text = _("Section type: unknown"); + break; + } + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, disp); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, text); + + /* Champ "sh_flags"... */ + + dtext = strdup(_("Section flags: ")); + filled = false; + + if (ELF_SHDR(format, shdr, sh_type) & SHF_WRITE) + { + dtext = stradd(dtext, "W"); + filled = true; + } + + if (ELF_SHDR(format, shdr, sh_type) & SHF_ALLOC) + { + dtext = stradd(dtext, "A"); + filled = true; + } + + if (ELF_SHDR(format, shdr, sh_type) & SHF_EXECINSTR) + { + dtext = stradd(dtext, "X"); + filled = true; + } + + if (ELF_SHDR(format, shdr, sh_type) & SHF_MERGE) + { + dtext = stradd(dtext, "M"); + filled = true; + } + + if (ELF_SHDR(format, shdr, sh_type) & SHF_LINK_ORDER) + { + dtext = stradd(dtext, "L"); + filled = true; + } + + if (ELF_SHDR(format, shdr, sh_type) & SHF_TLS) + { + dtext = stradd(dtext, "T"); + filled = true; + } + + if (!filled) + dtext = stradd(dtext, _("none")); + + if (format->is_32b) + { + /* Champ "sh_flags" (suite) */ + + 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, dtext); + + free(dtext); + + /* Champ "sh_addr" */ + + 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 virtual addr at execution")); + + /* Champ "sh_offset" */ + + 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 file offset")); + + /* Champ "sh_size" */ + + 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, _("Section size in bytes")); + + } + else + { + /* Champ "sh_flags" (suite) */ + + 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, dtext); + + free(dtext); + + /* Champ "sh_addr" */ + + 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 virtual addr at execution")); + + /* Champ "sh_offset" */ + + 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 file offset")); + + /* Champ "sh_size" */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Section size in bytes")); + + } + + /* Champ "sh_link" */ + + 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, _("Link to another section")); + + /* Champ "sh_info" */ + + 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, _("Additional section information")); + + if (format->is_32b) + { + /* Champ "sh_addralign" */ + + 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 alignment")); + + /* Champ "sh_entsize" */ + + 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, _("Entry size if section holds table")); + + } + else + { + /* Champ "sh_addralign" */ + + 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 alignment")); + + /* Champ "sh_entsize" */ + + copy_vmpa(&start, pos); + instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + + SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + + ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("Entry size if section holds table")); + + } + + g_object_unref(G_OBJECT(content)); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Charge tous les symboles liés aux en-têtes de section ELF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool annotate_elf_section_header_table(GElfFormat *format) +{ + bool result; /* Bilan à retourner */ + const elf_header *header; /* En-tête principale */ + SourceEndian endian; /* Boutisme utilisé */ + elf_shdr strings; /* Section des descriptions */ + off_t offset; /* Tête de lecture du binaire */ + vmpa2t pos; /* Localisation des symboles */ + uint16_t e_shnum; /* Nombre d'éléments 'Program' */ + uint16_t i; /* Boucle de parcours */ + + result = true; + + header = g_elf_format_get_header(format); + endian = g_elf_format_get_endianness(format); + + if (!find_elf_section_by_index(format, ELF_HDR(format, *header, e_shstrndx), &strings)) + return false; + + offset = ELF_HDR(format, *header, e_shoff); + + init_vmpa(&pos, offset, 0x9900); + + e_shnum = ELF_HDR(format, *header, e_shnum); + + for (i = 0; i < e_shnum && result; i++) + result = annotate_elf_section_header(format, endian, &strings, &pos); + + return true; + +} |