summaryrefslogtreecommitdiff
path: root/src/format/elf
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-08-09 18:12:27 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-08-09 18:12:27 (GMT)
commit5cd25c4adfe0426520a51a76de3f77c77cfa4b8e (patch)
tree396514971fb78e81b7bb55c9cd3331d87b45ca9a /src/format/elf
parentd02deb2425d6559c357bdd00e1c0fb05f35d5fc9 (diff)
Reorganized the way formats are handled (Java and PE got disabled, Dwarf is empty).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@105 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/elf')
-rw-r--r--src/format/elf/Makefile.am10
-rw-r--r--src/format/elf/e_elf.c604
-rw-r--r--src/format/elf/e_elf.h63
-rw-r--r--src/format/elf/elf-int.c227
-rw-r--r--src/format/elf/elf-int.h113
-rw-r--r--src/format/elf/elf.c444
-rw-r--r--src/format/elf/elf.h62
-rw-r--r--src/format/elf/elf_def.h388
-rw-r--r--src/format/elf/helper_x86.c166
-rw-r--r--src/format/elf/helper_x86.h9
-rw-r--r--src/format/elf/section.c153
-rw-r--r--src/format/elf/section.h40
-rw-r--r--src/format/elf/strings.c161
-rw-r--r--src/format/elf/strings.h7
-rw-r--r--src/format/elf/symbol.c492
-rw-r--r--src/format/elf/symbols.c418
-rw-r--r--src/format/elf/symbols.h (renamed from src/format/elf/symbol.h)16
17 files changed, 1867 insertions, 1506 deletions
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am
index 822ea44..1e18356 100644
--- a/src/format/elf/Makefile.am
+++ b/src/format/elf/Makefile.am
@@ -2,13 +2,15 @@
noinst_LTLIBRARIES = libformatelf.la
libformatelf_la_SOURCES = \
- e_elf.h e_elf.c \
- elf-int.h \
- helper_mips.h helper_mips.c \
+ elf-int.h elf-int.c \
+ elf.h elf.c \
+ elf_def.h \
helper_x86.h helper_x86.c \
section.h section.c \
strings.h strings.c \
- symbol.h symbol.c
+ symbols.h symbols.c
+
+# helper_mips.h helper_mips.c
libformatelf_la_LDFLAGS =
diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c
deleted file mode 100644
index a91e279..0000000
--- a/src/format/elf/e_elf.c
+++ /dev/null
@@ -1,604 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * e_elf.c - support du format ELF
- *
- * Copyright (C) 2008 Cyrille Bagard
- *
- * This file is part of OpenIDA.
- *
- * 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 "e_elf.h"
-
-
-#include <malloc.h>
-#include <string.h>
-
-
-#include "elf-int.h"
-#include "section.h"
-#include "strings.h"
-#include "symbol.h"
-#include "../../panel/log.h"
-#include "../../common/extstr.h"
-
-
-
-
-#define _(str) str
-
-
-
-
-/* Indique le type d'architecture visée par le format. */
-FormatTargetMachine get_elf_target_machine(const elf_format *);
-
-
-
-/* Fournit l'adresse mémoire du point d'entrée du programme. */
-uint64_t get_elf_entry_point(const elf_format *);
-
-
-
-
-
-/* Récupère tous les éléments identifiées dans le binaire. */
-size_t get_elf_resolved_items(const elf_format *, char ***, ResolvedType **, uint64_t **);
-
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
-* *
-* Description : Indique si le format peut être pris en charge ici. *
-* *
-* Retour : true si la réponse est positive, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool elf_is_matching(const uint8_t *content, off_t length)
-{
- bool result; /* Bilan à faire connaître */
-
- result = false;
-
- if (length >= 4)
- result = (strncmp((const char *)content, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
-* *
-* Description : Prend en charge un nouvel ELF. *
-* *
-* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.*
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-elf_format *load_elf(const uint8_t *content, off_t length)
-{
- elf_format *result; /* Structure à retourner */
- bool test; /* Bilan d'une initialisation */
-
-
- Elf32_Half i;
- Elf32_Phdr phdr;
-
- size_t count;
-
-
- result = (elf_format *)calloc(1, sizeof(elf_format));
-
- EXE_FORMAT(result)->content = content;
- EXE_FORMAT(result)->length = length;
-
- EXE_FORMAT(result)->get_target_machine = (get_target_machine_fc)get_elf_target_machine;
- EXE_FORMAT(result)->get_entry_point = (get_entry_point_fc)get_elf_entry_point;
- EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_elf_default_code_parts;
- EXE_FORMAT(result)->find_section = (find_section_fc)find_elf_section_content_by_name;
- EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols;
- EXE_FORMAT(result)->get_resolved = (get_resolved_fc)get_elf_resolved_items;
- EXE_FORMAT(result)->resolve_symbol = (resolve_symbol_fc)resolve_elf_symbol;
- EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_elf_routines;
-
- memcpy(&result->header, content, sizeof(Elf32_Ehdr));
-
-
- /* TODO : endian */
-
-
- /* Vérification des tailles d'entrée de table */
- switch (result->header.e_ident[EI_CLASS])
- {
- case ELFCLASS32:
-
- if (result->header.e_phentsize != sizeof(Elf32_Phdr))
- {
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"),
- result->header.e_phentsize);
- result->header.e_phentsize = sizeof(Elf32_Phdr);
- }
-
- if (result->header.e_shentsize != sizeof(Elf32_Shdr))
- {
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"),
- result->header.e_shentsize);
- result->header.e_shentsize = sizeof(Elf32_Shdr);
- }
-
- break;
-
- case ELFCLASS64:
-
- if (result->header.e_phentsize != sizeof(Elf64_Phdr))
- {
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"),
- result->header.e_phentsize);
- result->header.e_phentsize = sizeof(Elf64_Phdr);
- }
-
- if (result->header.e_shentsize != sizeof(Elf64_Shdr))
- {
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"),
- result->header.e_shentsize);
- result->header.e_shentsize = sizeof(Elf64_Shdr);
- }
-
- break;
-
- default:
- log_variadic_message(LMT_BAD_BINARY, ("Invalid ELF class '%hhu'"),
- result->header.e_ident[EI_CLASS]);
- break;
-
- }
-
-
- /* FIXME : à améliorer */
- if ((result->header.e_shnum * result->header.e_shentsize) >= length)
- {
- log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !"));
- result->header.e_shnum = 0;
- }
-
-
- result->is_32b = (result->header.e_ident[EI_CLASS] == ELFCLASS32);
-
-
- for (i = 0; i < result->header.e_phnum; i++)
- {
-
- memcpy(&phdr, &content[result->header.e_phoff + i * result->header.e_phentsize], result->header.e_phentsize);
-
-
- printf(" seg [0x%08x] :: %d -> %d\n", phdr.p_type, phdr.p_offset, phdr.p_filesz);
-
-
- }
-
-
- test = read_elf_section_names(result);
-
- printf("section names ok ? %d\n", test);
-
- test = find_all_elf_strings(result);
-
- printf("strings ok ? %d\n", test);
-
- test = load_elf_symbols(result);
-
- printf("symbols ok ? %d\n", test);
-
-
-
- return result;
-
- lelf:
-
- /* TODO */
-
- return NULL;
-
-}
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* *
-* Description : Indique le type d'architecture visée par le format. *
-* *
-* Retour : Identifiant de l'architecture ciblée par le format. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-FormatTargetMachine get_elf_target_machine(const elf_format *format)
-{
- FormatTargetMachine result; /* Identifiant à retourner */
-
- switch (format->header.e_machine)
- {
- case EM_MIPS:
- result = FTM_MIPS;
- break;
-
- case EM_386:
- result = FTM_386;
- break;
-
- default:
- /* FIXME */
- break;
-
- }
-
- return result;
-
-}
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* *
-* Description : Fournit l'adresse mémoire du point d'entrée du programme. *
-* *
-* Retour : Adresse de mémoire. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-uint64_t get_elf_entry_point(const elf_format *format)
-{
- return format->header.e_entry;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* count = quantité de zones listées. [OUT] *
-* *
-* Description : Fournit les références aux zones de code à analyser. *
-* *
-* Retour : Zones de code à analyser. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bin_part **get_elf_default_code_parts(const elf_format *format, size_t *count)
-{
- bin_part **result; /* Tableau à retourner */
- bin_part *part; /* Partie à intégrer à la liste*/
- off_t offset; /* Position physique */
- off_t size; /* Taille de la partie */
- uint64_t voffset; /* Adresse virtuelle éventuelle*/
- int i; /* Boucle de parcours */
- Elf_Shdr shdr; /* En-tête de section ELF */
- Elf_Phdr phdr; /* En-tête de programme ELF */
-
- result = NULL;
- *count = 0;
-
- if (format->sec_size > 0)
- {
- if (find_elf_section_content_by_name(format, ".plt", &offset, &size, &voffset))
- {
- part = create_bin_part();
-
- set_bin_part_name(part, ".plt");
- set_bin_part_values(part, offset, size, voffset);
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- if (find_elf_section_content_by_name(format, ".MIPS.stubs", &offset, &size, &voffset))
- {
- part = create_bin_part();
-
- set_bin_part_name(part, ".MIPS.stubs");
- set_bin_part_values(part, offset, size, voffset);
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- if (find_elf_section_content_by_name(format, ".init", &offset, &size, &voffset))
- {
- part = create_bin_part();
-
- set_bin_part_name(part, ".init");
- set_bin_part_values(part, offset, size, voffset);
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- if (find_elf_section_content_by_name(format, ".text", &offset, &size, &voffset))
- {
- part = create_bin_part();
-
- set_bin_part_name(part, ".text");
- set_bin_part_values(part, offset, size, voffset);
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- if (find_elf_section_content_by_name(format, ".fini", &offset, &size, &voffset))
- {
- part = create_bin_part();
-
- set_bin_part_name(part, ".fini");
- set_bin_part_values(part, offset, size, voffset);
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- }
-
- /* Si aucune section n'a été trouvée... */
-
- if (*count == 0)
- for (i = 0; i < format->header.e_shnum; i++)
- {
- offset = format->header.e_shoff + format->header.e_shentsize * i;
- if ((offset + format->header.e_shentsize) >= EXE_FORMAT(format)->length) continue;
-
- memcpy(&shdr, &EXE_FORMAT(format)->content[offset], format->header.e_shentsize);
-
- if (ELF_SHDR(format, &shdr, sh_flags) & SHF_EXECINSTR)
- {
- part = create_bin_part();
-
- /* TODO : nom */
-
- set_bin_part_values(part, ELF_SHDR(format, &shdr, sh_offset),
- ELF_SHDR(format, &shdr, sh_size),
- ELF_SHDR(format, &shdr, sh_addr));
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- }
-
- /* En désespoir de cause, on se rabbat sur les parties de programme directement */
-
- if (*count == 0)
- for (i = 0; i < format->header.e_phnum; i++)
- {
- offset = format->header.e_phoff + format->header.e_phentsize * i;
- if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue;
-
- memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize);
-
- if (ELF_PHDR(format, &phdr, p_flags) & PF_X)
- {
- part = create_bin_part();
-
- /* TODO : nom */
-
- set_bin_part_values(part, ELF_PHDR(format, &phdr, p_offset),
- ELF_PHDR(format, &phdr, p_filesz),
- ELF_PHDR(format, &phdr, p_vaddr));
-
- result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *));
- result[*count - 1] = part;
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* labels = liste des commentaires à insérer. [OUT] *
-* types = type des symboles listés. [OUT] *
-* offsets = liste des indices des commentaires. [OUT] *
-* *
-* Description : Récupère tous les symboles présents dans le contenu binaire. *
-* *
-* Retour : Nombre d'éléments mis en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t get_elf_symbols(const elf_format *format, char ***labels, SymbolType **types, uint64_t **offsets)
-{
- size_t result; /* Quantité à retourner */
- size_t i; /* Boucle de parcours */
-
- result = format->sym_count;
-
- *labels = (char **)calloc(result, sizeof(char *));
- *types = (SymbolType *)calloc(result, sizeof(SymbolType));
- *offsets = (uint64_t *)calloc(result, sizeof(uint64_t));
-
- for (i = 0; i < format->sym_count; i++)
- {
- (*labels)[i] = strdup(format->symbols[i].name);
- (*types)[i] = STP_SECTION;
- (*offsets)[i] = format->symbols[i].address;
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* labels = liste des commentaires à insérer. [OUT] *
-* types = type des symboles listés. [OUT] *
-* offsets = liste des indices des commentaires. [OUT] *
-* *
-* Description : Récupère tous les éléments identifiées dans le binaire. *
-* *
-* Retour : Nombre d'éléments mis en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t get_elf_resolved_items(const elf_format *format, char ***labels, ResolvedType **types, uint64_t **offsets)
-{
- size_t result; /* Quantité à retourner */
- size_t i; /* Boucle de parcours */
- size_t start; /* Point de départ du tour */
-
- result = format->sym_count + format->str_count;
-
- *labels = (char **)calloc(result, sizeof(char *));
- *types = (SymbolType *)calloc(result, sizeof(SymbolType));
- *offsets = (uint64_t *)calloc(result, sizeof(uint64_t));
-
- for (i = 0; i < format->sym_count; i++)
- {
- (*labels)[i] = strdup(format->symbols[i].name);
- (*types)[i] = RTP_SECTION;
- (*offsets)[i] = format->symbols[i].address;
- }
-
- start = format->sym_count;
-
- for (i = 0; i < format->str_count; i++)
- {
- (*labels)[start + i] = strndup(format->strings[i].value, format->strings[i].len);
- (*types)[start + i] = RTP_STRING;
- (*offsets)[start + i] = format->strings[i].address;
-
- (*labels)[start + i] = escape_crlf((*labels)[start + i]);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* label = étiquette du symbole si trouvé. [OUT] *
-* type = type du symbole trouvé. [OUT] *
-* address = adresse à cibler, puis décallage final. [OUT] *
-* *
-* Description : Recherche le symbole correspondant à une adresse. *
-* *
-* Retour : true si l'opération a été un succès, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type, vmpa_t *address)
-{
- bool result; /* Bilan à retourner */
- size_t best_index; /* Meilleur symbole trouvé */
- vmpa_t best_addr; /* Meilleure adresse trouvée */
- vmpa_t addr; /* Adresse de routine */
- size_t i; /* Boucle de parcours */
-
- if (resolve_elf_strings(format, label, address))
- {
- *type = STP_STRING;
- return true;
- }
-
- best_index = format->routines_count; /* Pour GCC */
- best_addr = UINT64_MAX; /* FIXME */
-
- for (i = 0; i < format->routines_count; i++)
- {
- addr = g_binary_routine_get_address(format->routines[i]);
-
- if (addr <= *address && (*address - addr) < best_addr)
- {
- best_index = i;
- best_addr = *address - addr;
- }
-
- }
-
- result = (best_addr != UINT64_MAX);
-
- if (result)
- {
- *label = strdup(g_binary_routine_get_name(format->routines[best_index]));
- *type = STP_SECTION;
- *address -= g_binary_routine_get_address(format->routines[best_index]);
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* count = taille du tableau créé. [OUT] *
-* *
-* Description : Fournit le prototype de toutes les routines détectées. *
-* *
-* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBinRoutine **get_all_elf_routines(const elf_format *format, size_t *count)
-{
- *count = format->routines_count;
-
- return format->routines;
-
-}
diff --git a/src/format/elf/e_elf.h b/src/format/elf/e_elf.h
deleted file mode 100644
index b8abe05..0000000
--- a/src/format/elf/e_elf.h
+++ /dev/null
@@ -1,63 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * e_elf.h - prototypes pour le support du format ELF
- *
- * Copyright (C) 2008 Cyrille Bagard
- *
- * This file is part of OpenIDA.
- *
- * 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/>.
- */
-
-
-#ifndef _FORMAT_ELF_ELF_H
-#define _FORMAT_ELF_ELF_H
-
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-
-#include "../exe_format.h"
-
-
-
-/* Description du format ELF */
-typedef struct _elf_format elf_format;
-
-
-/* Indique si le format peut être pris en charge ici. */
-bool elf_is_matching(const uint8_t *, off_t);
-
-/* Prend en charge un nouvel ELF. */
-elf_format *load_elf(const uint8_t *, off_t);
-
-
-
-/* Fournit les références aux zones de code à analyser. */
-bin_part **get_elf_default_code_parts(const elf_format *, size_t *);
-
-/* Récupère tous les symboles présents dans le contenu binaire. */
-size_t get_elf_symbols(const elf_format *, char ***, SymbolType **, uint64_t **);
-
-/* Recherche le symbole correspondant à une adresse. */
-bool resolve_elf_symbol(const elf_format *, char **, SymbolType *, vmpa_t *);
-
-/* Fournit le prototype de toutes les routines détectées. */
-GBinRoutine **get_all_elf_routines(const elf_format *, size_t *);
-
-
-
-#endif /* _FORMAT_ELF_ELF_H */
diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c
new file mode 100644
index 0000000..69363d2
--- /dev/null
+++ b/src/format/elf/elf-int.c
@@ -0,0 +1,227 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf-int.c - structures internes du format ELF
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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 "elf-int.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* header = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de programme ELF. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_elf_program_header(const GElfFormat *format, off_t *pos, elf_phdr *header)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ if (format->is_32b)
+ {
+ result = read_u32(&header->phdr32.p_type, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_offset, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_vaddr, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_paddr, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_filesz, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_memsz, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_flags, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr32.p_align, content, pos, length, format->endian);
+ }
+ else
+ {
+ result = read_u32(&header->phdr64.p_type, content, pos, length, format->endian);
+ result &= read_u32(&header->phdr64.p_flags, content, pos, length, format->endian);
+ result &= read_u64(&header->phdr64.p_offset, content, pos, length, format->endian);
+ result &= read_u64(&header->phdr64.p_vaddr, content, pos, length, format->endian);
+ result &= read_u64(&header->phdr64.p_paddr, content, pos, length, format->endian);
+ result &= read_u64(&header->phdr64.p_filesz, content, pos, length, format->endian);
+ result &= read_u64(&header->phdr64.p_memsz, content, pos, length, format->endian);
+ result &= read_u64(&header->phdr64.p_align, content, pos, length, format->endian);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de la tête de lecture. *
+* section = section lue. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de section ELF. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_elf_section_header(const GElfFormat *format, off_t pos, elf_shdr *section)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ elf32_shdr *shdr32; /* Version 32 bits */
+ elf64_shdr *shdr64; /* Version 32 bits */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ if (format->is_32b)
+ {
+ shdr32 = &section->shdr32;
+
+ result = read_u32(&shdr32->sh_name, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_type, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_flags, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_addr, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_offset, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_size, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_link, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_info, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_addralign, content, &pos, length, format->endian);
+ result &= read_u32(&shdr32->sh_entsize, content, &pos, length, format->endian);
+
+ }
+ else
+ {
+ shdr64 = &section->shdr64;
+
+ result = read_u32(&shdr64->sh_name, content, &pos, length, format->endian);
+ result &= read_u32(&shdr64->sh_type, content, &pos, length, format->endian);
+ result &= read_u64(&shdr64->sh_flags, content, &pos, length, format->endian);
+ result &= read_u64(&shdr64->sh_addr, content, &pos, length, format->endian);
+ result &= read_u64(&shdr64->sh_offset, content, &pos, length, format->endian);
+ result &= read_u64(&shdr64->sh_size, content, &pos, length, format->endian);
+ result &= read_u32(&shdr64->sh_link, content, &pos, length, format->endian);
+ result &= read_u32(&shdr64->sh_info, content, &pos, length, format->endian);
+ result &= read_u64(&shdr64->sh_addralign, content, &pos, length, format->endian);
+ result &= read_u64(&shdr64->sh_entsize, content, &pos, length, format->endian);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* sym = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'un symbole ELF. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_elf_symbol(const GElfFormat *format, off_t *pos, elf_sym *sym)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ if (format->is_32b)
+ {
+ result = read_u32(&sym->sym32.st_name, content, pos, length, format->endian);
+ result &= read_u32(&sym->sym32.st_value, content, pos, length, format->endian);
+ result &= read_u32(&sym->sym32.st_size, content, pos, length, format->endian);
+ result &= read_u8(&sym->sym32.st_info, content, pos, length, format->endian);
+ result &= read_u8(&sym->sym32.st_other, content, pos, length, format->endian);
+ result &= read_u16(&sym->sym32.st_shndx, content, pos, length, format->endian);
+ }
+ else
+ {
+ result = read_u32(&sym->sym64.st_name, content, pos, length, format->endian);
+ result &= read_u8(&sym->sym64.st_info, content, pos, length, format->endian);
+ result &= read_u8(&sym->sym64.st_other, content, pos, length, format->endian);
+ result &= read_u16(&sym->sym64.st_shndx, content, pos, length, format->endian);
+ result &= read_u64(&sym->sym64.st_value, content, pos, length, format->endian);
+ result &= read_u64(&sym->sym64.st_size, content, pos, length, format->endian);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* reloc = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une relocalisation ELF. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_elf_relocation(const GElfFormat *format, off_t *pos, elf_rel *reloc)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ if (format->is_32b)
+ {
+ result = read_u32(&reloc->rel32.r_offset, content, pos, length, format->endian);
+ result &= read_u32(&reloc->rel32.r_info, content, pos, length, format->endian);
+ }
+ else
+ {
+ result = read_u64(&reloc->rel64.r_offset, content, pos, length, format->endian);
+ result &= read_u64(&reloc->rel64.r_info, content, pos, length, format->endian);
+ }
+
+ return result;
+
+}
diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h
index 4339475..f7fd804 100644
--- a/src/format/elf/elf-int.h
+++ b/src/format/elf/elf-int.h
@@ -25,115 +25,44 @@
#define _FORMAT_ELF_ELF_INT_H
+#include "elf.h"
+#include "elf_def.h"
+#include "../executable-int.h"
+#include "../../common/endianness.h"
-#include <elf.h>
-#include <sys/types.h>
-#include "../exe_format-int.h"
-
-
-
-/* Chaîne de caractères présente */
-typedef struct _elf_string
-{
- const char *value; /* Valeur humainement lisible */
- size_t len; /* Longueur de la chaîne */
- vmpa_t address; /* Adresse de localisation */
-
-} elf_string;
-
-/* Symbole trouvé */
-typedef struct _elf_symbol
-{
- const char *name; /* Désignation du symbole */
- uint64_t address; /* Adresse du symbole */
- off_t size; /* Taille du code associé */
-
-} elf_symbol;
-
-/* Relocalisation trouvée */
-typedef struct _elf_relocation
+/* Format d'exécutable générique (instance) */
+struct _GElfFormat
{
- const char *name; /* Désignation du symbole */
- vmpa_t address; /* Adresse du symbole */
+ GExeFormat parent; /* A laisser en premier */
-} elf_relocation;
-
-
-
-/* Description du format ELF */
-struct _elf_format
-{
- exe_format dummy; /* A laisser en premier */
-
- Elf32_Ehdr header; /* En-tête du format */
+ elf_header header; /* En-tête du format */
bool is_32b; /* Format du binaire */
-
- char *sec_names; /* Noms des sections */
- size_t sec_size; /* Taille de ces définitions */
-
- elf_relocation *relocations; /* Liste des relocalisations */
- size_t rel_count; /* Taille de cette liste */
-
- GBinRoutine **routines; /* Liste des routines trouvées */
- size_t routines_count; /* Nombre de ces routines */
-
- elf_symbol *symbols; /* Liste des symboles */
- size_t sym_count; /* Taille de cette liste */
-
- elf_string *strings; /* Liste des chaînes */
- size_t str_count; /* Taille de cette liste */
+ SourceEndian endian; /* Boutisme du format */
};
-
-
-
-/* En-tête de programme ELF */
-typedef union _Elf_Phdr
-{
- Elf32_Phdr header32; /* Version 32 bits */
- Elf64_Phdr header64; /* Version 64 bits */
-
-} Elf_Phdr;
-
-#define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? (hdr)->header32.fld : (hdr)->header64.fld)
-
-
-/* Entrée de la table de relocalisation */
-
-typedef union _Elf_Rel
+/* Format d'exécutable générique (classe) */
+struct _GElfFormatClass
{
- Elf32_Rel rel32; /* Version 32 bits */
- Elf64_Rel rel64; /* Version 64 bits */
-
-} Elf_Rel;
-
-#define ELF_SIZEOF_REL(fmt) (fmt->is_32b ? sizeof(Elf32_Rel) : sizeof(Elf64_Rel))
-
-#define ELF_REL(fmt, rl, fld) (fmt->is_32b ? rl.rel32.fld : rl.rel64.fld)
-
-#define ELF_REL_SYM(fmt, rl) (fmt->is_32b ? ELF32_R_SYM(rl.rel32.r_info) : ELF64_R_SYM(rl.rel64.r_info))
-#define ELF_REL_TYPE(fmt, rl) (fmt->is_32b ? ELF32_R_TYPE(rl.rel32.r_info) : ELF64_R_TYPE(rl.rel64.r_info))
+ GExeFormatClass parent; /* A laisser en premier */
+};
-/* Information sur un symbole */
-
-typedef union _Elf_Sym
-{
- Elf32_Sym sym32; /* Version 32 bits */
- Elf64_Sym sym64; /* Version 64 bits */
-
-} Elf_Sym;
-#define ELF_SIZEOF_SYM(fmt) (fmt->is_32b ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym))
-#define ELF_SYM(fmt, sb, fld) (fmt->is_32b ? sb.sym32.fld : sb.sym64.fld)
+/* Procède à la lecture d'une en-tête de programme ELF. */
+bool read_elf_program_header(const GElfFormat *, off_t *, elf_phdr *);
+/* Procède à la lecture d'une en-tête de section ELF. */
+bool read_elf_section_header(const GElfFormat *, off_t, elf_shdr *);
-#define ELF_ST_TYPE ELF32_ST_TYPE
+/* Procède à la lecture d'un symbole ELF. */
+bool read_elf_symbol(const GElfFormat *, off_t *, elf_sym *);
+/* Procède à la lecture d'une relocalisation ELF. */
+bool read_elf_relocation(const GElfFormat *, off_t *, elf_rel *);
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
new file mode 100644
index 0000000..d24a89e
--- /dev/null
+++ b/src/format/elf/elf.c
@@ -0,0 +1,444 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf.c - support du format ELF
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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 "elf.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "elf-int.h"
+#include "section.h"
+#include "strings.h"
+#include "symbols.h"
+#include "../../panel/log.h"
+
+
+
+
+#ifndef _
+# define _(str) (str)
+#endif
+
+
+
+
+/* Initialise la classe des formats d'exécutables ELF. */
+static void g_elf_format_class_init(GElfFormatClass *);
+
+/* Initialise une instance de format d'exécutable ELF. */
+static void g_elf_format_init(GElfFormat *);
+
+/* Procède à la lecture de l'en-tête d'un contenu binaire. */
+static bool read_elf_header(const bin_t *, off_t, elf_header *, bool *, SourceEndian *);
+
+/* Indique le type d'architecture visée par le format. */
+static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *);
+
+/* Fournit l'adresse mémoire du point d'entrée du programme. */
+static vmpa_t g_elf_format_get_entry_point(const GElfFormat *);
+
+/* Fournit les références aux zones binaires à analyser. */
+static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de format recherché. *
+* content = contenu binaire à parcourir. *
+* length = taille du contenu en question. *
+* *
+* Description : Indique si le format peut être pris en charge ici. *
+* *
+* Retour : true si la réponse est positive, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool elf_is_matching(FormatType type, const bin_t *content, off_t length)
+{
+ bool result; /* Bilan à faire connaître */
+
+ result = false;
+
+ if (length >= 4)
+ result = (memcmp(content, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0);
+
+ return result;
+
+}
+
+
+/* Indique le type défini pour un format d'exécutable ELF. */
+G_DEFINE_TYPE(GElfFormat, g_elf_format, G_TYPE_EXE_FORMAT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des formats d'exécutables ELF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_format_class_init(GElfFormatClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = instance à initialiser. *
+* *
+* Description : Initialise une instance de format d'exécutable ELF. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_elf_format_init(GElfFormat *format)
+{
+ GExeFormat *exe_format;
+
+ exe_format = G_EXE_FORMAT(format);
+
+ exe_format->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine;
+ exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point;
+ exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à parcourir. *
+* length = taille du contenu en question. *
+* header = en-tête à déterminer. [OUT] *
+* is_32b = indique si le format est en 32 ou 64 bits. [OUT] *
+* endian = boutisme reconnu dans le format. [OUT] *
+* *
+* Description : Procède à la lecture de l'en-tête d'un contenu binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool read_elf_header(const bin_t *content, off_t length, elf_header *header, bool *is_32b, SourceEndian *endian)
+{
+ bool result; /* Bilan à retourner */
+ off_t pos; /* Position de lecture */
+
+ result = (length >= EI_NIDENT);
+
+ pos = 0;
+
+ if (result)
+ {
+ memcpy(header->e_ident, content, EI_NIDENT);
+ pos += EI_NIDENT;
+ }
+
+ /* Détermination de l'espace d'adressage */
+ if (result)
+ switch (header->e_ident[EI_CLASS])
+ {
+ case ELFCLASS32:
+ *is_32b = true;
+ break;
+ case ELFDATA2MSB:
+ *is_32b = false;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ /* Détermination du boutisme */
+ if (result)
+ switch (header->e_ident[EI_DATA])
+ {
+ case ELFDATA2LSB:
+ *endian = SRE_LITTLE;
+ break;
+ case ELFDATA2MSB:
+ *endian = SRE_BIG;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ if (result)
+ result = read_u16(&header->e_type, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_machine, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u32(&header->e_version, content, &pos, length, *endian);
+
+ if (result)
+ {
+ if (*is_32b)
+ result = read_u32(&header->e_entry.addr32, content, &pos, length, *endian);
+ else
+ result = read_u64(&header->e_entry.addr64, content, &pos, length, *endian);
+ }
+
+ if (result)
+ {
+ if (*is_32b)
+ result = read_u32(&header->e_phoff.off32, content, &pos, length, *endian);
+ else
+ result = read_u64(&header->e_phoff.off64, content, &pos, length, *endian);
+ }
+
+ if (result)
+ {
+ if (*is_32b)
+ result = read_u32(&header->e_shoff.off32, content, &pos, length, *endian);
+ else
+ result = read_u64(&header->e_shoff.off64, content, &pos, length, *endian);
+ }
+
+ if (result)
+ result = read_u32(&header->e_flags, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_ehsize, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_phentsize, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_phnum, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_shentsize, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_shnum, content, &pos, length, *endian);
+
+ if (result)
+ result = read_u16(&header->e_shstrndx, content, &pos, length, *endian);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à parcourir. *
+* length = taille du contenu en question. *
+* *
+* Description : Prend en charge un nouveau format ELF. *
+* *
+* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinFormat *g_elf_format_new(const bin_t *content, off_t length)
+{
+ GElfFormat *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_ELF_FORMAT, NULL);
+
+ g_binary_format_set_content(G_BIN_FORMAT(result), content, length);
+
+ if (!read_elf_header(content, length, &result->header, &result->is_32b, &result->endian))
+ {
+ /* TODO */
+ return NULL;
+ }
+
+
+ /* Vérification des tailles d'entrée de table */
+
+ if (result->header.e_phentsize != ELF_SIZEOF_PHDR(result))
+ {
+ log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"),
+ result->header.e_phentsize);
+ result->header.e_phentsize = ELF_SIZEOF_PHDR(result);
+ }
+
+ if (result->header.e_shentsize != ELF_SIZEOF_SHDR(result))
+ {
+ log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"),
+ result->header.e_shentsize);
+ result->header.e_shentsize = ELF_SIZEOF_SHDR(result);
+ }
+
+ /* FIXME : à améliorer */
+ if ((result->header.e_shnum * result->header.e_shentsize) >= length)
+ {
+ log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !"));
+ result->header.e_shnum = 0;
+ }
+
+
+
+
+ if (!load_elf_symbols(result))
+ {
+ /* TODO */
+ return NULL;
+ }
+
+
+ if (!find_all_elf_strings(result))
+ {
+ /* TODO */
+ return NULL;
+ }
+
+
+
+ return G_BIN_FORMAT(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* *
+* Description : Indique le type d'architecture visée par le format. *
+* *
+* Retour : Identifiant de l'architecture ciblée par le format. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *format)
+{
+ FormatTargetMachine result; /* Identifiant à retourner */
+
+ switch (format->header.e_machine)
+ {
+ case EM_MIPS:
+ result = FTM_MIPS;
+ break;
+
+ case EM_386:
+ result = FTM_386;
+ break;
+
+ case EM_NONE:
+ default:
+ result = FTM_NONE;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* *
+* Description : Fournit l'adresse mémoire du point d'entrée du programme. *
+* *
+* Retour : Adresse de mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format)
+{
+ return (format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* count = quantité de zones listées. [OUT] *
+* *
+* Description : Fournit les références aux zones binaires à analyser. *
+* *
+* Retour : Zones binaires à analyser. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count)
+{
+ GBinPart **result; /* Tableau à retourner */
+ uint16_t i; /* Boucle de parcours */
+ elf_shdr section; /* En-tête de section ELF */
+ GBinPart *part; /* Partie à intégrer à la liste*/
+
+ result = NULL;
+ *count = 0;
+
+ /* Première tentative : les sections */
+
+ for (i = 0; i < format->header.e_shnum; i++)
+ {
+ if (!find_elf_section_by_index(format, i, &section))
+ continue;
+
+
+ if (ELF_SHDR(format, section, sh_flags) & SHF_EXECINSTR)
+ {
+ part = g_binary_part_new();
+
+ /* TODO : nom, droits/type */
+
+ g_binary_part_set_values(part,
+ ELF_SHDR(format, section, sh_offset),
+ ELF_SHDR(format, section, sh_size),
+ ELF_SHDR(format, section, sh_addr));
+
+ result = (GBinPart **)realloc(result, ++(*count) * sizeof(GBinPart *));
+ result[*count - 1] = part;
+
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h
new file mode 100644
index 0000000..e8ad70b
--- /dev/null
+++ b/src/format/elf/elf.h
@@ -0,0 +1,62 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf.h - prototypes pour le support du format ELF
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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/>.
+ */
+
+
+#ifndef _FORMAT_ELF_ELF_H
+#define _FORMAT_ELF_ELF_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+
+#include "../format.h"
+
+
+
+#define G_TYPE_ELF_FORMAT g_elf_format_get_type()
+#define G_ELF_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_elf_format_get_type(), GElfFormat))
+#define G_IS_ELF_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_elf_format_get_type()))
+#define G_ELF_FORMAT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_elf_format_get_type(), GElfFormatIface))
+#define G_ELF_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ELF_FORMAT, GElfFormatClass))
+
+
+/* Format d'exécutable ELF (instance) */
+typedef struct _GElfFormat GElfFormat;
+
+/* Format d'exécutable ELF (classe) */
+typedef struct _GElfFormatClass GElfFormatClass;
+
+
+/* Indique si le format peut être pris en charge ici. */
+bool elf_is_matching(FormatType, const bin_t *, off_t);
+
+/* Indique le type défini pour un format d'exécutable ELF. */
+GType g_elf_format_get_type(void);
+
+/* Prend en charge un nouveau format ELF. */
+GBinFormat *g_elf_format_new(const bin_t *, off_t);
+
+
+
+#endif /* _FORMAT_ELF_ELF_H */
diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h
new file mode 100644
index 0000000..bbd6117
--- /dev/null
+++ b/src/format/elf/elf_def.h
@@ -0,0 +1,388 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf_def.h - liste des structures et constantes utilisées par le format ELF
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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/>.
+ */
+
+
+#ifndef _FORMAT_ELF_ELF_DEF_H
+#define _FORMAT_ELF_ELF_DEF_H
+
+
+#include <stdint.h>
+
+
+
+/* Adresses virtuelles */
+typedef union _elf_addr
+{
+ uint32_t addr32; /* Elf 32 bits */
+ uint64_t addr64; /* Elf 64 bits */
+
+} elf_addr;
+
+/* Positions dans le fichier */
+typedef union _elf_off
+{
+ uint32_t off32; /* Elf 32 bits */
+ uint64_t off64; /* Elf 64 bits */
+
+} elf_off;
+
+
+#define ELF_OFF(fmt, off) (fmt->is_32b ? (off).off32 : (off).off64)
+
+
+
+/* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */
+
+
+#define EI_NIDENT 16
+
+
+/* En-tête de fichier ELF */
+typedef struct _elf_header
+{
+ uint8_t e_ident[EI_NIDENT]; /* Magic number + informations */
+ uint16_t e_type; /* Type de fichier */
+ uint16_t e_machine; /* Architecture */
+ uint32_t e_version; /* Version du type de fichier */
+ elf_addr e_entry; /* Point d'entrée du programme */
+ elf_off e_phoff; /* Début de la table 'Program' */
+ elf_off e_shoff; /* Début de la table 'Section' */
+ uint32_t e_flags; /* Prop. spécifiques au proc. */
+ uint16_t e_ehsize; /* Taille de l'en-tête en oct. */
+ uint16_t e_phentsize; /* Taille d'une entrée Program */
+ uint16_t e_phnum; /* Nombre d'éléments 'Program' */
+ uint16_t e_shentsize; /* Taille d'une entrée Section */
+ uint16_t e_shnum; /* Nombre d'éléments 'Section' */
+ uint16_t e_shstrndx; /* Indice de la section chaînes*/
+
+} elf_header;
+
+
+/* Composition du champ e_ident */
+
+
+#define EI_CLASS 4 /* Indice de classe du fichier */
+#define EI_DATA 5 /* Indice de l'encodage */
+
+
+/* ... EI_CLASS */
+
+#define ELFCLASSNONE 0 /* Objet invalide */
+#define ELFCLASS32 1 /* Objet 32 bits */
+#define ELFCLASS64 2 /* Objet 64 bits */
+
+/* ... EI_DATA */
+
+#define ELFDATANONE 0 /* Encodage invalide */
+#define ELFDATA2LSB 1 /* Complément à 2, petit bout. */
+#define ELFDATA2MSB 2 /* Complément à 2, grand bout. */
+
+
+/* Valeurs possibles pour e_machine */
+
+#define EM_NONE 0 /* Aucune machine */
+#define EM_386 3 /* Intel 80386 */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
+
+
+
+/* --------------------------- EN-TETE DES PROGRAMMES ELF --------------------------- */
+
+
+/* Version 32 et 64 bits */
+
+
+typedef struct _elf32_phdr
+{
+ uint32_t p_type; /* Type de segment */
+ uint32_t p_offset; /* Position dans le fichier */
+ uint32_t p_vaddr; /* Adresse virtuelle du segment*/
+ uint32_t p_paddr; /* Adresse physique du segment */
+ uint32_t p_filesz; /* Taille dans le fichier */
+ uint32_t p_memsz; /* Taille en mémoire */
+ uint32_t p_flags; /* Drapeaux pour le segment */
+ uint32_t p_align; /* Alignement du segment */
+
+} elf32_phdr;
+
+typedef struct _elf64_phdr
+{
+ uint32_t p_type; /* Type de segment */
+ uint32_t p_flags; /* Drapeaux pour le segment */
+ uint64_t p_offset; /* Position dans le fichier */
+ uint64_t p_vaddr; /* Adresse virtuelle du segment*/
+ uint64_t p_paddr; /* Adresse physique du segment */
+ uint64_t p_filesz; /* Taille dans le fichier */
+ uint64_t p_memsz; /* Taille en mémoire */
+ uint64_t p_align; /* Alignement du segment */
+
+} elf64_phdr;
+
+typedef union _elf_phdr
+{
+ elf32_phdr phdr32; /* Version 32 bits */
+ elf64_phdr phdr64; /* Version 32 bits */
+
+} elf_phdr;
+
+
+#define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? hdr.phdr32.fld : hdr.phdr64.fld)
+
+#define ELF_SIZEOF_PHDR(fmt) (fmt->is_32b ? sizeof(elf32_phdr) : sizeof(elf64_phdr))
+
+
+/* Valeurs possibles pour p_flags */
+
+#define PF_X (1 << 0) /* Le segment est exécutable */
+#define PF_W (1 << 1) /* Le segment est écrasable */
+#define PF_R (1 << 2) /* Le segment est lisible */
+
+
+
+/* ---------------------------- EN-TETE DES SECTIONS ELF ---------------------------- */
+
+
+/* Version 32 et 64 bits */
+
+typedef struct _elf32_shdr
+{
+ uint32_t sh_name; /* Indice du nom de la section */
+ uint32_t sh_type; /* Type de section */
+ uint32_t sh_flags; /* Drapeaux pour la section */
+ uint32_t sh_addr; /* Adresse virtuelle à l'exec. */
+ uint32_t sh_offset; /* Position dans le fichier */
+ uint32_t sh_size; /* Taille en octets */
+ uint32_t sh_link; /* Lien vers une autre section */
+ uint32_t sh_info; /* Infos. complémentaires */
+ uint32_t sh_addralign; /* Alignement de la section */
+ uint32_t sh_entsize; /* Eventuelle taille d'élément */
+
+} elf32_shdr;
+
+typedef struct _elf64_shdr
+{
+ uint32_t sh_name; /* Indice du nom de la section */
+ uint32_t sh_type; /* Type de section */
+ uint64_t sh_flags; /* Drapeaux pour la section */
+ uint64_t sh_addr; /* Adresse virtuelle à l'exec. */
+ uint64_t sh_offset; /* Position dans le fichier */
+ uint64_t sh_size; /* Taille en octets */
+ uint32_t sh_link; /* Lien vers une autre section */
+ uint32_t sh_info; /* Infos. complémentaires */
+ uint64_t sh_addralign; /* Alignement de la section */
+ uint64_t sh_entsize; /* Eventuelle taille d'élément */
+
+} elf64_shdr;
+
+typedef union _elf_shdr
+{
+ elf32_shdr shdr32; /* Version 32 bits */
+ elf64_shdr shdr64; /* Version 32 bits */
+
+} elf_shdr;
+
+
+#define ELF_SHDR(fmt, shdr, fld) (fmt->is_32b ? (shdr).shdr32.fld : (shdr).shdr64.fld)
+
+#define ELF_SIZEOF_SHDR(fmt) (fmt->is_32b ? sizeof(elf32_shdr) : sizeof(elf64_shdr))
+
+
+/* Valeurs possibles pour sh_type */
+
+#define SHT_NULL 0 /* Entrée non utilisée */
+#define SHT_PROGBITS 1 /* Données de programme */
+#define SHT_SYMTAB 2 /* Table des symboles */
+#define SHT_STRTAB 3 /* Table de chaînes de carac. */
+#define SHT_DYNAMIC 6 /* Info. de liaison dynamique */
+
+
+/* Valeurs possibles pour sh_flags */
+
+#define SHF_ALLOC (1 << 1) /* Copie en mémoire pdt l'exec.*/
+#define SHF_EXECINSTR (1 << 2) /* Section exécutable */
+#define SHF_STRINGS (1 << 5) /* Contient des chaînes ('\0') */
+
+
+
+/* ----------------------------- DONNEES POUR LE LINKER ----------------------------- */
+
+
+/* Entrées de la section dynamique (version 32 et 64 bits) */
+
+typedef struct _elf32_dyn
+{
+ int32_t d_tag; /* Type de l'entrée */
+
+ union
+ {
+ uint32_t d_val; /* Valeur entière */
+ uint32_t d_ptr; /* Valeur d'adresse */
+
+ } d_un;
+
+} elf32_dyn;
+
+typedef struct _elf64_dyn
+{
+ int64_t d_tag; /* Type de l'entrée */
+
+ union
+ {
+ uint64_t d_val; /* Valeur entière */
+ uint64_t d_ptr; /* Valeur d'adresse */
+
+ } d_un;
+
+} elf64_dyn;
+
+typedef union _elf_dyn
+{
+ elf32_dyn dyn32; /* Version 32 bits */
+ elf64_dyn dyn64; /* Version 32 bits */
+
+} elf_dyn;
+
+
+#define ELF_DYN(fmt, dyn, fld) (fmt->is_32b ? (dyn).dyn32.fld : (dyn).dyn64.fld)
+
+#define ELF_SIZEOF_DYN(fmt) (fmt->is_32b ? sizeof(elf32_dyn) : sizeof(elf64_dyn))
+
+
+
+/* Valeurs possibles pour d_tag */
+
+#define DT_SYMTAB 6 /* Table des symboles */
+#define DT_JMPREL 23 /* Relocalisations PLT */
+
+
+
+/* ---------------------------- SYMBOLES DE BINAIRES ELF ---------------------------- */
+
+
+/* Elément de la table des symboles */
+
+typedef struct _elf32_sym
+{
+ uint32_t st_name; /* Indice pour le nom */
+ uint32_t st_value; /* Valeur du symbole */
+ uint32_t st_size; /* Taille du symbole */
+ unsigned char st_info; /* Type et infos. du symbole */
+ unsigned char st_other; /* Visibilité du symbole */
+ uint16_t st_shndx; /* Indice de la section */
+
+} elf32_sym;
+
+typedef struct _elf64_sym
+{
+ uint32_t st_name; /* Indice pour le nom */
+ unsigned char st_info; /* Type et infos. du symbole */
+ unsigned char st_other; /* Visibilité du symbole */
+ uint16_t st_shndx; /* Indice de la section */
+ uint64_t st_value; /* Valeur du symbole */
+ uint64_t st_size; /* Taille du symbole */
+
+} elf64_sym;
+
+typedef union _elf_sym
+{
+ elf32_sym sym32; /* Version 32 bits */
+ elf64_sym sym64; /* Version 64 bits */
+
+} elf_sym;
+
+
+#define ELF_SYM(fmt, sb, fld) (fmt->is_32b ? sb.sym32.fld : sb.sym64.fld)
+
+#define ELF_ST_BIND(fmt, sym) (fmt->is_32b ? ELF32_ST_BIND(sym.sym32.st_info) : ELF64_ST_BIND(sym.sym64.st_info))
+#define ELF_ST_TYPE(fmt, sym) (fmt->is_32b ? ELF32_ST_TYPE(sym.sym32.st_info) : ELF64_ST_TYPE(sym.sym64.st_info))
+
+#define ELF_SIZEOF_SYM(fmt) (fmt->is_32b ? sizeof(elf32_sym) : sizeof(elf64_sym))
+
+
+/* Extraction des informations de st_info */
+
+#define ELF32_ST_BIND(val) (((unsigned char)(val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+
+#define ELF64_ST_BIND(val) ELF32_ST_BIND(val)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE(val)
+
+/* Valeurs pour le sous-champ ST_TYPE de st_info */
+
+#define STT_NOTYPE 0 /* Type de symbole non spécifié*/
+#define STT_OBJECT 1 /* Symbole, objet de données */
+#define STT_FUNC 2 /* Symbole, objet de code */
+
+
+
+/* ------------------------- INFORMATIONS DE RELOCALISATION ------------------------- */
+
+
+/* Entrée de la table de relocalisation */
+
+typedef struct _elf32_rel
+{
+ uint32_t r_offset; /* Adresse */
+ uint32_t r_info; /* Indice de type et symbole */
+
+} elf32_rel;
+
+typedef struct _elf64_rel
+{
+ uint64_t r_offset; /* Adresse */
+ uint64_t r_info; /* Indice de type et symbole */
+
+} elf64_rel;
+
+typedef union _elf_rel
+{
+ elf32_rel rel32; /* Version 32 bits */
+ elf64_rel rel64; /* Version 64 bits */
+
+} elf_rel;
+
+
+#define ELF_REL(fmt, rl, fld) (fmt->is_32b ? rl.rel32.fld : rl.rel64.fld)
+
+#define ELF_REL_SYM(fmt, rl) (fmt->is_32b ? ELF32_R_SYM(rl.rel32.r_info) : ELF64_R_SYM(rl.rel64.r_info))
+#define ELF_REL_TYPE(fmt, rl) (fmt->is_32b ? ELF32_R_TYPE(rl.rel32.r_info) : ELF64_R_TYPE(rl.rel64.r_info))
+
+#define ELF_SIZEOF_REL(fmt) (fmt->is_32b ? sizeof(elf32_rel) : sizeof(elf64_rel))
+
+
+/* Extraction des informations de r_info */
+
+#define ELF32_R_SYM(val) ((val) >> 8)
+#define ELF32_R_TYPE(val) ((val) & 0xff)
+
+#define ELF64_R_SYM(val) ((val) >> 32)
+#define ELF64_R_TYPE(val) ((val) & 0xffffffff)
+
+/* Type de relocalisation (x86) */
+
+#define R_386_NONE 0 /* Pas de relocalisation */
+#define R_386_JMP_SLOT 7 /* Entrée PLT */
+
+
+
+#endif /* _FORMAT_ELF_ELF_DEF_H */
diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c
index 1975709..82be74c 100644
--- a/src/format/elf/helper_x86.c
+++ b/src/format/elf/helper_x86.c
@@ -25,37 +25,117 @@
#include <malloc.h>
+#include <stdio.h>
#include <string.h>
#include "elf-int.h"
-#include "section.h"
+#include "../symbol.h"
#include "../../arch/immediate.h"
#include "../../arch/processor.h"
#include "../../arch/x86/instruction.h"
-#include "../../panel/log.h"
-#define _(str) (str)
-
+/* symbols.c : Récupère la désignation d'un symbole donné. */
+extern const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr *, off_t);
/* Décode les instructions liées à la relocalisation. */
-GArchInstruction **decode_elf_relocations(elf_format *, size_t *);
+GArchInstruction **decode_elf_relocations(GElfFormat *, const elf_shdr *, size_t *);
/* Déduit les adresses effectives des relocalisations. */
-void translate_elf_relocations(elf_format *, GArchInstruction **, size_t);
+void translate_elf_relocations(GElfFormat *, GArchInstruction **, size_t);
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* dyn_start = début des informations dynamiques associées. *
-* dyn_size = taille de la zone associée. *
-* str_start = début de la zone de chaîne de caractères. *
-* str_size = taille de la zone de chaînes de caractères. *
+* Paramètres : format = description de l'exécutable à compléter. *
+* relxxx = section .rel.xxx trouvée (zone à traiter). *
+* dynsym = section .dynsym trouvée (info. dynamiques). *
+* dynstr = section .dynstr trouvée (chaînes de caractères). *
+* *
+* Description : Charge en mémoire la liste des symboles dynamiques. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_elf_x86_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr)
+{
+ bool result; /* Bilan à retourner */
+ off_t rel_start; /* Début de la zone à traiter */
+ off_t rel_size; /* Taille de cette même zone */
+ off_t iter; /* Boucle de parcours */
+ elf_rel reloc; /* Infos de relocalisation */
+ off_t index; /* Indice de la portion visée */
+ const char *name; /* Nom du symbole trouvé */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+
+
+
+ result = true;
+
+
+
+ get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL);
+
+
+ printf("rel :: %d -> %d\n", rel_start, rel_start + rel_size);
+
+
+
+ for (iter = rel_start; iter < (rel_start + rel_size); )
+ {
+ result = read_elf_relocation(format, &iter, &reloc);
+ if (!result) break;
+
+ switch (ELF_REL_TYPE(format, reloc))
+ {
+ case R_386_NONE:
+ break;
+
+ case R_386_JMP_SLOT:
+
+ index = ELF_REL_SYM(format, reloc);
+ name = get_elf_symbol_name(format, dynsym, dynstr, index);
+
+
+ printf("got a jump ! >> %d - %s\n", index, name);
+
+
+ if (name == NULL)
+ {
+ /* FIXME */
+ name = "unknown";
+ }
+
+ symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_REL(format, reloc, r_offset));
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+ break;
+
+ default:
+ printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc));
+ break;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* plt = section .plt trouvée (points d'entrées dynamiques). *
* *
* Description : Déduit les adresses effectives des appels externes. *
* *
@@ -65,13 +145,13 @@ void translate_elf_relocations(elf_format *, GArchInstruction **, size_t);
* *
******************************************************************************/
-bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start, off_t dyn_size, off_t str_start, off_t str_size)
+bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt)
{
GArchInstruction **instructions; /* Instructions décodées */
size_t count; /* Quantité d'instructions */
size_t i; /* Boucle de parcours */
- instructions = decode_elf_relocations(format, &count);
+ instructions = decode_elf_relocations(format, plt, &count);
translate_elf_relocations(format, instructions, count);
@@ -89,6 +169,7 @@ bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start,
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* plt = section .plt trouvée (points d'entrées dynamiques). *
* count = nombre d'instructions lues. [OUT] *
* *
* Description : Décode les instructions liées à la relocalisation. *
@@ -99,15 +180,12 @@ bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start,
* *
******************************************************************************/
-GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)
+GArchInstruction **decode_elf_relocations(GElfFormat *format, const elf_shdr *plt, size_t *count)
{
GArchInstruction **result; /* Liste à renvoyer */
off_t plt_start; /* Début de section */
off_t plt_size; /* Taille de section */
vmpa_t plt_address; /* Adresse virtuelle associée */
- Elf_Shdr *sections; /* Groupe de sections trouvées */
- size_t sec_count; /* Quantité de données */
- size_t i; /* Boucle de parcours */
GArchProcessor *proc; /* Processeur pour le décodage */
off_t pos; /* Tête de lecture */
vmpa_t address; /* Adresse virtuelle courante */
@@ -116,26 +194,7 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)
result = NULL;
*count = 0;
- if (!find_elf_section_content_by_name(format, ".plt", &plt_start, &plt_size, &plt_address))
- {
- log_simple_message(LMT_BAD_BINARY, _("No .plt section found ! Trying to guess it..."));
-
- /* FIXME : 64 bits ! */
-
- find_elf_section_by_type(format, SHT_PROGBITS, &sections, &sec_count);
-
- for (i = 0; i < sec_count; i++)
- if (ELF_SHDR(format, &sections[i], sh_entsize) > 0)
- {
- get_elf_section_content(format, &sections[i], &plt_start, &plt_size, &plt_address);
- break;
- }
-
- free(sections);
-
- if (i == sec_count) return NULL;
-
- }
+ get_elf_section_content(format, plt, &plt_start, &plt_size, &plt_address);
proc = get_arch_processor_for_type(APT_386);
@@ -143,7 +202,7 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)
{
address = plt_address + pos;
- instr = g_arch_processor_decode_instruction(proc, &EXE_FORMAT(format)->content[plt_start],
+ instr = g_arch_processor_decode_instruction(proc, &G_BIN_FORMAT(format)->content[plt_start],
&pos, plt_size, 0/* FIXME*/, address);
result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *));
@@ -170,18 +229,21 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count)
* *
******************************************************************************/
-void translate_elf_relocations(elf_format *format, GArchInstruction **instructions, size_t count)
+void translate_elf_relocations(GElfFormat *format, GArchInstruction **instructions, size_t count)
{
size_t i; /* Boucle de parcours #1 */
X86Opcodes opcode_n0; /* Opcode de l'instruction n */
X86Opcodes opcode_n1; /* Opcode de l'instruction n+1 */
X86Opcodes opcode_n2; /* Opcode de l'instruction n+2 */
- GArchOperand *operand; /* Valeur du saut */
+ const GArchOperand *operand; /* Valeur du saut */
vmpa_t address; /* Adresse virtuelle finale */
+ GBinSymbol **symbols; /* Liste des symboles existants*/
+ size_t symbols_count; /* Taille de cette liste */
size_t j; /* Boucle de parcours #2 */
size_t new_len; /* Taille du nouveau nom */
char *new_name; /* Nom avec suffixe @plt */
GBinRoutine *routine; /* Nouvelle routine déduite */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
for (i = 0; (i + 2) < count; )
{
@@ -195,31 +257,39 @@ void translate_elf_relocations(elf_format *format, GArchInstruction **instructio
{
operand = g_arch_instruction_get_operand(instructions[i], 0);
-
g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address);
if (g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address))
- for (j = 0; j < format->rel_count; j++)
- if (format->relocations[j].address == address)
+ {
+ symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &symbols_count);
+
+ for (j = 0; j < symbols_count; j++)
+ if (g_binary_symbol_get_address(symbols[j]) == address)
{
- new_len = strlen(format->relocations[j].name) + 4 + 1;
+ new_len = strlen(g_binary_symbol_to_string(symbols[j])) + 4 + 1;
new_name = calloc(new_len, sizeof(char));
- snprintf(new_name, new_len, "%s@plt", format->relocations[j].name);
+ snprintf(new_name, new_len, "%s@plt", g_binary_symbol_to_string(symbols[j]));
g_arch_instruction_get_location(instructions[i], NULL, NULL, &address);
+ /* Routine */
+
routine = g_binary_routine_new();
g_binary_routine_set_name(routine, new_name);
g_binary_routine_set_address(routine, address);
- format->routines = (GBinRoutine **)realloc(format->routines,
- ++format->routines_count * sizeof(GBinRoutine *));
+ g_binary_format_add_routine(G_BIN_FORMAT(format), routine);
+
+ /* Symbole uniquement */
- format->routines[format->routines_count - 1] = routine;
+ symbol = g_binary_symbol_new(STP_FUNCTION, new_name, address);
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
}
+ }
+
i += 3;
}
diff --git a/src/format/elf/helper_x86.h b/src/format/elf/helper_x86.h
index 957c8c3..eae7c8b 100644
--- a/src/format/elf/helper_x86.h
+++ b/src/format/elf/helper_x86.h
@@ -25,16 +25,15 @@
#define _FORMAT_ELF_HELPER_X86_H
-#include <stdbool.h>
-#include <sys/types.h>
+#include "section.h"
-#include "e_elf.h"
-
+/* Charge en mémoire la liste des symboles dynamiques. */
+bool load_elf_x86_relocated_symbols(GElfFormat *, const elf_shdr *, const elf_shdr *, const elf_shdr *);
/* Déduit les adresses effectives des appels externes. */
-bool g_elf_format_find_x86_dynamic_symbols(elf_format *, off_t, off_t, off_t, off_t);
+bool find_elf_x86_dynamic_symbols(GElfFormat *, const elf_shdr *);
diff --git a/src/format/elf/section.c b/src/format/elf/section.c
index c619293..940acdf 100644
--- a/src/format/elf/section.c
+++ b/src/format/elf/section.c
@@ -34,9 +34,11 @@
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
+* Paramètres : format = description de l'exécutable à consulter. *
+* index = indice de la section recherchée. *
+* section = ensemble d'informations à faire remonter. [OUT] *
* *
-* Description : Charge en mémoire la liste humaine des sections. *
+* Description : Recherche une section donnée au sein de binaire par indice. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -44,25 +46,15 @@
* *
******************************************************************************/
-bool read_elf_section_names(elf_format *format)
+bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shdr *section)
{
- off_t offset; /* Position des données */
- Elf32_Shdr section; /* Section visée */
-
- offset = format->header.e_shoff + format->header.e_shentsize * format->header.e_shstrndx;
-
- if ((offset + sizeof(Elf32_Shdr)) > EXE_FORMAT(format)->length) return false;
-
- memcpy(&section, &EXE_FORMAT(format)->content[offset], sizeof(Elf32_Shdr));
-
- if ((section.sh_offset + section.sh_size) > EXE_FORMAT(format)->length) return false;
+ off_t offset; /* Emplacement à venir lire */
- format->sec_names = (char *)calloc(section.sh_size + 1, sizeof(char));
- format->sec_size = section.sh_size;
+ if (index >= format->header.e_shnum) return false;
- memcpy(format->sec_names, &EXE_FORMAT(format)->content[section.sh_offset], section.sh_size);
+ offset = ELF_OFF(format, format->header.e_shoff) + format->header.e_shentsize * index;
- return true;
+ return read_elf_section_header(format, offset, section);
}
@@ -81,13 +73,15 @@ bool read_elf_section_names(elf_format *format)
* *
******************************************************************************/
-bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Shdr *section)
+bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_shdr *section)
{
- bool result; /* Bilan à retourner */
+ bool result; /* Bilan à faire remonter */
+ elf_shdr strings; /* Section des descriptions */
uint16_t i; /* Boucle de parcours */
+ const char *secname; /* Nom d'une section analysée */
- /* Si on perd notre temps... */
- if (format->sec_size == 0) return false;
+ if (!find_elf_section_by_index(format, format->header.e_shstrndx, &strings))
+ return false;
result = false;
@@ -95,7 +89,10 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh
{
find_elf_section_by_index(format, i, section);
- result = (strcmp(name, &format->sec_names[ELF_SHDR(format, section, sh_name)]) == 0);
+ secname = extract_name_from_elf_string_section(format, &strings,
+ ELF_SHDR(format, *section, sh_name));
+
+ result = (strcmp(name, secname) == 0);
}
@@ -106,10 +103,9 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* type = type de la section recherchée. *
-* sections = tableau d'informations à faire remonter. [OUT] *
-* count = nombre d'éléments présents dans le tableau. [OUT] *
+* Paramètres : format = description de l'exécutable à consulter. *
+* addr = adresse de la section recherchée. (32 bits) *
+* section = ensemble d'informations à faire remonter. [OUT] *
* *
* Description : Recherche une section donnée au sein de binaire par type. *
* *
@@ -119,38 +115,34 @@ bool find_elf_section_by_name(const elf_format *format, const char *name, Elf_Sh
* *
******************************************************************************/
-bool find_elf_section_by_type(const elf_format *format, uint16_t type, Elf_Shdr **sections, size_t *count)
+bool find_elf_section_by_virtual_address(const GElfFormat *format, uint32_t addr, elf_shdr *section)
{
+ bool result; /* Bilan à faire remonter */
uint16_t i; /* Boucle de parcours */
- Elf_Shdr section; /* Section à analyser */
- *sections = NULL;
- *count = 0;
+ result = false;
- for (i = 0; i < format->header.e_shnum; i++)
+ for (i = 0; i < format->header.e_shnum && !result; i++)
{
- find_elf_section_by_index(format, i, &section);
+ find_elf_section_by_index(format, i, section);
- if (type == ELF_SHDR(format, &section, sh_type))
- {
- *sections = (Elf_Shdr *)realloc(*sections, ++(*count) * sizeof(Elf_Shdr));
- (*sections)[*count - 1] = section;
- }
+ result = (addr == ELF_SHDR(format, *section, sh_addr));
}
- return (*count > 0);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à consulter. *
-* index = indice de la section recherchée. *
-* section = ensemble d'informations à faire remonter. [OUT] *
+* Paramètres : format = description de l'exécutable à consulter. *
+* type = type de la section recherchée. *
+* sections = tableau d'informations à faire remonter. [OUT] *
+* count = nombre d'éléments présents dans le tableau. [OUT] *
* *
-* Description : Recherche une section donnée au sein de binaire par indice. *
+* Description : Recherche une section donnée au sein de binaire par type. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -158,17 +150,27 @@ bool find_elf_section_by_type(const elf_format *format, uint16_t type, Elf_Shdr
* *
******************************************************************************/
-bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shdr *section)
+bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr **sections, size_t *count)
{
- off_t offset; /* Emplacement à venir lire */
+ uint16_t i; /* Boucle de parcours */
+ elf_shdr section; /* Section à analyser */
- if (index >= format->header.e_shnum) return false;
+ *sections = NULL;
+ *count = 0;
- offset = format->header.e_shoff + format->header.e_shentsize * index;
+ for (i = 0; i < format->header.e_shnum; i++)
+ {
+ find_elf_section_by_index(format, i, &section);
- memcpy(section, &EXE_FORMAT(format)->content[offset], ELF_SIZEOF_SHDR(format));
+ if (type == ELF_SHDR(format, section, sh_type))
+ {
+ *sections = (elf_shdr *)realloc(*sections, ++(*count) * sizeof(elf_shdr));
+ (*sections)[*count - 1] = section;
+ }
+
+ }
- return true;
+ return (*count > 0);
}
@@ -179,7 +181,7 @@ bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shd
* section = section à consulter. *
* offset = position de la section trouvée. [OUT] *
* size = taille de la section trouvée. [OUT] *
-* voffset = adresse virtuelle de la section trouvée. [OUT] *
+* addr = adresse virtuelle de la section trouvée. [OUT] *
* *
* Description : Fournit les adresses et taille contenues dans une section. *
* *
@@ -189,13 +191,13 @@ bool find_elf_section_by_index(const elf_format *format, uint16_t index, Elf_Shd
* *
******************************************************************************/
-void get_elf_section_content(const elf_format *format, const Elf_Shdr *section, off_t *offset, off_t *size, uint64_t *voffset)
+void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, off_t *offset, off_t *size, vmpa_t *addr)
{
- *offset = ELF_SHDR(format, section, sh_offset);
- *size = ELF_SHDR(format, section, sh_size);
+ *offset = ELF_SHDR(format, *section, sh_offset);
+ *size = ELF_SHDR(format, *section, sh_size);
- if (voffset != NULL)
- *voffset = ELF_SHDR(format, section, sh_addr);
+ if (addr != NULL)
+ *addr = ELF_SHDR(format, *section, sh_addr);
}
@@ -206,7 +208,7 @@ void get_elf_section_content(const elf_format *format, const Elf_Shdr *section,
* name = nom de la section recherchée. *
* offset = position de la section trouvée. [OUT] *
* size = taille de la section trouvée. [OUT] *
-* voffset = adresse virtuelle de la section trouvée. [OUT] *
+* address = adresse virtuelle de la section trouvée. [OUT] *
* *
* Description : Recherche une zone donnée au sein de binaire par nom. *
* *
@@ -216,15 +218,15 @@ void get_elf_section_content(const elf_format *format, const Elf_Shdr *section,
* *
******************************************************************************/
-bool find_elf_section_content_by_name(const elf_format *format, const char *name, off_t *offset, off_t *size, uint64_t *voffset)
+bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, off_t *offset, off_t *size, vmpa_t *address)
{
bool result; /* Bilan à retourner */
- Elf_Shdr section; /* Section trouvée ou non */
+ elf_shdr section; /* Section trouvée ou non */
result = find_elf_section_by_name(format, name, &section);
if (result)
- get_elf_section_content(format, &section, offset, size, voffset);
+ get_elf_section_content(format, &section, offset, size, address);
return result;
@@ -234,28 +236,39 @@ bool find_elf_section_content_by_name(const elf_format *format, const char *name
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
-* index = indice de la section recherchée. *
-* offset = position de la section trouvée. [OUT] *
-* size = taille de la section trouvée. [OUT] *
-* voffset = adresse virtuelle de la section trouvée. [OUT] *
+* section = section contenant des chaînes terminées par '\0'. *
+* index = indice du premier caractères à cerner. *
* *
-* Description : Recherche une zone donnée au sein de binaire par indice. *
+* Description : Identifie une chaîne de caractères dans une section adéquate.*
* *
-* Retour : Bilan de l'opération. *
+* Retour : Pointeur vers la chaîne recherchée ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool find_elf_section_content_by_index(const elf_format *format, uint16_t index, off_t *offset, off_t *size, uint64_t *voffset)
+const char *extract_name_from_elf_string_section(const GElfFormat *format, const elf_shdr *section, uint16_t index)
{
- bool result; /* Bilan à retourner */
- Elf_Shdr section; /* Section trouvée ou non */
+ const char *result; /* Nom trouvé à renvoyer */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ off_t last; /* Dernier '\0' possible */
+ off_t pos; /* Point de lecture */
- result = find_elf_section_by_index(format, index, &section);
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
- if (result)
- get_elf_section_content(format, &section, offset, size, voffset);
+ last = ELF_SHDR(format, *section, sh_offset) + ELF_SHDR(format, *section, sh_size);
+
+ pos = ELF_SHDR(format, *section, sh_offset) + index;
+
+ if ((pos + 1) >= MIN(length, last))
+ return NULL;
+
+ result = (const char *)&content[pos];
+
+ if ((pos + strlen(result)) > last)
+ return NULL;
return result;
diff --git a/src/format/elf/section.h b/src/format/elf/section.h
index 6bc3a75..944fd7c 100644
--- a/src/format/elf/section.h
+++ b/src/format/elf/section.h
@@ -25,47 +25,31 @@
#define _FORMAT_ELF_SECTION_H
-#include <elf.h>
+#include "elf.h"
+#include "elf_def.h"
-#include "e_elf.h"
-
-/* En-tête de section ELF */
-typedef union _Elf_Shdr
-{
- Elf32_Shdr section32; /* Version 32 bits */
- Elf64_Shdr section64; /* Version 64 bits */
-
-} Elf_Shdr;
-
-
-#define ELF_SIZEOF_SHDR(fmt) (fmt->is_32b ? sizeof(Elf32_Shdr) : sizeof(Elf64_Shdr))
-
-#define ELF_SHDR(fmt, shdr, fld) (fmt->is_32b ? (shdr)->section32.fld : (shdr)->section64.fld)
-
-
-
-/* Charge en mémoire la liste humaine des sections. */
-bool read_elf_section_names(elf_format *);
+/* Recherche une section donnée au sein de binaire par indice. */
+bool find_elf_section_by_index(const GElfFormat *, uint16_t, elf_shdr *);
/* Recherche une section donnée au sein de binaire par nom. */
-bool find_elf_section_by_name(const elf_format *, const char *, Elf_Shdr *);
+bool find_elf_section_by_name(const GElfFormat *, const char *, elf_shdr *);
/* Recherche une section donnée au sein de binaire par type. */
-bool find_elf_section_by_type(const elf_format *, uint16_t, Elf_Shdr **, size_t *);
+bool find_elf_section_by_virtual_address(const GElfFormat *, uint32_t, elf_shdr *);
-/* Recherche une section donnée au sein de binaire par indice. */
-bool find_elf_section_by_index(const elf_format *, uint16_t, Elf_Shdr *);
+/* Recherche une section donnée au sein de binaire par type. */
+bool find_elf_sections_by_type(const GElfFormat *, uint32_t, elf_shdr **, size_t *);
/* Fournit les adresses et taille contenues dans une section. */
-void get_elf_section_content(const elf_format *, const Elf_Shdr *, off_t *, off_t *, uint64_t *);
+void get_elf_section_content(const GElfFormat *, const elf_shdr *, off_t *, off_t *, vmpa_t *);
/* Recherche une zone donnée au sein de binaire par nom. */
-bool find_elf_section_content_by_name(const elf_format *, const char *, off_t *, off_t *, uint64_t *);
+bool find_elf_section_content_by_name(const GElfFormat *, const char *, off_t *, off_t *, vmpa_t *);
-/* Recherche une zone donnée au sein de binaire par indice. */
-bool find_elf_section_content_by_index(const elf_format *, uint16_t, off_t *, off_t *, uint64_t *);
+/* Identifie une chaîne de caractères dans une section adéquate. */
+const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, uint16_t);
diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c
index 2bcd911..157d3b5 100644
--- a/src/format/elf/strings.c
+++ b/src/format/elf/strings.c
@@ -27,6 +27,7 @@
#include <ctype.h>
#include <malloc.h>
#include <string.h>
+#include <sys/param.h>
#include "elf-int.h"
@@ -35,7 +36,7 @@
/* Enregistre toutes les chaînes de caractères trouvées. */
-bool parse_elf_string_data(elf_format *, const off_t, const off_t, uint64_t);
+bool parse_elf_string_data(GElfFormat *, off_t, off_t, vmpa_t);
@@ -51,63 +52,81 @@ bool parse_elf_string_data(elf_format *, const off_t, const off_t, uint64_t);
* *
******************************************************************************/
-bool find_all_elf_strings(elf_format *format)
+bool find_all_elf_strings(GElfFormat *format)
{
+ bool got_string; /* Indique un remplissage */
off_t str_start; /* Début de section */
off_t str_size; /* Taille de section */
- uint64_t str_vaddr; /* Adresse virtuelle associée */
- Elf_Shdr *sections; /* Groupe de sections trouvées */
+ vmpa_t str_addr; /* Adresse virtuelle associée */
+ elf_shdr *sections; /* Groupe de sections trouvées */
size_t count; /* Quantité de données */
- size_t i; /* Boucle de parcours */
- off_t offset; /* Position physique */
- Elf_Phdr phdr; /* En-tête de programme ELF */
+ size_t i; /* Boucle de parcours #1 */
+ off_t length; /* Taille totale du contenu */
+ off_t iter; /* Boucle de parcours #2 */
+ elf_phdr phdr; /* En-tête de programme ELF */
+
+ got_string = false;
/* Données en lecture seule */
- if (find_elf_section_content_by_name(format, ".rodata", &str_start, &str_size, &str_vaddr))
- parse_elf_string_data(format, str_start, str_size, str_vaddr);
+ if (find_elf_section_content_by_name(format, ".rodata", &str_start, &str_size, &str_addr))
+ got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);
else
{
- find_elf_section_by_type(format, SHT_PROGBITS, &sections, &count);
+ if (find_elf_sections_by_type(format, SHT_PROGBITS, &sections, &count))
+ {
+ for (i = 0; i < count; i++)
+ if (ELF_SHDR(format, sections[i], sh_flags) == SHF_ALLOC
+ || (ELF_SHDR(format, sections[i], sh_flags) & SHF_STRINGS))
+ {
+ get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_addr);
+ got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);
+ }
- for (i = 0; i < count; i++)
- if (ELF_SHDR(format, &sections[i], sh_flags) == SHF_ALLOC
- || (ELF_SHDR(format, &sections[i], sh_flags) & SHF_STRINGS))
- {
- get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_vaddr);
- parse_elf_string_data(format, str_start, str_size, str_vaddr);
- }
+ free(sections);
+
+ }
}
/* Chaîne de caractères déclarées */
- find_elf_section_by_type(format, SHT_STRTAB, &sections, &count);
-
- for (i = 0; i < count; i++)
+ if (find_elf_sections_by_type(format, SHT_STRTAB, &sections, &count))
{
- get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_vaddr);
- parse_elf_string_data(format, str_start, str_size, str_vaddr);
+ for (i = 0; i < count; i++)
+ {
+ get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_addr);
+ got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);
+ }
+
+ free(sections);
+
}
/* En désespoir de cause, on se rabbat sur les parties de programme directement */
- if (format->str_count == 0 && format->header.e_shnum == 0 /* FIXME : cond. à garder ? */)
- for (i = 0; i < format->header.e_phnum; i++)
- {
- offset = format->header.e_phoff + format->header.e_phentsize * i;
- if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue;
+ if (!got_string)
+ {
+ length = G_BIN_FORMAT(format)->length;
+ length = MIN(length, format->header.e_phnum * ELF_SIZEOF_PHDR(format));
- memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize);
+ for (iter = ELF_OFF(format, format->header.e_phoff); iter < length; )
+ {
+ if (!read_elf_program_header(format, &iter, &phdr))
+ continue;
- if (ELF_PHDR(format, &phdr, p_flags) & PF_R && !(ELF_PHDR(format, &phdr, p_flags) & PF_X))
- parse_elf_string_data(format, ELF_PHDR(format, &phdr, p_offset),
- ELF_PHDR(format, &phdr, p_filesz),
- ELF_PHDR(format, &phdr, p_vaddr));
+ if (ELF_PHDR(format, phdr, p_flags) & PF_R
+ && !(ELF_PHDR(format, phdr, p_flags) & PF_X))
+ parse_elf_string_data(format,
+ ELF_PHDR(format, phdr, p_offset),
+ ELF_PHDR(format, phdr, p_filesz),
+ ELF_PHDR(format, phdr, p_vaddr));
}
+ }
+
return true;
}
@@ -115,77 +134,49 @@ bool find_all_elf_strings(elf_format *format)
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* start = début de la zone à parcourir. *
-* size = taille de l'espace à parcourir. *
-* vaddress = adresse virtuelle du début de la section. *
+* Paramètres : format = description de l'exécutable à compléter. *
+* start = début de la zone à parcourir. *
+* size = taille de l'espace à parcourir. *
+* address = adresse virtuelle du début de la section. *
* *
* Description : Enregistre toutes les chaînes de caractères trouvées. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : true si des chaînes ont été ajoutées, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool parse_elf_string_data(elf_format *format, const off_t start, const off_t size, uint64_t vaddress)
+bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t address)
{
+ bool result; /* Bilan à faire remonter */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
off_t i; /* Boucle de parcours */
off_t end; /* Position de fin de chaîne */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
- if (vaddress == 0) return false;
-
- for (i = start; i < (start + size); i++)
- if (isprint(EXE_FORMAT(format)->content[i]))
- {
- for (end = i + 1; end < (start + size); end++)
- if (!isprint(EXE_FORMAT(format)->content[end])) break;
-
- format->strings = (elf_string *)realloc(format->strings, ++format->str_count * sizeof(elf_string));
-
- format->strings[format->str_count - 1].value = strndup((const char *)&EXE_FORMAT(format)->content[i], end - i);
- format->strings[format->str_count - 1].len = end - i;
- format->strings[format->str_count - 1].address = vaddress + i - start;
-
- i = end;
-
- }
+ if (address == 0) return false;
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* label = étiquette allouée du symbole si trouvé. [OUT] *
-* vaddres = adresse à cibler, puis décallage final. [OUT] *
-* *
-* Description : Recherche une chaîne correspondant à une adresse. *
-* *
-* Retour : true si l'opération a été un succès, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ result = false;
-bool resolve_elf_strings(const elf_format *format, char **label, vmpa_t *address)
-{
- bool result; /* Bilan de recherche remonté */
- size_t real_start; /* Début de chaîne effective */
- size_t i; /* Boucle de parcours */
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
- result = false;
+ length = MIN(length, start + size);
- for (i = 0; i < format->str_count && !result; i++)
- if (format->strings[i].address <= *address
- && *address < (format->strings[i].address + format->strings[i].len))
+ for (i = start; i < length; i++)
+ if (isprint(content[i]))
{
- real_start = *address - format->strings[i].address;
- *label = strndup(&format->strings[i].value[real_start],
- format->strings[i].len - real_start);
+ for (end = i + 1; end < length; end++)
+ if (!isprint(content[end])) break;
+
+ symbol = g_binary_symbol_new(STP_STRING, NULL, address + i - start);
+ g_binary_symbol_set_alt_name(symbol, strndup((const char *)&content[i], end - i));
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+ i = end;
result = true;
}
diff --git a/src/format/elf/strings.h b/src/format/elf/strings.h
index f9b17ac..e52d054 100644
--- a/src/format/elf/strings.h
+++ b/src/format/elf/strings.h
@@ -25,15 +25,12 @@
#define _FORMAT_ELF_STRINGS_H
-#include "e_elf.h"
+#include "elf.h"
/*Charge en mémoire toutes les chaînes trouvées. */
-bool find_all_elf_strings(elf_format *);
-
-/* Recherche une chaîne correspondant à une adresse. */
-bool resolve_elf_strings(const elf_format *, char **, vmpa_t *);
+bool find_all_elf_strings(GElfFormat *);
diff --git a/src/format/elf/symbol.c b/src/format/elf/symbol.c
deleted file mode 100644
index 35943e9..0000000
--- a/src/format/elf/symbol.c
+++ /dev/null
@@ -1,492 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * symbol.c - gestion des symboles d'un ELF
- *
- * Copyright (C) 2008 Cyrille Bagard
- *
- * This file is part of OpenIDA.
- *
- * 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 "symbol.h"
-
-
-#include <malloc.h>
-#include <elf.h>
-#include <stdio.h>
-#include <string.h>
-
-
-#include "elf-int.h"
-#include "helper_mips.h"
-#include "section.h"
-
-
-
-
-
-/* -------------------------- DETAIL DES SYMBOLES EXTERNES -------------------------- */
-
-
-/* Charge en mémoire la liste des symboles dynamiques. */
-bool load_elf_relocation_table(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *);
-
-/* Récupère les informations d'un symbole dynamique donné. */
-char *get_elf_dynamic_symbol_info(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *);
-
-
-
-
-/* Charge en mémoire la liste humaine des symboles (32 bits). */
-bool load_elf_symbol_table_32(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *);
-
-/* Charge en mémoire la liste humaine des symboles (64 bits). */
-bool load_elf_symbol_table_64(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *);
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* *
-* Description : Charge en mémoire la liste humaine des symboles. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_elf_symbols(elf_format *format)
-{
- bool result; /* Bilan à retourner */
- Elf_Shdr *sections; /* Groupe de sections trouvées */
- size_t count; /* Quantité de données */
- size_t i; /* Boucle de parcours */
- Elf_Shdr section; /* Section trouvée ou non */
- off_t sym_start; /* Début de section */
- off_t sym_size; /* Taille de section */
- off_t str_start; /* Début de section */
- off_t str_size; /* Taille de section */
- off_t rel_start; /* Début de section */
- off_t rel_size; /* Taille de section */
-
-
- bool test; /* Bilan d'une recherche */
-
- off_t dyn_start; /* Début de section */
- off_t dyn_size; /* Taille de section */
-
-
-
- result = true;
-
-
- /* Table des symboles */
-
- find_elf_section_by_type(format, SHT_SYMTAB, &sections, &count);
-
- for (i = 0; i < count; i++)
- {
- /* Section ".symtab" */
-
- get_elf_section_content(format, &sections[i], &sym_start, &sym_size, NULL);
-
- /* Section ".strtab" */
-
- result &= find_elf_section_by_index(format, ELF_SHDR(format, &sections[i], sh_link), &section);
-
- get_elf_section_content(format, &section, &str_start, &str_size, NULL);
-
- if (result)
- {
-
-
-
- result = load_elf_symbol_table_32(format, &sym_start, &sym_size, &str_start, &str_size);
-
-
-
- }
-
- }
-
- /* Relocalisations */
-
-
-
- /* TODO : fixme ! */
-
- find_elf_section_by_type(format, SHT_REL, &sections, &count);
-
- for (i = 0; i < count; i++)
- {
- /* Section ".rel.xxx" */
-
- get_elf_section_content(format, &sections[i], &rel_start, &rel_size, NULL);
-
- /* Section ".dynsym" */
-
- result &= find_elf_section_by_index(format, ELF_SHDR(format, &sections[i], sh_link), &section);
-
- get_elf_section_content(format, &section, &dyn_start, &dyn_size, NULL);
-
- /* Section ".dynstr" */
-
- result &= find_elf_section_by_index(format, ELF_SHDR(format, &section, sh_link), &section);
-
- get_elf_section_content(format, &section, &str_start, &str_size, NULL);
-
- /* Récupération (première partie) */
- if (result)
- {
-
- result = load_elf_relocation_table(format, &rel_start, &rel_size, &dyn_start, &dyn_size, &str_start, &str_size);
-
-
- }
-
- }
-
- free(sections);
-
- /* TODO : fixme ! */
-
-
-
-
-
- /* Liaison dynamique (si elle existe) */
-
- test = find_elf_section_by_name(format, ".dynsym", &section);
-
- if (!test)
- {
- test = find_elf_section_by_type(format, SHT_HASH, &sections, &count);
-
- if (test)
- test = find_elf_section_by_index(format, ELF_SHDR(format, &sections[0], sh_link), &section);
-
- }
-
- if (test)
- {
- get_elf_section_content(format, &section, &dyn_start, &dyn_size, NULL);
-
- result &= find_elf_section_by_index(format, ELF_SHDR(format, &section, sh_link), &section);
-
- }
-
- if (result)
- {
- get_elf_section_content(format, &section, &str_start, &str_size, NULL);
-
- switch (get_elf_target_machine(format))
- {
- case FTM_MIPS:
- result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size);
- break;
-
- case FTM_386:
- result = g_elf_format_find_x86_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size);
- break;
-
- default:
- break;
-
- }
-
- }
-
- return result;
-
-}
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* sym_start = début de la zone à traiter. *
-* sym_size = taille de la zone à traiter. *
-* str_start = début de la zone de chaîne de caractères. *
-* str_size = taille de la zone de chaînes de caractères. *
-* *
-* Description : Charge en mémoire la liste humaine des symboles (32 bits). *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const off_t *sym_size, const off_t *str_start, const off_t *str_size)
-{
- off_t iter; /* Boucle de parcours */
- Elf32_Sym symbol; /* Symbole ELF lu */
- GBinRoutine *routine; /* Nouvelle routine trouvée */
-
- if (*sym_size % sizeof(Elf32_Sym) != 0) return false;
-
- for (iter = *sym_start; iter < (*sym_start + *sym_size); iter += sizeof(Elf32_Sym))
- {
- memcpy(&symbol, &EXE_FORMAT(format)->content[iter], sizeof(Elf32_Sym));
-
- if (!(ELF32_ST_TYPE(symbol.st_info) == STT_FUNC)) continue;
-
- if (symbol.st_value == 0) continue;
-
- /* Sécurité anti-débordements */
- if (symbol.st_name >= *str_size) continue;
-
- /* Si le symbole possède un nom... */
- if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0)
- {
- routine = g_binary_routine_new();
-
- g_binary_routine_set_name(routine, strdup(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]));
- g_binary_routine_set_address(routine, symbol.st_value);
- g_binary_routine_set_size(routine, symbol.st_size);
-
- format->routines = (GBinRoutine **)realloc(format->routines,
- ++format->routines_count * sizeof(GBinRoutine *));
-
- format->routines[format->routines_count - 1] = routine;
-
- }
-
- }
-
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* sym_start = début de la zone à traiter. *
-* sym_size = taille de la zone à traiter. *
-* str_start = début de la zone de chaîne de caractères. *
-* str_size = taille de la zone de chaînes de caractères. *
-* *
-* Description : Charge en mémoire la liste humaine des symboles (64 bits). *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_elf_symbol_table_64(elf_format *format, const off_t *sym_start, const off_t *sym_size, const off_t *str_start, const off_t *str_size)
-{
- off_t iter; /* Boucle de parcours */
- Elf64_Sym symbol; /* Symbole ELF lu */
-
- if (*sym_size % sizeof(Elf64_Sym) != 0) return false;
-
- for (iter = *sym_start; iter < (*sym_start + *sym_size); iter += sizeof(Elf64_Sym))
- {
- memcpy(&symbol, &EXE_FORMAT(format)->content[iter], sizeof(Elf64_Sym));
-
- if (!(ELF64_ST_TYPE(symbol.st_info) == STT_FUNC
- || (ELF64_ST_TYPE(symbol.st_info) == STT_NOTYPE
- && ELF64_ST_BIND(symbol.st_info) == STB_GLOBAL))) continue;
-
- if (symbol.st_value == 0) continue;
-
- /* Sécurité anti-débordements */
- if (symbol.st_name >= *str_size) continue;
-
- /* Si le symbole possède un nom... */
- if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0)
- {
- format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol));
-
- format->symbols[format->sym_count - 1].name = &EXE_FORMAT(format)->content[*str_start + symbol.st_name];
- format->symbols[format->sym_count - 1].address = symbol.st_value;
-
- }
-
- }
-
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* comments = liste des commentaires à insérer. [OUT] *
-* offsets = liste des indices des commentaires. [OUT] *
-* count = taille des listes construites. [OUT] *
-* *
-* Description : Récupère tous les commentaires à insérer dans le code. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void get_elf_symbol_comments(const elf_format *format, char ***comments, uint64_t **offsets, size_t *count)
-{
- size_t i; /* Boucle de parcours */
- size_t len; /* Longueur d'une désignation */
-
- if (format->sym_count > 0)
- {
- *comments = (char **)calloc(*count + format->sym_count, sizeof(char *));
- *offsets = (uint64_t *)calloc(*count + format->sym_count, sizeof(uint64_t));
-
- for (i = 0; i < format->sym_count; i++)
- {
- len = strlen(format->symbols[i].name);
-
- (*comments)[i] = (char *)calloc(len + 9, sizeof(char));
- snprintf((*comments)[i], len + 9, "&lt;%s&gt;", format->symbols[i].name);
-
- (*offsets)[i] = format->symbols[i].address;
-
- }
-
- *count += format->sym_count;
-
- }
-
-}
-
-
-
-
-
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* DETAIL DES SYMBOLES EXTERNES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* plt_start = début de la zone à traiter. *
-* plt_size = taille de la zone à traiter. *
-* dyn_start = début des informations dynamiques associées. *
-* dyn_size = taille de la zone associée. *
-* str_start = début de la zone de chaîne de caractères. *
-* str_size = taille de la zone de chaînes de caractères. *
-* *
-* Description : Charge en mémoire la liste des symboles dynamiques. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_elf_relocation_table(elf_format *format, const off_t *plt_start, const off_t *plt_size, const off_t *dyn_start, const off_t *dyn_size, const off_t *str_start, const off_t *str_size)
-{
- off_t iter; /* Boucle de parcours */
- Elf_Rel reloc; /* Infos de relocalisation */
- off_t index; /* Indice de la portion visée */
- char *name; /* Nom du symbole trouvé */
-
- for (iter = *plt_start; iter < (*plt_start + *plt_size); iter += ELF_SIZEOF_REL(format))
- {
- memcpy(&reloc, &EXE_FORMAT(format)->content[iter], ELF_SIZEOF_REL(format));
-
- switch (format->header.e_machine)
- {
- case EM_386:
- switch (ELF32_R_TYPE(ELF_REL_TYPE(format, reloc)))
- {
- case R_386_JMP_SLOT:
-
- index = ELF_REL_SYM(format, reloc);
- name = get_elf_dynamic_symbol_info(format, dyn_start, dyn_size, &index, str_start, str_size);
-
- if (name != NULL)
- {
- format->relocations = (elf_symbol *)realloc(format->relocations, ++format->rel_count * sizeof(elf_symbol));
-
- format->relocations[format->rel_count - 1].name = name;
- format->relocations[format->rel_count - 1].address = ELF_REL(format, reloc, r_offset);
-
- }
-
- break;
-
- default:
- printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc));
- break;
-
- }
- break;
-
- default:
- printf("Machine not recognized !\n");
- return false;
- break;
-
- }
-
-
- }
-
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* dyn_start = début des informations dynamiques associées. *
-* dyn_size = taille de la zone associée. *
-* index = indice de l'entrée à venir lire. *
-* str_start = début de la zone de chaîne de caractères. *
-* str_size = taille de la zone de chaînes de caractères. *
-* *
-* Description : Récupère les informations d'un symbole dynamique donné. *
-* *
-* Retour : Nom du symbole trouvé, ou NULL si erreur ou non adapté. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-char *get_elf_dynamic_symbol_info(elf_format *format, const off_t *dyn_start, const off_t *dyn_size, const off_t *index, const off_t *str_start, const off_t *str_size)
-{
- off_t offset; /* Emplacement à venir lire */
- Elf_Sym symbol; /* Symbole aux infos visées */
-
- offset = *dyn_start + *index * ELF_SIZEOF_SYM(format);
- if ((offset + ELF_SIZEOF_SYM(format)) > (*dyn_start + *dyn_size)) return NULL;
-
- memcpy(&symbol, &EXE_FORMAT(format)->content[offset], ELF_SIZEOF_SYM(format));
-
- if (ELF_SYM(format, symbol, st_name) >= *str_size) return NULL;
-
- return (char *)&EXE_FORMAT(format)->content[*str_start + ELF_SYM(format, symbol, st_name)];
-
-}
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
new file mode 100644
index 0000000..97b6ff2
--- /dev/null
+++ b/src/format/elf/symbols.c
@@ -0,0 +1,418 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * symbols.c - gestion des symboles d'un ELF
+ *
+ * Copyright (C) 2008 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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 "symbols.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "elf-int.h"
+#include "helper_x86.h"
+#include "section.h"
+#include "../../panel/log.h"
+
+
+
+
+
+#define _(str) str
+
+
+
+
+/* Récupère la désignation d'un symbole donné. */
+const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr *, off_t);
+
+
+
+/* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */
+
+
+/* Charge tous les symboles internes possibles. */
+static bool load_elf_internal_symbols(GElfFormat *);
+
+
+
+/* -------------------------- DETAIL DES SYMBOLES EXTERNES -------------------------- */
+
+
+/* Retrouve un élément donné dans la section dynamique. */
+static bool find_elf_dynamic_item(const GElfFormat *, const elf_shdr *, int32_t, elf_dyn *);
+
+/* Charge tous les éléments dynamiques externes possibles. */
+static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* *
+* Description : Charge en mémoire la liste humaine des symboles. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_elf_symbols(GElfFormat *format)
+{
+ bool result; /* Bilan à retourner */
+ elf_shdr *sections; /* Groupe de sections trouvées */
+ size_t count; /* Quantité de données */
+
+ result = true;
+
+ /* Symboles externes */
+
+ if (find_elf_sections_by_type(format, SHT_DYNAMIC, &sections, &count))
+ {
+ log_variadic_message(LMT_INFO, _("Binary is dynamically linked"));
+
+ result &= load_elf_external_symbols(format, &sections[0]);
+
+ free(sections);
+
+ }
+ else log_variadic_message(LMT_INFO, _("Binary is statically linked"));
+
+ /* Symboles internes */
+ result &= load_elf_internal_symbols(format);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* sym = section comprenant les symboles à venir lire. *
+* str = section de chaînes de caractères pour les noms. *
+* index = indice de l'entrée à venir lire. *
+* *
+* Description : Récupère la désignation d'un symbole donné. *
+* *
+* Retour : Nom du symbole trouvé, ou NULL si erreur ou non adapté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const elf_shdr *str, off_t index)
+{
+ const char *result; /* Résultat à retourner */
+ off_t sym_start; /* Début de section */
+ off_t sym_size; /* Taille de section */
+ off_t str_start; /* Début de section */
+ off_t str_size; /* Taille de section */
+ off_t offset; /* Emplacement à venir lire */
+ elf_sym symbol; /* Symbole aux infos visées */
+
+ result = NULL;
+
+ get_elf_section_content(format, sym, &sym_start, &sym_size, NULL);
+ get_elf_section_content(format, str, &str_start, &str_size, NULL);
+
+ offset = sym_start + index * ELF_SIZEOF_SYM(format);
+ if ((offset + ELF_SIZEOF_SYM(format)) > (sym_start + sym_size)) return NULL;
+
+ if (read_elf_symbol(format, &offset, &symbol))
+ result = extract_name_from_elf_string_section(format, str, ELF_SYM(format, symbol, st_name));
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DETAIL DES SYMBOLES INTERNES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* *
+* Description : Charge tous les symboles internes possibles. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool load_elf_internal_symbols(GElfFormat *format)
+{
+ bool result; /* Bilan à retourner */
+ elf_shdr *symtabs; /* Groupe de sections trouvées */
+ size_t count; /* Quantité de données */
+ size_t i; /* Boucle de parcours */
+ elf_shdr strtab; /* Section .strtab trouvée */
+ bool has_strtab; /* Présence de cette section */
+ off_t sym_start; /* Début de la zone à traiter */
+ off_t sym_size; /* Taille de cette même zone */
+ off_t iter; /* Boucle de parcours */
+ const char *name; /* Nom du symbole trouvé */
+ elf_sym sym; /* Symbole aux infos visées */
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+ result = true;
+
+ if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtabs, &count))
+ for (i = 0; i < count && result; i++)
+ {
+ has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, symtabs[i], sh_link), &strtab);
+
+ get_elf_section_content(format, &symtabs[i], &sym_start, &sym_size, NULL);
+
+ for (iter = sym_start; iter < (sym_start + sym_size); )
+ {
+ result = read_elf_symbol(format, &iter, &sym);
+ if (!result) break;
+
+ if (ELF_SYM(format, sym, st_value) == 0) continue;
+
+ if (!(ELF_ST_TYPE(format, sym) == STT_FUNC)) continue;
+
+ if (!has_strtab) name = NULL;
+ else name = get_elf_symbol_name(format, &symtabs[i], &strtab,
+ ((iter - sym_start) / ELF_SIZEOF_SYM(format)) - 1);
+
+ if (name == NULL)
+ {
+ /* FIXME */
+ name = "unknown";
+ }
+
+ /* Routine */
+
+ routine = g_binary_routine_new();
+
+ g_binary_routine_set_name(routine, strdup(name));
+ g_binary_routine_set_address(routine, ELF_SYM(format, sym, st_value));
+ g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size));
+
+ g_binary_format_add_routine(G_BIN_FORMAT(format), routine);
+
+ /* Symbole uniquement */
+
+ symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_SYM(format, sym, st_value));
+
+ g_binary_symbol_attach_routine(symbol, routine);
+
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+ }
+
+
+ }
+
+ return true;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DETAIL DES SYMBOLES EXTERNES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* dynamic = section de type SHT_DYNAMIC. *
+* type = sorte d'élément recherché. *
+* item = élément retrouvé dans la section. [OUT] *
+* *
+* Description : Retrouve un élément donné dans la section dynamique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool find_elf_dynamic_item(const GElfFormat *format, const elf_shdr *section, int32_t type, elf_dyn *item)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ off_t pos; /* Position de lecture */
+ off_t tmp; /* Position écrasable */
+ int32_t tag32; /* Type de l'entrée (32 bits) */
+ int64_t tag64; /* Type de l'entrée (64 bits) */
+
+ result = true;
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ for (pos = ELF_SHDR(format, *section, sh_offset);
+ pos < length/* FIXME !! + xploit */ && result;
+ pos += ELF_SIZEOF_DYN(format))
+ {
+ tmp = pos;
+
+ if (format->is_32b)
+ {
+ result = read_s32(&tag32, content, &tmp, length, format->endian);
+ if (tag32 == type) break;
+ }
+ else
+ {
+ result = read_s64(&tag64, content, &tmp, length, format->endian);
+ if (tag64 == type) break;
+ }
+
+ }
+
+ result &= (pos < length);
+
+ if (result)
+ {
+ if (format->is_32b)
+ {
+ result = read_s32(&item->dyn32.d_tag, content, &pos, length, format->endian);
+ result &= read_s32(&item->dyn32.d_un.d_val, content, &pos, length, format->endian);
+ }
+ else
+ {
+ result = read_s64(&item->dyn64.d_tag, content, &pos, length, format->endian);
+ result &= read_s64(&item->dyn64.d_un.d_val, content, &pos, length, format->endian);
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* dynamic = section de type SHT_DYNAMIC. *
+* *
+* Description : Charge tous les éléments dynamiques externes possibles. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool load_elf_external_symbols(GElfFormat *format, const elf_shdr *section)
+{
+ bool result; /* Bilan à retourner */
+
+ elf_dyn item; /* Elément dynamique */
+ elf_shdr relxxx; /* Section .rel.xxx trouvée */
+ elf_shdr dynsym; /* Section .dynsym trouvée */
+ elf_shdr dynstr; /* Section .dynstr trouvée */
+ elf_shdr plt; /* Section .plt trouvée */
+
+ result = true;
+
+
+
+
+
+
+ /* Section .rel.plt */
+ if (find_elf_dynamic_item(format, section, DT_JMPREL, &item))
+ {
+ result &= find_elf_section_by_virtual_address(format, ELF_DYN(format, item, d_un.d_ptr), &relxxx);
+
+ if (result)
+ result = find_elf_section_by_index(format, ELF_SHDR(format, relxxx, sh_link), &dynsym);
+
+ if (result)
+ result = find_elf_section_by_index(format, ELF_SHDR(format, dynsym, sh_link), &dynstr);
+
+ if (result)
+ switch (g_exe_format_get_target_machine(G_EXE_FORMAT(format)))
+ {
+ case FTM_386:
+ result = load_elf_x86_relocated_symbols(format, &relxxx, &dynsym, &dynstr);
+ break;
+
+ default:
+ break;
+
+ }
+
+ }
+
+ /* Entrées équivalentes dans le binaire */
+ if (find_elf_dynamic_item(format, section, DT_SYMTAB, &item))
+ {
+ result &= find_elf_section_by_virtual_address(format, ELF_DYN(format, item, d_un.d_ptr), &dynsym);
+
+ if (result)
+ result = find_elf_section_by_index(format, ELF_SHDR(format, dynsym, sh_link), &dynstr);
+
+ if (result)
+ switch (g_exe_format_get_target_machine(G_EXE_FORMAT(format)))
+ {
+ case FTM_MIPS:
+ //result = find_elf_mips_dynamic_symbols(format, &dynsym, &dynstr);
+ break;
+
+ case FTM_386:
+
+ if (find_elf_dynamic_item(format, section, DT_JMPREL, &item))
+ {
+ result &= find_elf_section_by_virtual_address(format, ELF_DYN(format, item, d_un.d_ptr), &relxxx);
+
+ if (result)
+ result = find_elf_section_by_index(format, ELF_SHDR(format, relxxx, sh_info), &plt);
+
+ if (result)
+ result = find_elf_x86_dynamic_symbols(format, &plt);
+
+ }
+
+ break;
+
+ default:
+ break;
+
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/src/format/elf/symbol.h b/src/format/elf/symbols.h
index 0a8f203..6644cbf 100644
--- a/src/format/elf/symbol.h
+++ b/src/format/elf/symbols.h
@@ -1,6 +1,6 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
- * symbol.h - prototypes pour la gestion des symboles d'un ELF
+ * symbols.h - prototypes pour la gestion des symboles d'un ELF
*
* Copyright (C) 2008 Cyrille Bagard
*
@@ -21,20 +21,16 @@
*/
-#ifndef _FORMAT_ELF_SYMBOL_H
-#define _FORMAT_ELF_SYMBOL_H
+#ifndef _FORMAT_ELF_SYMBOLS_H
+#define _FORMAT_ELF_SYMBOLS_H
-#include "e_elf.h"
-
+#include "elf.h"
/* Charge en mémoire la liste humaine des symboles. */
-bool load_elf_symbols(elf_format *);
-
-/* Récupère tous les commentaires à insérer dans le code. */
-void get_elf_symbol_comments(const elf_format *, char ***, uint64_t **, size_t *);
+bool load_elf_symbols(GElfFormat *);
-#endif /* _FORMAT_ELF_SYMBOL_H */
+#endif /* _FORMAT_ELF_SYMBOLS_H */