diff options
-rw-r--r-- | ChangeLog | 24 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | plugins/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/fmtp/Makefile.am | 13 | ||||
-rw-r--r-- | plugins/fmtp/def.h | 149 | ||||
-rw-r--r-- | plugins/fmtp/parser.c | 223 | ||||
-rw-r--r-- | plugins/fmtp/parser.h | 43 | ||||
-rw-r--r-- | plugins/readelf/Makefile.am | 3 | ||||
-rw-r--r-- | plugins/readelf/header.c | 670 | ||||
-rw-r--r-- | plugins/readelf/header.h | 2 | ||||
-rw-r--r-- | plugins/readelf/program.c | 405 | ||||
-rw-r--r-- | plugins/readelf/reader.c | 2 | ||||
-rw-r--r-- | plugins/readelf/section.c | 530 |
13 files changed, 1300 insertions, 767 deletions
@@ -1,3 +1,27 @@ +17-04-27 Cyrille Bagard <nocbos@gmail.com> + + * configure.ac: + Add the new Makefile from the 'plugins/fmtp' directory. + + * plugins/Makefile.am: + Add 'fmtp' to SUBDIRS. + + * plugins/fmtp/Makefile.am: + * plugins/fmtp/def.h: + * plugins/fmtp/parser.c: + * plugins/fmtp/parser.h: + New entries: provide a generic parser for format fields. + + * plugins/readelf/Makefile.am: + Update LDFLAGS and AM_CPPFLAGS. + + * plugins/readelf/header.c: + * plugins/readelf/header.h: + * plugins/readelf/program.c: + * plugins/readelf/reader.c: + * plugins/readelf/section.c: + Parse ELF format fields using a new generic parser to save memory. + 17-04-22 Cyrille Bagard <nocbos@gmail.com> * src/analysis/disass/links.c: diff --git a/configure.ac b/configure.ac index 60cf9c5..ccace74 100644 --- a/configure.ac +++ b/configure.ac @@ -315,6 +315,7 @@ AC_CONFIG_FILES([Makefile pixmaps/Makefile plugins/Makefile plugins/devdbg/Makefile + plugins/fmtp/Makefile plugins/libcsem/Makefile plugins/mobicore/Makefile plugins/pychrysa/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d0b8fc8..0cbe6fa 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -4,4 +4,4 @@ if HAVE_PYTHON3_CONFIG endif # androhelpers -SUBDIRS = devdbg libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets +SUBDIRS = devdbg fmtp libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf ropgadgets diff --git a/plugins/fmtp/Makefile.am b/plugins/fmtp/Makefile.am new file mode 100644 index 0000000..1c5d0d9 --- /dev/null +++ b/plugins/fmtp/Makefile.am @@ -0,0 +1,13 @@ + +lib_LTLIBRARIES = libfmtp.la + +libfmtp_la_SOURCES = \ + def.h \ + parser.h parser.c + +libfmtp_la_CFLAGS = $(AM_CFLAGS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/fmtp/def.h b/plugins/fmtp/def.h new file mode 100644 index 0000000..d69d20a --- /dev/null +++ b/plugins/fmtp/def.h @@ -0,0 +1,149 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * def.h - prototypes pour la définition des unités de lecture + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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/>. + */ + + +#ifndef _PLUGINS_FMTP_DEF_H +#define _PLUGINS_FMTP_DEF_H + + +#include <stdbool.h> + + +#include <arch/archbase.h> +#include <common/cpp.h> + + + +/** + * Assurément utile pour les déclarations... + */ + +#define __(s) s + + +/** + * Méthodes de définitions des déclarations. + */ + +/* Possibilités pour un champ à commenter */ +typedef struct _field_desc_switch +{ + bool is_range; /* Sélection de définition */ + + union + { + uint64_t fixed; /* Valeur fixe */ + + struct + { + uint64_t lower; /* Borne basse */ + uint64_t upper; /* Borne haute */ + }; + + }; + + const char *desc; /* Description associée */ + +} field_desc_switch; + +/* Partie de commentaire */ +typedef struct _comment_part +{ + bool is_static; /* Choix du champ textuel */ + bool avoid_i18n; /* Pas de traduction ! */ + + union + { + const char *static_text; /* Texte alloué statiquement */ + char *dynamic_text; /* Texte alloué dynamiquement */ + }; + +} comment_part; + +/* Type de commentaires associés */ +typedef enum _FieldCommentType +{ + FCT_PLAIN, /* Brut et statique */ + FCT_SWITCH, /* Eventail des possibles */ + FCT_MULTI /* En plusieurs parties */ + +} FieldCommentType; + +/* Définition générale */ +typedef struct _fmt_field_def +{ + const char *name; /* Nom du champ */ + + MemoryDataSize size; /* Taille d'un élément */ + size_t repeat; /* Quantité d'éléments présents*/ + + bool is_padding; /* Simple bourrage ? */ + + bool has_display_rules; /* Validité des champs suivants*/ + const ImmOperandDisplay *disp_rules; /* Règles d'affichage */ + size_t disp_count; /* Quantité de ces règles */ + + FieldCommentType ctype; /* Type de commentaire */ + union + { + const char *plain; /* Commentaire simple */ + + struct + { + const field_desc_switch *choices; /* Choix multiples */ + size_t ccount; /* Quantité de ces choix */ + const char *def_choice; /* Commentaire par défaut */ + }; + + struct + { + comment_part *parts; /* Parties à considérer */ + size_t pcount; /* Quantité de ces parties */ + }; + + } comment; + +} fmt_field_def; + + +/* Règles d'affichage */ + +#define DISPLAY_RULES(...) \ + .has_display_rules = true, \ + .disp_rules = (ImmOperandDisplay []) { __VA_ARGS__ }, \ + .disp_count = ARRAY_SIZE(((ImmOperandDisplay []) { __VA_ARGS__ })) + +/* Rédaction des commentaires */ + +#define PLAIN_COMMENT(txt) \ + .ctype = FCT_PLAIN, \ + .comment.plain = txt + +#define SWITCH_COMMENT(array, def) \ + .ctype = FCT_SWITCH, \ + .comment.choices = array, \ + .comment.ccount = ARRAY_SIZE(array), \ + .comment.def_choice = def + + + +#endif /* _PLUGINS_FMTP_DEF_H */ diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c new file mode 100644 index 0000000..2f469c1 --- /dev/null +++ b/plugins/fmtp/parser.c @@ -0,0 +1,223 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.c - interprétation des champs d'un format binaire + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 "parser.h" + + +#include <assert.h> + + +#include <i18n.h> +#include <arch/raw.h> + + + +/* Effectue l'interprétation d'une définition de champ. */ +static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *); + + + + +/****************************************************************************** +* * +* Paramètres : def = définition de champ à considérer. * +* format = description de l'exécutable à compléter. * +* pos = tête de lecture pour les données. * +* * +* Description : Effectue l'interprétation d'une définition de champ. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos) +{ + GBinContent *content; /* Contenu binaire à lire */ + SourceEndian endian; /* Boutisme utilisé */ + bool result; /* Bilan à retourner */ + GArchInstruction *instr; /* Instruction décodée */ + GImmOperand *imm; /* Opérande à transformer */ + size_t i; /* Boucle de parcours */ + const vmpa2t *addr; /* Emplacement d'instruction */ + GDbComment *comment; /* Définition de commentaire */ + uint64_t raw; /* Valeur brute à étudier */ + const comment_part *part; /* Accès plus direct */ + + + GBinSymbol *symbol; /* Symbole à intégrer */ + + + /* Lecture */ + + content = g_binary_format_get_content(format); + endian = g_binary_format_get_endianness(format); + + assert(def->repeat > 0); + + instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian); + + result = (instr != NULL); + + if (!result) + goto pfd_exit; + + if (def->is_padding) + g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + + if (def->has_display_rules) + { + assert(def->disp_count <= def->repeat); + + for (i = 0; i < def->disp_count; i++) + { + imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, i)); + + g_imm_operand_set_default_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr)); + g_imm_operand_set_display(&imm, def->disp_rules[i], G_SHARE_CONTAINER(instr)); + + // TODO : unref(imm) + + } + + } + + /* Commentaire */ + + addr = get_mrange_addr(g_arch_instruction_get_range(instr)); + + comment = g_db_comment_new_inlined(addr, BLF_HAS_CODE, false); + g_db_item_set_volatile(G_DB_ITEM(comment), true); + + switch (def->ctype) + { + case FCT_PLAIN: + g_db_comment_add_static_text(comment, _(def->comment.plain)); + break; + + case FCT_SWITCH: + + imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, 0)); + raw = g_imm_operand_get_raw_value(imm); + // TODO : unref(imm) + + for (i = 0; i < def->comment.ccount; i++) + { + if (def->comment.choices[i].is_range) + { + if (raw < def->comment.choices[i].lower) + continue; + if (raw > def->comment.choices[i].upper) + continue; + } + + else if (raw != def->comment.choices[i].fixed) + continue; + + g_db_comment_add_static_text(comment, _(def->comment.choices[i].desc)); + break; + + } + + if (i == def->comment.ccount) + g_db_comment_add_static_text(comment, _(def->comment.def_choice)); + + break; + + case FCT_MULTI: + + for (i = 0; i < def->comment.pcount; i++) + { + part = &def->comment.parts[i]; + + if (part->is_static) + { + if (part->avoid_i18n) + g_db_comment_add_static_text(comment, part->static_text); + else + g_db_comment_add_static_text(comment, _(part->static_text)); + } + else + { + if (part->avoid_i18n) + g_db_comment_add_dynamic_text(comment, part->dynamic_text); + else + g_db_comment_add_dynamic_text(comment, _(part->dynamic_text)); + } + + } + + break; + + } + + /* Insertion */ + + symbol = g_binary_symbol_new(STP_DATA); + + g_binary_symbol_attach_instruction(symbol, instr); + g_binary_symbol_set_comment(symbol, comment); + + result = g_binary_format_add_symbol(format, symbol); + + if (!result) + g_object_unref(G_OBJECT(instr)); + + pfd_exit: + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : defs = liste de définitions à traiter. * +* count = taille de cette liste. * +* format = description de l'exécutable à compléter. * +* pos = tête de lecture pour les données. * +* * +* Description : Lance l'interprétation d'une série de définitions de champs. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < count && result; i++) + result = parse_field_definition(defs + i, format, pos); + + return result; + +} diff --git a/plugins/fmtp/parser.h b/plugins/fmtp/parser.h new file mode 100644 index 0000000..dcd9bf2 --- /dev/null +++ b/plugins/fmtp/parser.h @@ -0,0 +1,43 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.h - prototypes pour l'interprétation des champs d'un format binaire + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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/>. + */ + + +#ifndef _PLUGINS_FMTP_PARSER_H +#define _PLUGINS_FMTP_PARSER_H + + +#include <stdbool.h> + + +#include <format/format.h> + + +#include "def.h" + + + +/* Lance l'interprétation d'une série de définitions de champs. */ +bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *); + + + +#endif /* _PLUGINS_FMTP_PARSER_H */ diff --git a/plugins/readelf/Makefile.am b/plugins/readelf/Makefile.am index 13f45f8..c3cf822 100644 --- a/plugins/readelf/Makefile.am +++ b/plugins/readelf/Makefile.am @@ -10,7 +10,8 @@ libreadelf_la_SOURCES = \ libreadelf_la_CFLAGS = $(AM_CFLAGS) +libreadelf_la_LDFLAGS = -L../../plugins/fmtp/.libs -lfmtp -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src -I../.. AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c index d0aee92..21884a3 100644 --- a/plugins/readelf/header.c +++ b/plugins/readelf/header.c @@ -24,435 +24,473 @@ #include "header.h" -#include <i18n.h> -#include <arch/raw.h> -#include <format/symbol.h> +#include <common/cpp.h> +#include <plugins/fmtp/parser.h> + + + +/* Définition des champs */ + +static field_desc_switch _elf_classes[] = { + + { .fixed = EV_NONE, .desc = __("File class: invalid") }, + { .fixed = ELFCLASS32, .desc = __("File class: 32-bit objects") }, + { .fixed = ELFCLASS64, .desc = __("File class: 64-bit objects") } + +}; + +static field_desc_switch _elf_data[] = { + + { .fixed = ELFDATANONE, .desc = __("Data encoding: invalid") }, + { .fixed = ELFDATA2LSB, .desc = __("Data encoding: 2's complement, little endian") }, + { .fixed = ELFDATA2MSB, .desc = __("Data encoding: 2's complement, big endian") } + +}; + +static field_desc_switch _elf_versions[] = { + + { .fixed = EV_NONE, .desc = __("File version: invalid") }, + { .fixed = EV_CURRENT, .desc = __("File version: current") } + +}; + +static field_desc_switch _elf_os_abis[] = { + + { .fixed = ELFOSABI_SYSV, .desc = __("OS ABI: UNIX System V ABI") }, + { .fixed = ELFOSABI_HPUX, .desc = __("OS ABI: HP-UX") }, + { .fixed = ELFOSABI_NETBSD, .desc = __("OS ABI: NetBSD") }, + { .fixed = ELFOSABI_GNU, .desc = __("OS ABI: Object uses GNU ELF extensions") }, + { .fixed = ELFOSABI_SOLARIS, .desc = __("OS ABI: Sun Solaris") }, + { .fixed = ELFOSABI_AIX, .desc = __("OS ABI: IBM AIX") }, + { .fixed = ELFOSABI_IRIX, .desc = __("OS ABI: SGI Irix") }, + { .fixed = ELFOSABI_FREEBSD, .desc = __("OS ABI: FreeBSD") }, + { .fixed = ELFOSABI_TRU64, .desc = __("OS ABI: Compaq TRU64 UNIX") }, + { .fixed = ELFOSABI_MODESTO, .desc = __("OS ABI: Novell Modesto") }, + { .fixed = ELFOSABI_OPENBSD, .desc = __("OS ABI: OpenBSD") }, + { .fixed = ELFOSABI_ARM_AEABI, .desc = __("OS ABI: ARM EABI") }, + { .fixed = ELFOSABI_ARM, .desc = __("OS ABI: ARM") }, + { .fixed = ELFOSABI_STANDALONE, .desc = __("OS ABI: Standalone (embedded) application") } + +}; + +static field_desc_switch _elf_types[] = { + + { .fixed = ET_NONE, .desc = __("Object file type: no file type") }, + { .fixed = ET_REL, .desc = __("Object file type: relocatable file") }, + { .fixed = ET_EXEC, .desc = __("Object file type: executable file") }, + { .fixed = ET_DYN, .desc = __("Object file type: shared object file") }, + { .fixed = ET_CORE, .desc = __("Object file type: core file") }, + { .lower = ET_LOOS, .upper = ET_HIOS, .desc = __("Object file type: OS-specific") }, + { .lower = ET_LOPROC, .upper = ET_HIPROC, .desc = __("Object file type: processor-specific") } + +}; + +static field_desc_switch _elf_machines[] = { + + { .fixed = EM_NONE, .desc = __("Architecture: No machine") }, + { .fixed = EM_M32, .desc = __("Architecture: AT&T WE 32100") }, + { .fixed = EM_SPARC, .desc = __("Architecture: SUN SPARC") }, + { .fixed = EM_386, .desc = __("Architecture: Intel 80386") }, + { .fixed = EM_68K, .desc = __("Architecture: Motorola m68k family") }, + { .fixed = EM_88K, .desc = __("Architecture: Motorola m88k family") }, + { .fixed = EM_860, .desc = __("Architecture: Intel 80860") }, + { .fixed = EM_MIPS, .desc = __("Architecture: MIPS R3000 big-endian") }, + { .fixed = EM_S370, .desc = __("Architecture: IBM System/370") }, + { .fixed = EM_MIPS_RS3_LE, .desc = __("Architecture: MIPS R3000 little-endian") }, + { .fixed = EM_PARISC, .desc = __("Architecture: HPPA") }, + { .fixed = EM_VPP500, .desc = __("Architecture: Fujitsu VPP500") }, + { .fixed = EM_SPARC32PLUS, .desc = __("Architecture: Sun's \"v8plus\"") }, + { .fixed = EM_960, .desc = __("Architecture: Intel 80960") }, + { .fixed = EM_PPC, .desc = __("Architecture: PowerPC") }, + { .fixed = EM_PPC64, .desc = __("Architecture: PowerPC 64-bit") }, + { .fixed = EM_S390, .desc = __("Architecture: IBM S390") }, + { .fixed = EM_V800, .desc = __("Architecture: NEC V800 series") }, + { .fixed = EM_FR20, .desc = __("Architecture: Fujitsu FR20") }, + { .fixed = EM_RH32, .desc = __("Architecture: TRW RH-32") }, + { .fixed = EM_RCE, .desc = __("Architecture: Motorola RCE") }, + { .fixed = EM_ARM, .desc = __("Architecture: ARM") }, + { .fixed = EM_FAKE_ALPHA, .desc = __("Architecture: Digital Alpha") }, + { .fixed = EM_SH, .desc = __("Architecture: Hitachi SH") }, + { .fixed = EM_SPARCV9, .desc = __("Architecture: SPARC v9 64-bit") }, + { .fixed = EM_TRICORE, .desc = __("Architecture: Siemens Tricore") }, + { .fixed = EM_ARC, .desc = __("Architecture: Argonaut RISC Core") }, + { .fixed = EM_H8_300, .desc = __("Architecture: Hitachi H8/300") }, + { .fixed = EM_H8_300H, .desc = __("Architecture: Hitachi H8/300H") }, + { .fixed = EM_H8S, .desc = __("Architecture: Hitachi H8S") }, + { .fixed = EM_H8_500, .desc = __("Architecture: Hitachi H8/500") }, + { .fixed = EM_IA_64, .desc = __("Architecture: Intel Merced") }, + { .fixed = EM_MIPS_X, .desc = __("Architecture: Stanford MIPS-X") }, + { .fixed = EM_COLDFIRE, .desc = __("Architecture: Motorola Coldfire") }, + { .fixed = EM_68HC12, .desc = __("Architecture: Motorola M68HC12") }, + { .fixed = EM_MMA, .desc = __("Architecture: Fujitsu MMA Multimedia Accelerator") }, + { .fixed = EM_PCP, .desc = __("Architecture: Siemens PCP") }, + { .fixed = EM_NCPU, .desc = __("Architecture: Sony nCPU embeeded RISC") }, + { .fixed = EM_NDR1, .desc = __("Architecture: Denso NDR1 microprocessor") }, + { .fixed = EM_STARCORE, .desc = __("Architecture: Motorola Start*Core processor") }, + { .fixed = EM_ME16, .desc = __("Architecture: Toyota ME16 processor") }, + { .fixed = EM_ST100, .desc = __("Architecture: STMicroelectronic ST100 processor") }, + { .fixed = EM_TINYJ, .desc = __("Architecture: Advanced Logic Corp. Tinyj emb.fam") }, + { .fixed = EM_X86_64, .desc = __("Architecture: AMD x86-64 architecture") }, + { .fixed = EM_PDSP, .desc = __("Architecture: Sony DSP Processor") }, + { .fixed = EM_FX66, .desc = __("Architecture: Siemens FX66 microcontroller") }, + { .fixed = EM_ST9PLUS, .desc = __("Architecture: STMicroelectronics ST9+ 8/16 mc") }, + { .fixed = EM_ST7, .desc = __("Architecture: STmicroelectronics ST7 8 bit mc") }, + { .fixed = EM_68HC16, .desc = __("Architecture: Motorola MC68HC16 microcontroller") }, + { .fixed = EM_68HC11, .desc = __("Architecture: Motorola MC68HC11 microcontroller") }, + { .fixed = EM_68HC08, .desc = __("Architecture: Motorola MC68HC08 microcontroller") }, + { .fixed = EM_68HC05, .desc = __("Architecture: Motorola MC68HC05 microcontroller") }, + { .fixed = EM_SVX, .desc = __("Architecture: Silicon Graphics SVx") }, + { .fixed = EM_ST19, .desc = __("Architecture: STMicroelectronics ST19 8 bit mc") }, + { .fixed = EM_VAX, .desc = __("Architecture: Digital VAX") }, + { .fixed = EM_CRIS, .desc = __("Architecture: Axis Communications 32-bit embedded processor") }, + { .fixed = EM_JAVELIN, .desc = __("Architecture: Infineon Technologies 32-bit embedded processor") }, + { .fixed = EM_FIREPATH, .desc = __("Architecture: Element 14 64-bit DSP Processor") }, + { .fixed = EM_ZSP, .desc = __("Architecture: LSI Logic 16-bit DSP Processor") }, + { .fixed = EM_MMIX, .desc = __("Architecture: Donald Knuth's educational 64-bit processor") }, + { .fixed = EM_HUANY, .desc = __("Architecture: Harvard University machine-independent object files") }, + { .fixed = EM_PRISM, .desc = __("Architecture: SiTera Prism") }, + { .fixed = EM_AVR, .desc = __("Architecture: Atmel AVR 8-bit microcontroller") }, + { .fixed = EM_FR30, .desc = __("Architecture: Fujitsu FR30") }, + { .fixed = EM_D10V, .desc = __("Architecture: Mitsubishi D10V") }, + { .fixed = EM_D30V, .desc = __("Architecture: Mitsubishi D30V") }, + { .fixed = EM_V850, .desc = __("Architecture: NEC v850") }, + { .fixed = EM_M32R, .desc = __("Architecture: Mitsubishi M32R") }, + { .fixed = EM_MN10300, .desc = __("Architecture: Matsushita MN10300") }, + { .fixed = EM_MN10200, .desc = __("Architecture: Matsushita MN10200") }, + { .fixed = EM_PJ, .desc = __("Architecture: picoJava") }, + { .fixed = EM_OPENRISC, .desc = __("Architecture: OpenRISC 32-bit embedded processor") }, + { .fixed = EM_ARC_A5, .desc = __("Architecture: ARC Cores Tangent-A5") }, + { .fixed = EM_XTENSA, .desc = __("Architecture: Tensilica Xtensa Architecture") }, + { .fixed = EM_AARCH64, .desc = __("Architecture: ARM AARCH64") }, + { .fixed = EM_TILEPRO, .desc = __("Architecture: Tilera TILEPro") }, + { .fixed = EM_MICROBLAZE, .desc = __("Architecture: Xilinx MicroBlaze") }, + { .fixed = EM_TILEGX, .desc = __("Architecture: Tilera TILE-Gx") } + +}; + +static fmt_field_def _elf_header_base[] = { + { + .name = "e_ident[EI_MAG]", + .size = MDS_8_BITS, + .repeat = 4, -/****************************************************************************** -* * -* 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 : - * -* * -******************************************************************************/ + DISPLAY_RULES(IOD_HEX, IOD_CHAR, IOD_CHAR, IOD_CHAR), -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*/ - 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 */ + PLAIN_COMMENT(__("ELF magic number")) - content = g_binary_format_get_content(G_BIN_FORMAT(format)); + }, - header = g_elf_format_get_header(format); - endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); + { + .name = "e_ident[EI_CLASS]", + + .size = MDS_8_BITS, + .repeat = 1, + + DISPLAY_RULES(IOD_DEC), - if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos)) - return false; + SWITCH_COMMENT(_elf_classes, __("File class: unknown")) - /* ELFMAG (0) */ + }, + + { + .name = "e_ident[EI_DATA]", - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, &pos, endian); + .size = MDS_8_BITS, + .repeat = 1, - SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR); - SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); - SET_IMM_DISPLAY(instr, operand, 3, IOD_CHAR); + DISPLAY_RULES(IOD_DEC), - ADD_RAW_AS_SYM_CST(format, symbol, instr, comment, _("ELF magic number")); + SWITCH_COMMENT(_elf_data, __("Data encoding: unknown")) - /* 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; - } + .name = "e_ident[EI_VERSION]", - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); + .size = MDS_8_BITS, + .repeat = 1, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + DISPLAY_RULES(IOD_DEC), - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + SWITCH_COMMENT(_elf_versions, __("File version: unknown")) - /* 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; - } + .name = "e_ident[EI_OSABI]", - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); + .size = MDS_8_BITS, + .repeat = 1, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + DISPLAY_RULES(IOD_DEC), - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + SWITCH_COMMENT(_elf_os_abis, __("OS ABI: unknown")) - /* 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; - } + .name = "e_ident[EI_ABIVERSION]", - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); + .size = MDS_8_BITS, + .repeat = 1, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + DISPLAY_RULES(IOD_DEC), - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + PLAIN_COMMENT(__("ABI version")) - /* 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; - } + .name = "...", + + .size = MDS_8_BITS, + .repeat = 7, - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); + .is_padding = true, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + PLAIN_COMMENT(__("Padding")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + }, - /* EI_ABIVERSION (8) */ + { + .name = "e_type", + + .size = MDS_16_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endian); + DISPLAY_RULES(IOD_DEC), - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + SWITCH_COMMENT(_elf_types, __("Object file type: unkown")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("ABI version")); + }, - /* Padding */ + { + .name = "e_machine", - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 7, &pos, endian); + .size = MDS_16_BITS, + .repeat = 1, - g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + DISPLAY_RULES(IOD_DEC), - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Padding")); + SWITCH_COMMENT(_elf_machines, __("Architecture: unknown")) - /* 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; + .name = "e_version", + + .size = MDS_32_BITS, + .repeat = 1, + + DISPLAY_RULES(IOD_DEC), + + PLAIN_COMMENT(__("Object file version")) + } - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); +}; + +static fmt_field_def _elf_header_offset_32[] = { + + { + .name = "e_entry", - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + .size = MDS_32_BITS, + .repeat = 1, - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + PLAIN_COMMENT(__("Entry point virtual address")) - /* 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; - } + .name = "e_phoff", + + .size = MDS_32_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + PLAIN_COMMENT(__("Program header table file offset")) - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + }, - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + { + .name = "e_shoff", - /* Champ "e_version" */ + .size = MDS_32_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + PLAIN_COMMENT(__("Section header table file offset")) - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + } - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Object file version")); +}; + +static fmt_field_def _elf_header_offset_64[] = { - if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32) { - /* Champ "e_entry" */ + .name = "e_entry", + + .size = MDS_64_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + PLAIN_COMMENT(__("Entry point virtual address")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry point virtual address")); + }, - /* Champ "e_phoff" */ + { + .name = "e_phoff", - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + .size = MDS_64_BITS, + .repeat = 1, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table file offset")); + PLAIN_COMMENT(__("Program header table file offset")) - /* Champ "e_shoff" */ + }, + + { + .name = "e_shoff", - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + .size = MDS_64_BITS, + .repeat = 1, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table file offset")); + PLAIN_COMMENT(__("Section header table file offset")) } - else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64) +}; + +static fmt_field_def _elf_header_ending[] = { + { - /* Champ "e_entry" */ + .name = "e_flags", - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian); + .size = MDS_32_BITS, + .repeat = 1, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry point virtual address")); + PLAIN_COMMENT(__("Processor-specific flags")) - /* Champ "e_phoff" */ + }, - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian); + { + .name = "e_ehsize", - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table file offset")); + .size = MDS_16_BITS, + .repeat = 1, - /* Champ "e_shoff" */ + DISPLAY_RULES(IOD_DEC), - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, &pos, endian); + PLAIN_COMMENT(__("ELF header size in bytes")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table file offset")); + }, - } + { + .name = "e_phentsize", - else return false; + .size = MDS_16_BITS, + .repeat = 1, - /* Champ "e_flags" */ + DISPLAY_RULES(IOD_DEC), - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); + PLAIN_COMMENT(__("Program header table entry size")) + + }, + + { + .name = "e_phnum", + + .size = MDS_16_BITS, + .repeat = 1, + + DISPLAY_RULES(IOD_DEC), + + PLAIN_COMMENT(__("Program header table entry count")) + + }, + + { + .name = "e_shentsize", - //SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + .size = MDS_16_BITS, + .repeat = 1, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Processor-specific flags")); + DISPLAY_RULES(IOD_DEC), - /* Champ "e_ehsize" */ + PLAIN_COMMENT(__("Section header table entry size")) - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + }, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + { + .name = "e_shnum", - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("ELF header size in bytes")); + .size = MDS_16_BITS, + .repeat = 1, - /* Champ "e_phentsize" */ + DISPLAY_RULES(IOD_DEC), - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + PLAIN_COMMENT(__("Section header table entry count")) - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + }, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table entry size")); + { + .name = "e_shstrndx", - /* Champ "e_phnum" */ + .size = MDS_16_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + DISPLAY_RULES(IOD_DEC), - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + PLAIN_COMMENT(__("Section header string table index")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Program header table entry count")); + } - /* Champ "e_shentsize" */ +}; - 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, instr, comment, _("Section header table entry size")); +/****************************************************************************** +* * +* 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 : - * +* * +******************************************************************************/ - /* Champ "e_shnum" */ +bool annotate_elf_header(GBinFormat *format) +{ + bool result; /* Bilan à retourner */ + const elf_header *header; /* En-tête principale */ + vmpa2t pos; /* Tête de lecture des symboles*/ - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + header = g_elf_format_get_header(G_ELF_FORMAT(format)); - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header table entry count")); + if (result) + result = parse_field_definitions(_elf_header_base, ARRAY_SIZE(_elf_header_base), format, &pos); - /* Champ "e_shstrndx" */ + if (result) + { + if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32) + result = parse_field_definitions(_elf_header_offset_32, ARRAY_SIZE(_elf_header_offset_32), + format, &pos); - instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian); + else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64) + result = parse_field_definitions(_elf_header_offset_64, ARRAY_SIZE(_elf_header_offset_64), + format, &pos); - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + else + result = false; - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section header string table index")); + } - g_object_unref(G_OBJECT(content)); + if (result) + result = parse_field_definitions(_elf_header_ending, ARRAY_SIZE(_elf_header_ending), format, &pos); - return true; + return result; } diff --git a/plugins/readelf/header.h b/plugins/readelf/header.h index 87724e3..9d1744e 100644 --- a/plugins/readelf/header.h +++ b/plugins/readelf/header.h @@ -30,7 +30,7 @@ /* Charge tous les symboles de l'en-tête ELF. */ -bool annotate_elf_header(GElfFormat *); +bool annotate_elf_header(GBinFormat *); diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c index 6bf117c..ba47639 100644 --- a/plugins/readelf/program.c +++ b/plugins/readelf/program.c @@ -24,284 +24,297 @@ #include "program.h" +#include <string.h> + + #include <i18n.h> -#include <arch/raw.h> +#include <common/cpp.h> #include <common/extstr.h> -#include <format/symbol.h> #include <format/elf/elf-int.h> +#include <plugins/fmtp/parser.h> -/* Charge tous les symboles liés à un en-tête de programme ELF. */ -static bool annotate_elf_program_header(GElfFormat *, SourceEndian, vmpa2t *); +/* Définition des champs */ +static field_desc_switch _elf_prgm_types[] = { + { .fixed = PT_NULL, .desc = __("Segment type: unused") }, + { .fixed = PT_LOAD, .desc = __("Segment type: loadable program segment") }, + { .fixed = PT_DYNAMIC, .desc = __("Segment type: dynamic linking information") }, + { .fixed = PT_INTERP, .desc = __("Segment type: program interpreter") }, + { .fixed = PT_NOTE, .desc = __("Segment type: auxiliary information") }, + { .fixed = PT_SHLIB, .desc = __("Segment type: reserved") }, + { .fixed = PT_PHDR, .desc = __("Segment type: entry for header table itself") }, + { .fixed = PT_TLS, .desc = __("Segment type: thread-local storage segment") }, + { .fixed = PT_GNU_EH_FRAME, .desc = __("Segment type: GCC .eh_frame_hdr segment") }, + { .fixed = PT_GNU_STACK, .desc = __("Segment type: indicates stack executability") }, + { .fixed = PT_GNU_RELRO, .desc = __("Segment type: read-only after relocation") }, + { .fixed = PT_SUNWSTACK, .desc = __("Segment type: Sun Stack segment") }, + { .lower = PT_LOSUNW, .upper = PT_HISUNW, .desc = __("Segment type: Sun specific segment") }, + { .lower = PT_LOOS, .upper = PT_HIOS, .desc = __("Segment type: OS-specific") }, + { .lower = PT_LOPROC, .upper = PT_HIPROC, .desc = __("Segment type: processor-specific") } -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* endian = boutisme présentement utilisé. * -* pos = tête de lecture à déplacer. [OUT] * -* * -* Description : Charge tous les symboles liés à un en-tête de programme ELF. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ +}; -static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian, vmpa2t *pos) -{ - elf_phdr phdr; /* En-tête de programme ELF */ - GBinContent *content; /* Contenu binaire à lire */ - ImmOperandDisplay disp; /* Afficahge de valeur */ - const char *text; /* Texte constant à insérer */ - 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_program_header(format, get_phy_addr(pos), &phdr)) - return false; +static fmt_field_def _elf_phdr_base[] = { - content = g_binary_format_get_content(G_BIN_FORMAT(format)); + { + .name = "p_type", - /* Champ "p_type" */ + .size = MDS_32_BITS, + .repeat = 1, - disp = IOD_DEC; + SWITCH_COMMENT(_elf_prgm_types, __("Segment type: unknown")) - switch (ELF_PHDR(format, phdr, p_type)) - { - case PT_NULL: - text = _("Segment type: unused"); - break; - case PT_LOAD: - text = _("Segment type: loadable program segment"); - break; - case PT_DYNAMIC: - text = _("Segment type: dynamic linking information"); - break; - case PT_INTERP: - text = _("Segment type: program interpreter"); - break; - case PT_NOTE: - text = _("Segment type: auxiliary information"); - break; - case PT_SHLIB: - text = _("Segment type: reserved"); - break; - case PT_PHDR: - text = _("Segment type: entry for header table itself"); - break; - case PT_TLS: - text = _("Segment type: thread-local storage segment"); - break; - case PT_LOOS ... PT_HIOS: - disp = IOD_HEX; - switch (ELF_PHDR(format, phdr, p_type)) - { - case PT_GNU_EH_FRAME: - text = _("Segment type: GCC .eh_frame_hdr segment"); - break; - case PT_GNU_STACK: - text = _("Segment type: indicates stack executability"); - break; - case PT_GNU_RELRO: - text = _("Segment type: read-only after relocation"); - break; - case PT_LOSUNW ... PT_HISUNW: - switch (ELF_PHDR(format, phdr, p_type)) - { - case PT_SUNWSTACK: - text = _("Segment type: Sun Stack segment"); - break; - default: - text = _("Segment type: Sun specific segment"); - break; - } - break; - default: - text = _("Segment type: OS-specific"); - break; - } - break; - case PT_LOPROC ... PT_HIPROC: - disp = IOD_HEX; - text = _("Segment type: processor-specific"); - break; - default: - disp = IOD_HEX; - text = _("Segment type: unknown"); - break; } - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +}; + +static fmt_field_def _elf_phdr_32b_a[] = { - SET_IMM_DISPLAY(instr, operand, 0, disp); + { + .name = "p_offset", - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + .size = MDS_32_BITS, + .repeat = 1, + + PLAIN_COMMENT(__("Segment file offset")) + + }, - if (format->is_32b) { - /* Champ "p_offset" */ + .name = "p_vaddr", + + .size = MDS_32_BITS, + .repeat = 1, + + PLAIN_COMMENT(__("Segment virtual address")) - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + }, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment file offset")); + { + .name = "p_paddr", + + .size = MDS_32_BITS, + .repeat = 1, - /* Champ "p_vaddr" */ + PLAIN_COMMENT(__("Segment physical address")) - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + }, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment virtual address")); + { + .name = "p_filesz", - /* Champ "p_paddr" */ + .size = MDS_32_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + PLAIN_COMMENT(__("Segment size in file")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment physical address")); + }, - /* Champ "p_filesz" */ + { + .name = "p_memsz", - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + .size = MDS_32_BITS, + .repeat = 1, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in file")); + PLAIN_COMMENT(__("Segment size in memory")) - /* Champ "p_memsz" */ + } - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); +}; - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in memory")); +static fmt_field_def _elf_phdr_32b_b[] = { - /* Champ "p_flags" */ + { + .name = "p_align", - dtext = strdup(_("Segment flags: ")); - filled = false; + .size = MDS_32_BITS, + .repeat = 1, - if (ELF_PHDR(format, phdr, p_flags) & PF_R) - { - dtext = stradd(dtext, "R"); - filled = true; - } + PLAIN_COMMENT(__("Segment alignment")) - if (ELF_PHDR(format, phdr, p_flags) & PF_W) - { - dtext = stradd(dtext, "W"); - filled = true; - } + } - if (ELF_PHDR(format, phdr, p_flags) & PF_X) - { - dtext = stradd(dtext, "X"); - filled = true; - } +}; - if (ELF_PHDR(format, phdr, p_flags) & PF_MASKOS) - /* TODO */; +static fmt_field_def _elf_phdr_64b[] = { - if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) - /* TODO */; + { + .name = "p_offset", - if (!filled) - dtext = stradd(dtext, _("none")); + .size = MDS_64_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + PLAIN_COMMENT(__("Segment file offset")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); + }, - free(dtext); + { + .name = "p_vaddr", - /* Champ "p_align" */ + .size = MDS_64_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + PLAIN_COMMENT(__("Segment virtual address")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment alignment")); + }, - } - else { - /* Champ "p_flags" */ + .name = "p_paddr", - dtext = strdup(_("Segment flags: ")); - filled = false; + .size = MDS_64_BITS, + .repeat = 1, - if (ELF_PHDR(format, phdr, p_flags) & PF_R) - { - dtext = stradd(dtext, "R"); - filled = true; - } + PLAIN_COMMENT(__("Segment physical address")) - if (ELF_PHDR(format, phdr, p_flags) & PF_W) - { - dtext = stradd(dtext, "W"); - filled = true; - } + }, - if (ELF_PHDR(format, phdr, p_flags) & PF_X) - { - dtext = stradd(dtext, "X"); - filled = true; - } + { + .name = "p_filesz", - if (ELF_PHDR(format, phdr, p_flags) & PF_MASKOS) - /* TODO */; + .size = MDS_64_BITS, + .repeat = 1, - if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) - /* TODO */; + PLAIN_COMMENT(__("Segment size in file")) - if (!filled) - dtext = stradd(dtext, _("none")); + }, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + { + .name = "p_memsz", - ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); + .size = MDS_64_BITS, + .repeat = 1, - free(dtext); + PLAIN_COMMENT(__("Segment size in memory")) - /* Champ "p_offset" */ + }, - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + { + .name = "p_align", - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment file offset")); + .size = MDS_64_BITS, + .repeat = 1, - /* Champ "p_vaddr" */ + PLAIN_COMMENT(__("Segment alignment")) - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + } - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment virtual address")); +}; - /* Champ "p_paddr" */ - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment physical address")); +/* Charge tous les symboles liés à un en-tête de programme ELF. */ +static bool annotate_elf_program_header(GElfFormat *, SourceEndian, vmpa2t *); - /* Champ "p_filesz" */ - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in file")); +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* endian = boutisme présentement utilisé. * +* pos = tête de lecture à déplacer. [OUT] * +* * +* Description : Charge tous les symboles liés à un en-tête de programme ELF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ - /* Champ "p_memsz" */ +static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + elf_phdr phdr; /* En-tête de programme ELF */ + fmt_field_def flags_field; /* Définition des drapeaux */ + char *rights; /* Reconstruction dynamique */ + comment_part parts[2]; /* Mise en place des parties */ + GBinFormat *bformat; /* Autre version du format */ + + result = read_elf_program_header(format, get_phy_addr(pos), &phdr); + + if (!result) + goto aeph_exit; - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + /* Préparation de la partie des drapeaux */ - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment size in memory")); + memset(&flags_field, 0, sizeof(flags_field)); - /* Champ "p_align" */ + flags_field.name = "p_flags"; - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + flags_field.size = MDS_32_BITS; + flags_field.repeat = 1; - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Segment alignment")); + rights = NULL; + if (ELF_PHDR(format, phdr, p_flags) & PF_R) + rights = stradd(rights, "R"); + + if (ELF_PHDR(format, phdr, p_flags) & PF_W) + rights = stradd(rights, "W"); + + if (ELF_PHDR(format, phdr, p_flags) & PF_X) + rights = stradd(rights, "X"); + + if (ELF_PHDR(format, phdr, p_flags) & PF_MASKOS) + /* TODO */; + + if (ELF_PHDR(format, phdr, p_flags) & PF_MASKPROC) + /* TODO */; + + if (rights == NULL) + { + flags_field.ctype = FCT_PLAIN; + flags_field.comment.plain = __("Segment flags: none"); } + else + { + parts[0].is_static = true; + parts[0].static_text = __("Segment flags: "); + + parts[1].is_static = false; + parts[1].dynamic_text = rights; + + flags_field.ctype = FCT_MULTI; + flags_field.comment.parts = parts; + flags_field.comment.pcount = ARRAY_SIZE(parts); + + } + + /* Interprétation générale */ + + bformat = G_BIN_FORMAT(format); + + result = parse_field_definitions(_elf_phdr_base, ARRAY_SIZE(_elf_phdr_base), bformat, pos); + + if (format->is_32b) + { + if (result) + result = parse_field_definitions(_elf_phdr_32b_a, ARRAY_SIZE(_elf_phdr_32b_a), bformat, pos); - g_object_unref(G_OBJECT(content)); + if (result) + result = parse_field_definitions(&flags_field, 1, bformat, pos); - return true; + if (result) + result = parse_field_definitions(_elf_phdr_32b_b, ARRAY_SIZE(_elf_phdr_32b_b), bformat, pos); + + } + else + { + + if (result) + result = parse_field_definitions(&flags_field, 1, bformat, pos); + + if (result) + result = parse_field_definitions(_elf_phdr_64b, ARRAY_SIZE(_elf_phdr_64b), bformat, pos); + + } + + aeph_exit: + + return result; } diff --git a/plugins/readelf/reader.c b/plugins/readelf/reader.c index 01d5d90..62efdf4 100644 --- a/plugins/readelf/reader.c +++ b/plugins/readelf/reader.c @@ -66,7 +66,7 @@ G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAct elf_fmt = G_ELF_FORMAT(format); - result = annotate_elf_header(elf_fmt); + result = annotate_elf_header(format); result &= annotate_elf_program_header_table(elf_fmt, status); diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c index f2cae76..e689aac 100644 --- a/plugins/readelf/section.c +++ b/plugins/readelf/section.c @@ -24,357 +24,385 @@ #include "section.h" +#include <string.h> + + #include <i18n.h> -#include <arch/raw.h> +#include <common/cpp.h> #include <common/extstr.h> -#include <format/symbol.h> #include <format/elf/elf-int.h> #include <format/elf/section.h> +#include <plugins/fmtp/parser.h> + + + +/* Définition des champs */ + +static field_desc_switch _elf_section_types[] = { + + { .fixed = SHT_NULL, .desc = __("Section type: unused") }, + { .fixed = SHT_PROGBITS, .desc = __("Section type: program data") }, + { .fixed = SHT_SYMTAB, .desc = __("Section type: symbol table") }, + { .fixed = SHT_STRTAB, .desc = __("Section type: string table") }, + { .fixed = SHT_RELA, .desc = __("Section type: relocation entries with addends") }, + { .fixed = SHT_HASH, .desc = __("Section type: symbol hash table") }, + { .fixed = SHT_DYNAMIC, .desc = __("Section type: dynamic linking information") }, + { .fixed = SHT_NOTE, .desc = __("Section type: notes") }, + { .fixed = SHT_NOBITS, .desc = __("Section type: program space with no data (bss)") }, + { .fixed = SHT_REL, .desc = __("Section type: relocation entries, no addends") }, + { .fixed = SHT_SHLIB, .desc = __("Section type: reserved") }, + { .fixed = SHT_DYNSYM, .desc = __("Section type: dynamic linker symbol table") }, + { .fixed = SHT_INIT_ARRAY, .desc = __("Section type: array of constructors") }, + { .fixed = SHT_FINI_ARRAY, .desc = __("Section type: array of destructors") }, + { .fixed = SHT_PREINIT_ARRAY, .desc = __("Section type: array of pre-constructors") }, + { .fixed = SHT_GROUP, .desc = __("Section type: section group") }, + { .fixed = SHT_SYMTAB_SHNDX, .desc = __("Section type: extended section indeces") }, + { .fixed = SHT_GNU_ATTRIBUTES, .desc = __("Section type: object attributes") }, + { .fixed = SHT_GNU_HASH, .desc = __("Section type: GNU-style hash table") }, + { .fixed = SHT_GNU_LIBLIST, .desc = __("Section type: prelink library list") }, + { .fixed = SHT_CHECKSUM, .desc = __("Section type: checksum for DSO content") }, + { .fixed = SHT_SUNW_move, .desc = __("Section type: SHT_SUNW_move") }, + { .fixed = SHT_SUNW_COMDAT, .desc = __("Section type: SHT_SUNW_COMDAT") }, + { .fixed = SHT_SUNW_syminfo, .desc = __("Section type: SHT_SUNW_syminfo") }, + { .fixed = SHT_GNU_verdef, .desc = __("Section type: version definition section") }, + { .fixed = SHT_GNU_verneed, .desc = __("Section type: version needs section") }, + { .fixed = SHT_GNU_versym, .desc = __("Section type: version symbol table") }, + { .lower = SHT_LOSUNW, .upper = SHT_HISUNW, .desc = __("Section type: Sun-specific") }, + { .lower = SHT_LOOS, .upper = SHT_HIOS, .desc = __("Section type: OS-specific") }, + { .lower = SHT_LOPROC, .upper = SHT_HIPROC, .desc = __("Section type: processor-specific") }, + { .lower = SHT_LOUSER, .upper = SHT_HIUSER, .desc = __("Section type: application-specific") } + +}; + +static fmt_field_def _elf_sh_type[] = { + { + .name = "sh_type", + .size = MDS_32_BITS, + .repeat = 1, -/* 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 *); + SWITCH_COMMENT(_elf_section_types, __("Section type: unknown")) + } +}; -/****************************************************************************** -* * -* 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 fmt_field_def _elf_shdr_32b[] = { -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 */ - 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; + { + .name = "sh_addr", - content = g_binary_format_get_content(G_BIN_FORMAT(format)); + .size = MDS_32_BITS, + .repeat = 1, - /* Champ "sh_name" */ + PLAIN_COMMENT(__("Section virtual addr at execution")) - 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, "'"); - } + .name = "sh_offset", - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + .size = MDS_32_BITS, + .repeat = 1, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + PLAIN_COMMENT(__("Section file offset")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); + }, - free(dtext); + { + .name = "sh_size", - /* Champ "sh_type" */ + .size = MDS_32_BITS, + .repeat = 1, - disp = IOD_DEC; + DISPLAY_RULES(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; - } + PLAIN_COMMENT(__("Section size in bytes")) - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + }, - SET_IMM_DISPLAY(instr, operand, 0, disp); + { + .name = "sh_link", - ADD_RAW_AS_SYM(format, symbol, instr, comment, text); + .size = MDS_32_BITS, + .repeat = 1, - /* Champ "sh_flags"... */ + PLAIN_COMMENT(__("Link to another section")) - dtext = strdup(_("Section flags: ")); - filled = false; + }, - if (ELF_SHDR(format, shdr, sh_type) & SHF_WRITE) { - dtext = stradd(dtext, "W"); - filled = true; - } + .name = "sh_info", + + .size = MDS_32_BITS, + .repeat = 1, + + PLAIN_COMMENT(__("Additional section information")) + + }, - if (ELF_SHDR(format, shdr, sh_type) & SHF_ALLOC) { - dtext = stradd(dtext, "A"); - filled = true; - } + .name = "sh_addralign", + + .size = MDS_32_BITS, + .repeat = 1, + + PLAIN_COMMENT(__("Section alignment")) + + }, - if (ELF_SHDR(format, shdr, sh_type) & SHF_EXECINSTR) { - dtext = stradd(dtext, "X"); - filled = true; + .name = "sh_entsize", + + .size = MDS_32_BITS, + .repeat = 1, + + DISPLAY_RULES(IOD_DEC), + + PLAIN_COMMENT(__("Entry size if section holds table")) + } - if (ELF_SHDR(format, shdr, sh_type) & SHF_MERGE) +}; + +static fmt_field_def _elf_shdr_64b[] = { + { - dtext = stradd(dtext, "M"); - filled = true; - } + .name = "sh_addr", + + .size = MDS_64_BITS, + .repeat = 1, + + PLAIN_COMMENT(__("Section virtual addr at execution")) + + }, - if (ELF_SHDR(format, shdr, sh_type) & SHF_LINK_ORDER) { - dtext = stradd(dtext, "L"); - filled = true; - } + .name = "sh_offset", + + .size = MDS_64_BITS, + .repeat = 1, + + PLAIN_COMMENT(__("Section file offset")) + + }, - if (ELF_SHDR(format, shdr, sh_type) & SHF_TLS) { - dtext = stradd(dtext, "T"); - filled = true; - } + .name = "sh_size", - if (!filled) - dtext = stradd(dtext, _("none")); + .size = MDS_64_BITS, + .repeat = 1, + + DISPLAY_RULES(IOD_DEC), + + PLAIN_COMMENT(__("Section size in bytes")) + + }, - if (format->is_32b) { - /* Champ "sh_flags" (suite) */ + .name = "sh_link", + + .size = MDS_32_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + PLAIN_COMMENT(__("Link to another section")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); + }, - free(dtext); + { + .name = "sh_info", + + .size = MDS_32_BITS, + .repeat = 1, - /* Champ "sh_addr" */ + PLAIN_COMMENT(__("Additional section information")) - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + }, - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section virtual addr at execution")); + { + .name = "sh_addralign", - /* Champ "sh_offset" */ + .size = MDS_64_BITS, + .repeat = 1, - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + PLAIN_COMMENT(__("Section alignment")) - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section file offset")); + }, - /* Champ "sh_size" */ + { + .name = "sh_entsize", - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + .size = MDS_64_BITS, + .repeat = 1, - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + DISPLAY_RULES(IOD_DEC), - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section size in bytes")); + PLAIN_COMMENT(__("Entry size if section holds table")) } - else - { - /* Champ "sh_flags" (suite) */ - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +}; + + - ADD_RAW_AS_SYM(format, symbol, instr, comment, dtext); +/* 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 *); - free(dtext); - /* Champ "sh_addr" */ - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); +/****************************************************************************** +* * +* 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) +{ + bool result; /* Bilan à retourner */ + elf_shdr shdr; /* En-tête de programme ELF */ + fmt_field_def name_field; /* Définition du nom de section*/ + const char *secname; /* Nom d'une section analysée */ + comment_part nparts[2]; /* Mise en place des parties */ + fmt_field_def flags_field; /* Définition des drapeaux */ + char *rights; /* Reconstruction dynamique */ + comment_part fparts[2]; /* Mise en place des parties */ + GBinFormat *bformat; /* Autre version du format */ - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section virtual addr at execution")); + result = read_elf_section_header(format, get_phy_addr(pos), &shdr); - /* Champ "sh_offset" */ + if (!result) + goto aesh_exit; - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + /* Préparation de la partie nominative */ - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section file offset")); + memset(&name_field, 0, sizeof(name_field)); - /* Champ "sh_size" */ + name_field.name = "sh_name"; - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + name_field.size = MDS_32_BITS; + name_field.repeat = 1; - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + name_field.has_display_rules = true; + name_field.disp_rules = (ImmOperandDisplay []) { IOD_DEC }; + name_field.disp_count = 1; - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section size in bytes")); + secname = extract_name_from_elf_string_section(format, strings, + ELF_SHDR(format, shdr, sh_name)); + if (secname == NULL) + { + name_field.ctype = FCT_PLAIN; + name_field.comment.plain = __("Section name: <invalid>"); } + else + { + nparts[0].is_static = true; + nparts[0].static_text = __("Segment name: "); - /* Champ "sh_link" */ + nparts[1].is_static = true; + nparts[1].avoid_i18n = true; + nparts[1].static_text = secname; - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + name_field.ctype = FCT_MULTI; + name_field.comment.parts = nparts; + name_field.comment.pcount = ARRAY_SIZE(nparts); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Link to another section")); + } - /* Champ "sh_info" */ + /* Préparation de la partie des drapeaux */ - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + memset(&flags_field, 0, sizeof(flags_field)); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Additional section information")); + flags_field.name = "sh_flags"; - if (format->is_32b) - { - /* Champ "sh_addralign" */ + flags_field.repeat = 1; + + rights = NULL; - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + if (ELF_SHDR(format, shdr, sh_type) & SHF_WRITE) + rights = stradd(rights, "W"); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section alignment")); + if (ELF_SHDR(format, shdr, sh_type) & SHF_ALLOC) + rights = stradd(rights, "A"); - /* Champ "sh_entsize" */ + if (ELF_SHDR(format, shdr, sh_type) & SHF_EXECINSTR) + rights = stradd(rights, "X"); - instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian); + if (ELF_SHDR(format, shdr, sh_type) & SHF_MERGE) + rights = stradd(rights, "M"); - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + if (ELF_SHDR(format, shdr, sh_type) & SHF_LINK_ORDER) + rights = stradd(rights, "L"); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry size if section holds table")); + if (ELF_SHDR(format, shdr, sh_type) & SHF_TLS) + rights = stradd(rights, "T"); + if (rights == NULL) + { + flags_field.ctype = FCT_PLAIN; + flags_field.comment.plain = __("Section flags: none"); } else { - /* Champ "sh_addralign" */ + fparts[0].is_static = true; + fparts[0].static_text = __("Section flags: "); + + fparts[1].is_static = false; + fparts[1].dynamic_text = rights; + + flags_field.ctype = FCT_MULTI; + flags_field.comment.parts = fparts; + flags_field.comment.pcount = ARRAY_SIZE(fparts); + + } + + /* Interprétation générale */ - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + bformat = G_BIN_FORMAT(format); - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Section alignment")); + result = parse_field_definitions(&name_field, 1, bformat, pos); - /* Champ "sh_entsize" */ + if (result) + result = parse_field_definitions(_elf_sh_type, ARRAY_SIZE(_elf_sh_type), bformat, pos); - instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, endian); + if (format->is_32b) + { + if (result) + { + flags_field.size = MDS_32_BITS; + result = parse_field_definitions(&flags_field, 1, bformat, pos); + } - SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); + if (result) + result = parse_field_definitions(_elf_shdr_32b, ARRAY_SIZE(_elf_shdr_32b), bformat, pos); + + } + else + { + if (result) + { + flags_field.size = MDS_64_BITS; + result = parse_field_definitions(&flags_field, 1, bformat, pos); + } - ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Entry size if section holds table")); + if (result) + result = parse_field_definitions(_elf_shdr_64b, ARRAY_SIZE(_elf_shdr_64b), bformat, pos); } - g_object_unref(G_OBJECT(content)); + aesh_exit: - return true; + return result; } @@ -415,7 +443,7 @@ bool annotate_elf_section_header_table(GElfFormat *format, GtkStatusStack *statu offset = ELF_HDR(format, *header, e_shoff); if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos)) - return false; + init_vmpa(&pos, offset, VMPA_NO_VIRTUAL); e_shnum = ELF_HDR(format, *header, e_shnum); |