summaryrefslogtreecommitdiff
path: root/src/format/elf/e_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/elf/e_elf.c')
-rw-r--r--src/format/elf/e_elf.c604
1 files changed, 0 insertions, 604 deletions
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;
-
-}