From 208abfe4182c0dafc230e0377b3efcc6c24be0f9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 1 Oct 2017 19:32:12 +0200 Subject: Defined the ELF support as plugin. --- ChangeLog | 98 ++- configure.ac | 4 +- plugins/Makefile.am | 2 +- plugins/elf/Makefile.am | 29 + plugins/elf/core.c | 68 ++ plugins/elf/core.h | 38 ++ plugins/elf/dynamic.c | 109 ++++ plugins/elf/dynamic.h | 41 ++ plugins/elf/elf-int.c | 431 +++++++++++++ plugins/elf/elf-int.h | 80 +++ plugins/elf/elf.c | 707 +++++++++++++++++++++ plugins/elf/elf.h | 68 ++ plugins/elf/elf_def.h | 634 ++++++++++++++++++ plugins/elf/elf_def_arm.h | 45 ++ plugins/elf/helper_arm.c | 173 +++++ plugins/elf/helper_arm.h | 40 ++ plugins/elf/loading.c | 291 +++++++++ plugins/elf/loading.h | 73 +++ plugins/elf/program.c | 217 +++++++ plugins/elf/program.h | 47 ++ plugins/elf/python/Makefile.am | 15 + plugins/elf/python/elf.c | 198 ++++++ plugins/elf/python/elf.h | 42 ++ plugins/elf/python/module.c | 91 +++ plugins/elf/python/module.h | 38 ++ plugins/elf/section.c | 425 +++++++++++++ plugins/elf/section.h | 68 ++ plugins/elf/strings.c | 250 ++++++++ plugins/elf/strings.h | 37 ++ plugins/elf/symbols.c | 891 ++++++++++++++++++++++++++ plugins/elf/symbols.h | 53 ++ plugins/libcsem/Makefile.am | 2 +- plugins/libcsem/semantic.c | 1 + plugins/libcsem/semantic.h | 1 - plugins/pychrysa/Makefile.am | 1 + plugins/pychrysa/access.c | 137 ++++ plugins/pychrysa/access.h | 40 ++ plugins/pychrysa/analysis/contents/module.c | 4 + plugins/pychrysa/analysis/db/items/module.c | 4 + plugins/pychrysa/analysis/db/module.c | 4 + plugins/pychrysa/analysis/module.c | 4 + plugins/pychrysa/arch/module.c | 4 + plugins/pychrysa/common/module.c | 4 + plugins/pychrysa/core/module.c | 4 + plugins/pychrysa/debug/module.c | 4 + plugins/pychrysa/format/Makefile.am | 5 +- plugins/pychrysa/format/elf/Makefile.am | 15 - plugins/pychrysa/format/elf/elf.c | 206 ------ plugins/pychrysa/format/elf/elf.h | 42 -- plugins/pychrysa/format/elf/module.c | 84 --- plugins/pychrysa/format/elf/module.h | 39 -- plugins/pychrysa/format/module.c | 6 +- plugins/pychrysa/glibext/module.c | 4 + plugins/pychrysa/gui/module.c | 4 + plugins/pychrysa/gui/panels/module.c | 4 + plugins/pychrysa/helpers.h | 6 +- plugins/pychrysa/pychrysa.c | 9 + plugins/readelf/header.c | 2 +- plugins/readelf/program.c | 2 +- plugins/readelf/program.h | 2 +- plugins/readelf/reader.c | 2 +- plugins/readelf/section.c | 4 +- plugins/readelf/section.h | 2 +- plugins/readelf/strtab.c | 2 +- plugins/readelf/strtab.h | 2 +- plugins/ropgadgets/plugin.c | 3 +- src/core/formats.c | 5 - src/format/Makefile.am | 3 +- src/format/elf/Makefile.am | 25 - src/format/elf/dynamic.c | 109 ---- src/format/elf/dynamic.h | 41 -- src/format/elf/elf-int.c | 431 ------------- src/format/elf/elf-int.h | 78 --- src/format/elf/elf.c | 711 --------------------- src/format/elf/elf.h | 66 -- src/format/elf/elf_def.h | 634 ------------------ src/format/elf/elf_def_arm.h | 45 -- src/format/elf/helper_arm.c | 168 ----- src/format/elf/helper_arm.h | 40 -- src/format/elf/helper_mips.c | 85 --- src/format/elf/helper_mips.h | 41 -- src/format/elf/helper_x86.c | 451 ------------- src/format/elf/helper_x86.h | 40 -- src/format/elf/loading.c | 291 --------- src/format/elf/loading.h | 71 --- src/format/elf/program.c | 217 ------- src/format/elf/program.h | 47 -- src/format/elf/section.c | 425 ------------- src/format/elf/section.h | 68 -- src/format/elf/strings.c | 248 -------- src/format/elf/strings.h | 37 -- src/format/elf/symbols.c | 952 ---------------------------- src/format/elf/symbols.h | 53 -- src/format/format.c | 5 - 94 files changed, 5552 insertions(+), 5797 deletions(-) create mode 100644 plugins/elf/Makefile.am create mode 100644 plugins/elf/core.c create mode 100644 plugins/elf/core.h create mode 100644 plugins/elf/dynamic.c create mode 100644 plugins/elf/dynamic.h create mode 100644 plugins/elf/elf-int.c create mode 100644 plugins/elf/elf-int.h create mode 100644 plugins/elf/elf.c create mode 100644 plugins/elf/elf.h create mode 100644 plugins/elf/elf_def.h create mode 100644 plugins/elf/elf_def_arm.h create mode 100644 plugins/elf/helper_arm.c create mode 100644 plugins/elf/helper_arm.h create mode 100644 plugins/elf/loading.c create mode 100644 plugins/elf/loading.h create mode 100644 plugins/elf/program.c create mode 100644 plugins/elf/program.h create mode 100644 plugins/elf/python/Makefile.am create mode 100644 plugins/elf/python/elf.c create mode 100644 plugins/elf/python/elf.h create mode 100644 plugins/elf/python/module.c create mode 100644 plugins/elf/python/module.h create mode 100644 plugins/elf/section.c create mode 100644 plugins/elf/section.h create mode 100644 plugins/elf/strings.c create mode 100644 plugins/elf/strings.h create mode 100644 plugins/elf/symbols.c create mode 100644 plugins/elf/symbols.h create mode 100644 plugins/pychrysa/access.c create mode 100644 plugins/pychrysa/access.h delete mode 100644 plugins/pychrysa/format/elf/Makefile.am delete mode 100644 plugins/pychrysa/format/elf/elf.c delete mode 100644 plugins/pychrysa/format/elf/elf.h delete mode 100644 plugins/pychrysa/format/elf/module.c delete mode 100644 plugins/pychrysa/format/elf/module.h delete mode 100644 src/format/elf/Makefile.am delete mode 100644 src/format/elf/dynamic.c delete mode 100644 src/format/elf/dynamic.h delete mode 100644 src/format/elf/elf-int.c delete mode 100644 src/format/elf/elf-int.h delete mode 100644 src/format/elf/elf.c delete mode 100644 src/format/elf/elf.h delete mode 100644 src/format/elf/elf_def.h delete mode 100644 src/format/elf/elf_def_arm.h delete mode 100644 src/format/elf/helper_arm.c delete mode 100644 src/format/elf/helper_arm.h delete mode 100644 src/format/elf/helper_mips.c delete mode 100644 src/format/elf/helper_mips.h delete mode 100644 src/format/elf/helper_x86.c delete mode 100644 src/format/elf/helper_x86.h delete mode 100644 src/format/elf/loading.c delete mode 100644 src/format/elf/loading.h delete mode 100644 src/format/elf/program.c delete mode 100644 src/format/elf/program.h delete mode 100644 src/format/elf/section.c delete mode 100644 src/format/elf/section.h delete mode 100644 src/format/elf/strings.c delete mode 100644 src/format/elf/strings.h delete mode 100644 src/format/elf/symbols.c delete mode 100644 src/format/elf/symbols.h diff --git a/ChangeLog b/ChangeLog index 4cbd7f8..420972c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,98 @@ -17-08-30 Cyrille Bagard +17-10-01 Cyrille Bagard + + * configure.ac: + Add the new Makefiles from the 'plugins/elf' and 'plugins/elf/python' + directories, and remove those from the 'plugins/pychrysa/format/elf' + and 'src/format/elf' ones. + + * plugins/Makefile.am: + Add elf to SUBDIRS. + + * plugins/elf/Makefile.am: + * plugins/elf/core.c: + * plugins/elf/core.h: + New entries: define the ELF support as plugin. + + * plugins/elf/dynamic.c: + * plugins/elf/dynamic.h: + * plugins/elf/elf-int.c: + * plugins/elf/elf-int.h: + * plugins/elf/elf.c: + * plugins/elf/elf.h: + * plugins/elf/elf_def.h: + * plugins/elf/elf_def_arm.h: + * plugins/elf/helper_arm.c: + * plugins/elf/helper_arm.h: + * plugins/elf/loading.c: + * plugins/elf/loading.h: + * plugins/elf/program.c: + * plugins/elf/program.h: + Moved entries. + + * plugins/elf/python/Makefile.am: + * plugins/elf/python/elf.c: + * plugins/elf/python/elf.h: + * plugins/elf/python/module.c: + * plugins/elf/python/module.h: + New entries: support Python for the ELF format here. + + * plugins/elf/section.c: + * plugins/elf/section.h: + * plugins/elf/strings.c: + * plugins/elf/strings.h: + * plugins/elf/symbols.c: + * plugins/elf/symbols.h: + Moved entries. + + * plugins/libcsem/Makefile.am: + * plugins/libcsem/semantic.c: + * plugins/libcsem/semantic.h: + Update code. + + * plugins/pychrysa/Makefile.am: + Add the 'access.[ch]' files to pychrysalide_la_SOURCES. + + * plugins/pychrysa/access.c: + * plugins/pychrysa/access.h: + New entries: provide a direct access to Python modules to be loaded. + + * plugins/pychrysa/analysis/contents/module.c: + * plugins/pychrysa/analysis/db/items/module.c: + * plugins/pychrysa/analysis/db/module.c: + * plugins/pychrysa/analysis/module.c: + * plugins/pychrysa/arch/module.c: + * plugins/pychrysa/common/module.c: + * plugins/pychrysa/core/module.c: + * plugins/pychrysa/debug/module.c: + * plugins/pychrysa/format/Makefile.am: + * plugins/pychrysa/format/module.c: + * plugins/pychrysa/glibext/module.c: + * plugins/pychrysa/gui/module.c: + * plugins/pychrysa/gui/panels/module.c: + * plugins/pychrysa/helpers.h: + * plugins/pychrysa/pychrysa.c: + * plugins/readelf/header.c: + * plugins/readelf/program.c: + * plugins/readelf/program.h: + * plugins/readelf/reader.c: + * plugins/readelf/section.c: + * plugins/readelf/section.h: + * plugins/readelf/strtab.c: + * plugins/readelf/strtab.h: + * plugins/ropgadgets/plugin.c: + * src/core/formats.c: + * src/format/Makefile.am: + Update code. + + * src/format/elf/helper_mips.c: + * src/format/elf/helper_x86.c: + * src/format/elf/helper_x86.h: + Deleted entries. + + * src/format/format.c: + Update code. + +17-09-30 Cyrille Bagard * src/plugins/plugin-def.h: Typo. @@ -6,7 +100,7 @@ * src/plugins/plugin.c: Check the ABI version before loading plugins. -17-08-30 Cyrille Bagard +17-09-30 Cyrille Bagard * plugins/pychrysa/plugin.c: * plugins/pychrysa/pychrysa.c: diff --git a/configure.ac b/configure.ac index 98923d6..80afa2e 100644 --- a/configure.ac +++ b/configure.ac @@ -320,6 +320,8 @@ AC_CONFIG_FILES([Makefile pixmaps/Makefile plugins/Makefile plugins/devdbg/Makefile + plugins/elf/Makefile + plugins/elf/python/Makefile plugins/fmtp/Makefile plugins/libcsem/Makefile plugins/mobicore/Makefile @@ -337,7 +339,6 @@ AC_CONFIG_FILES([Makefile plugins/pychrysa/debug/gdbrsp/Makefile plugins/pychrysa/format/Makefile plugins/pychrysa/format/dex/Makefile - plugins/pychrysa/format/elf/Makefile plugins/pychrysa/glibext/Makefile plugins/pychrysa/gtkext/Makefile plugins/pychrysa/gui/Makefile @@ -380,7 +381,6 @@ AC_CONFIG_FILES([Makefile src/format/dwarf/v2/Makefile src/format/dwarf/v3/Makefile src/format/dwarf/v4/Makefile - src/format/elf/Makefile src/format/java/Makefile src/format/mangling/Makefile src/format/mangling/dex/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 2ad0ae2..d8d771f 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -4,4 +4,4 @@ if HAVE_PYTHON3_CONFIG endif # androhelpers -SUBDIRS = devdbg fmtp libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf readmc ropgadgets +SUBDIRS = devdbg elf fmtp libcsem mobicore $(PYTHON3_SUBDIRS) readdex readelf readmc ropgadgets diff --git a/plugins/elf/Makefile.am b/plugins/elf/Makefile.am new file mode 100644 index 0000000..d3cfe05 --- /dev/null +++ b/plugins/elf/Makefile.am @@ -0,0 +1,29 @@ + +lib_LTLIBRARIES = libelf.la + +libelf_la_SOURCES = \ + core.h core.c \ + elf-int.h elf-int.c \ + elf.h elf.c \ + elf_def.h \ + elf_def_arm.h \ + dynamic.h dynamic.c \ + helper_arm.h helper_arm.c \ + loading.h loading.c \ + program.h program.c \ + section.h section.c \ + strings.h strings.c \ + symbols.h symbols.c + +libelf_la_LIBADD = \ + python/libelfpython.la + +libelf_la_LDFLAGS = \ + $(LIBPYTHON_LIBS) $(LIBPYGOBJECT_LIBS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(LIBXML_CFLAGS) -I../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = python diff --git a/plugins/elf/core.c b/plugins/elf/core.c new file mode 100644 index 0000000..5e2e19c --- /dev/null +++ b/plugins/elf/core.c @@ -0,0 +1,68 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.c - intégration du support du format ELF + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "core.h" + + +#include +#include + + +#include "elf.h" +#include "python/module.h" + + + +DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("elf", "Add suport for the ELF format", "0.1.0", + PGA_PLUGIN_INIT); + + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* ref = espace de référencement global. * +* * +* Description : Prend acte du chargement du greffon. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) +{ + bool result; /* Bilan à retourner */ + + result = register_format_matcher(elf_is_matching, NULL); + + if (result) + result = register_format_loader("elf", "Executable and Linkable Format", g_elf_format_new); + + if (result) + result = add_format_elf_module_to_python_module(); + + return result; + +} diff --git a/plugins/elf/core.h b/plugins/elf/core.h new file mode 100644 index 0000000..9702b74 --- /dev/null +++ b/plugins/elf/core.h @@ -0,0 +1,38 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.h - prototypes pour l'intégration du support du format ELF + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _PLUGINS_ELF_CORE_H +#define _PLUGINS_ELF_CORE_H + + +#include +#include + + + +/* Prend acte du chargement du greffon. */ +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *); + + + +#endif /* _PLUGINS_ELF_CORE_H */ diff --git a/plugins/elf/dynamic.c b/plugins/elf/dynamic.c new file mode 100644 index 0000000..782167c --- /dev/null +++ b/plugins/elf/dynamic.c @@ -0,0 +1,109 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * program.c - gestion des en-têtes de programme d'un ELF + * + * Copyright (C) 2015-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "dynamic.h" + + +#include "elf-int.h" +#include "program.h" + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* index = indice de la section recherchée. * +* dynamic = ensemble d'informations à faire remonter. [OUT] * +* * +* Description : Recherche un en-tête de programme DYNAMIC au sein de binaire.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_dynamic_program_header(const GElfFormat *format, elf_phdr *dynamic) +{ + bool result; /* Bilan d'opération à renvoyer*/ + uint16_t max; /* Nombre d'en-têtes présents */ + uint16_t i; /* Boucle de parcours */ + + result = false; + + max = ELF_HDR(format, format->header, e_phnum); + + for (i = 0; i < max && !result; i++) + { + if (!find_elf_program_by_index(format, i, dynamic)) + break; + + result = (ELF_PHDR(format, *dynamic, p_type) == PT_DYNAMIC); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* dynamic = programme de type PT_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 : - * +* * +******************************************************************************/ + +bool find_elf_dynamic_item_from_pheader(const GElfFormat *format, const elf_phdr *dynamic, int64_t type, elf_dyn *item) +{ + bool result; /* Bilan à retourner */ + off_t max; /* Nombre d'entités présentes */ + off_t i; /* Boucle de parcours */ + phys_t pos; /* Position de lecture */ + + result = false; + + max = ELF_PHDR(format, *dynamic, p_filesz) / ELF_SIZEOF_DYN(format); + + for (i = 0; i < max && !result; i++) + { + pos = ELF_PHDR(format, *dynamic, p_offset) + i * ELF_SIZEOF_DYN(format); + + if (!read_elf_dynamic_entry(format, pos, item)) + break; + + result = (ELF_DYN(format, *item, d_tag) == type); + + } + + return result; + +} diff --git a/plugins/elf/dynamic.h b/plugins/elf/dynamic.h new file mode 100644 index 0000000..7fce1d4 --- /dev/null +++ b/plugins/elf/dynamic.h @@ -0,0 +1,41 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * dynamic.h - prototypes pour la manipulation de l'en-ête de programme 'DYNAMIC' + * + * Copyright (C) 2015-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_DYNAMIC_H +#define _FORMAT_ELF_DYNAMIC_H + + +#include "elf.h" +#include "elf_def.h" + + + +/* Recherche un en-tête de programme DYNAMIC au sein de binaire. */ +bool find_elf_dynamic_program_header(const GElfFormat *, elf_phdr *); + +/* Retrouve un élément donné dans la section dynamique. */ +bool find_elf_dynamic_item_from_pheader(const GElfFormat *, const elf_phdr *, int64_t, elf_dyn *); + + + +#endif /* _FORMAT_ELF_DYNAMIC_H */ diff --git a/plugins/elf/elf-int.c b/plugins/elf/elf-int.c new file mode 100644 index 0000000..36a0f93 --- /dev/null +++ b/plugins/elf/elf-int.c @@ -0,0 +1,431 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf-int.c - structures internes du format ELF + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "elf-int.h" + + +#include + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* 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 ELF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, SourceEndian *endian) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ + + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, 0, VMPA_NO_VIRTUAL); + + result = g_binary_content_read_raw(content, &pos, EI_NIDENT, (bin_t *)header->hdr32.e_ident); + + /* Détermination de l'espace d'adressage */ + if (result) + switch (header->hdr32.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->hdr32.e_ident[EI_DATA]) + { + case ELFDATA2LSB: + *endian = SRE_LITTLE; + break; + case ELFDATA2MSB: + *endian = SRE_BIG; + break; + default: + result = false; + break; + } + + if (*is_32b) + { + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_type); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_machine); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_version); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_entry); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_phoff); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_shoff); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_flags); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_ehsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_phentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_phnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shstrndx); + } + else + { + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_type); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_machine); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr64.e_version); + result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_entry); + result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_phoff); + result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_shoff); + result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr64.e_flags); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_ehsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_phentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_phnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shentsize); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shnum); + result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shstrndx); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* phys = position de début de lecture. * +* 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, phys_t phys, elf_phdr *header) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ + + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + result = g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_type); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_offset); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_vaddr); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_paddr); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_filesz); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_memsz); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_flags); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_align); + } + else + { + result = g_binary_content_read_u32(content, &pos, format->endian, &header->phdr64.p_type); + result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr64.p_flags); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_offset); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_vaddr); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_paddr); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_filesz); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_memsz); + result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_align); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* phys = position de début 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, phys_t phys, elf_shdr *section) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ + elf32_shdr *shdr32; /* Version 32 bits */ + elf64_shdr *shdr64; /* Version 32 bits */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + shdr32 = §ion->shdr32; + + result = g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_name); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_type); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_flags); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_addr); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_offset); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_size); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_link); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_info); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_addralign); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_entsize); + + } + else + { + shdr64 = §ion->shdr64; + + result = g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_name); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_type); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_flags); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_addr); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_offset); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_size); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_link); + result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_info); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_addralign); + result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_entsize); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* phys = position de début de lecture. * +* dyn = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une entrée de type 'DYNAMIC' ELF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_elf_dynamic_entry(const GElfFormat *format, phys_t phys, elf_dyn *dyn) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ + + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + result = g_binary_content_read_s32(content, &pos, format->endian, &dyn->dyn32.d_tag); + result &= g_binary_content_read_u32(content, &pos, format->endian, &dyn->dyn32.d_un.d_val); + } + else + { + result = g_binary_content_read_s64(content, &pos, format->endian, &dyn->dyn64.d_tag); + result &= g_binary_content_read_u64(content, &pos, format->endian, &dyn->dyn64.d_un.d_val); + } + + 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, phys_t *phys, elf_sym *sym) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ + + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + result = g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_name); + result &= g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_value); + result &= g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_size); + result &= g_binary_content_read_u8(content, &pos, &sym->sym32.st_info); + result &= g_binary_content_read_u8(content, &pos, &sym->sym32.st_other); + result &= g_binary_content_read_u16(content, &pos, format->endian, &sym->sym32.st_shndx); + } + else + { + result = g_binary_content_read_u32(content, &pos, format->endian, &sym->sym64.st_name); + result &= g_binary_content_read_u8(content, &pos, &sym->sym64.st_info); + result &= g_binary_content_read_u8(content, &pos, &sym->sym64.st_other); + result &= g_binary_content_read_u16(content, &pos, format->endian, &sym->sym64.st_shndx); + result &= g_binary_content_read_u64(content, &pos, format->endian, &sym->sym64.st_value); + result &= g_binary_content_read_u64(content, &pos, format->endian, &sym->sym64.st_size); + } + + if (result) + *phys = get_phy_addr(&pos); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* phys = 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, phys_t *phys, elf_rel *reloc) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + vmpa2t pos; /* Position de lecture */ + + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + result = g_binary_content_read_u32(content, &pos, format->endian, &reloc->rel32.r_offset); + result &= g_binary_content_read_u32(content, &pos, format->endian, &reloc->rel32.r_info); + } + else + { + result = g_binary_content_read_u64(content, &pos, format->endian, &reloc->rel64.r_offset); + result &= g_binary_content_read_u64(content, &pos, format->endian, &reloc->rel64.r_info); + } + + if (result) + *phys = get_phy_addr(&pos); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* content = contenu binaire mis à disposition ou NULL. * +* pos = position de début de lecture. [OUT] * +* note = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une note ELF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_elf_note(const GElfFormat *format, GBinContent *content, phys_t *phys, elf_note *note) +{ + bool result; /* Bilan à retourner */ + vmpa2t pos; /* Position de lecture */ + + if (content == NULL) + content = G_BIN_FORMAT(format)->content; + + init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); + + result = g_binary_content_read_u32(content, &pos, format->endian, ¬e->namesz); + result &= g_binary_content_read_u32(content, &pos, format->endian, ¬e->descsz); + result &= g_binary_content_read_u32(content, &pos, format->endian, ¬e->type); + + if (result && note->namesz > 0) + { + align_vmpa(&pos, 4); + + note->name = (const char *)g_binary_content_get_raw_access(content, &pos, note->namesz); + + result &= (note->name != NULL); + + } + else note->name = NULL; + + if (result && note->descsz > 0) + { + align_vmpa(&pos, 4); + + note->desc = (const void *)g_binary_content_get_raw_access(content, &pos, note->descsz); + + result &= (note->desc != NULL); + + } + else note->desc = NULL; + + return result; + +} diff --git a/plugins/elf/elf-int.h b/plugins/elf/elf-int.h new file mode 100644 index 0000000..34f15cb --- /dev/null +++ b/plugins/elf/elf-int.h @@ -0,0 +1,80 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf-int.h - prototypes pour les structures internes du format ELF + * + * Copyright (C) 2008-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_ELF_INT_H +#define _FORMAT_ELF_ELF_INT_H + + +#include +#include + + +#include "elf.h" +#include "elf_def.h" + + + +/* Format d'exécutable générique (instance) */ +struct _GElfFormat +{ + GExeFormat parent; /* A laisser en premier */ + + elf_header header; /* En-tête du format */ + bool is_32b; /* Format du binaire */ + SourceEndian endian; /* Boutisme du format */ + +}; + +/* Format d'exécutable générique (classe) */ +struct _GElfFormatClass +{ + GExeFormatClass parent; /* A laisser en premier */ + +}; + + + +/* Procède à la lecture de l'en-tête d'un contenu binaire ELF. */ +bool read_elf_header(GElfFormat *, elf_header *, bool *, SourceEndian *); + +/* Procède à la lecture d'une en-tête de programme ELF. */ +bool read_elf_program_header(const GElfFormat *, phys_t, elf_phdr *); + +/* Procède à la lecture d'une en-tête de section ELF. */ +bool read_elf_section_header(const GElfFormat *, phys_t, elf_shdr *); + +/* Procède à la lecture d'une entrée de type 'DYNAMIC' ELF. */ +bool read_elf_dynamic_entry(const GElfFormat *, phys_t, elf_dyn *); + +/* Procède à la lecture d'un symbole ELF. */ +bool read_elf_symbol(const GElfFormat *, phys_t *, elf_sym *); + +/* Procède à la lecture d'une relocalisation ELF. */ +bool read_elf_relocation(const GElfFormat *, phys_t *, elf_rel *); + +/* Procède à la lecture d'une note ELF. */ +bool read_elf_note(const GElfFormat *, GBinContent *, phys_t *, elf_note *); + + + +#endif /* _FORMAT_ELF_ELF_INT_H */ diff --git a/plugins/elf/elf.c b/plugins/elf/elf.c new file mode 100644 index 0000000..04ee031 --- /dev/null +++ b/plugins/elf/elf.c @@ -0,0 +1,707 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf.c - support du format ELF + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "elf.h" + + +#include +#include +#include +#include + + +#include +#include +#include + + +#include "elf-int.h" +#include "program.h" +#include "section.h" +#include "strings.h" +#include "symbols.h" + + + +/* Taille maximale d'une description */ +#define MAX_PORTION_DESC 256 + + +/* 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 *); + +/* Supprime toutes les références externes. */ +static void g_elf_format_dispose(GElfFormat *); + +/* Procède à la libération totale de la mémoire. */ +static void g_elf_format_finalize(GElfFormat *); + +/* Informe quant au boutisme utilisé. */ +static SourceEndian g_elf_format_get_endianness(const GElfFormat *); + +/* Indique le type d'architecture visée par le format. */ +static const char *g_elf_format_get_target_machine(const GElfFormat *); + +/* Fournit l'adresse principale associée à un format Elf. */ +static bool g_elf_format_get_main_address(GElfFormat *, vmpa2t *); + +/* Etend la définition des portions au sein d'un binaire. */ +static void g_elf_format_refine_portions(GElfFormat *); + +/* Fournit l'emplacement correspondant à une position physique. */ +static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *); + +/* Fournit l'emplacement correspondant à une position physique. */ +static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *, virt_t, vmpa2t *); + +/* Fournit l'emplacement d'une section donnée. */ +static bool g_elf_format_get_section_range_by_name(const GElfFormat *, const char *, mrange_t *); + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* parent = éventuel format exécutable déjà chargé. * +* unused = adresse non utilisée ici. * +* key = identifiant de format trouvé ou NULL. [OUT] * +* * +* Description : Indique si le format peut être pris en charge ici. * +* * +* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +FormatMatchStatus elf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key) +{ + FormatMatchStatus result; /* Bilan à renvoyer */ + vmpa2t addr; /* Tête de lecture initiale */ + bool status; /* Bilan des accès mémoire */ + char magic[4]; /* Idenfiant standard */ + + if (parent != NULL) + return FMS_UNKNOWN; + + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + + status = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); + + status &= (memcmp(magic, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); + + if (status) + { + result = FMS_MATCHED; + *key = strdup("elf"); + } + else + result = FMS_UNKNOWN; + + 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) +{ + GObjectClass *object; /* Autre version de la classe */ + GBinFormatClass *fmt; /* Version en format basique */ + GExeFormatClass *exe; /* Version en exécutable */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_format_dispose; + object->finalize = (GObjectFinalizeFunc)g_elf_format_finalize; + + fmt = G_BIN_FORMAT_CLASS(klass); + + fmt->get_endian = (format_get_endian_fc)g_elf_format_get_endianness; + + exe = G_EXE_FORMAT_CLASS(klass); + + exe->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; + exe->get_main_addr = (get_main_addr_fc)g_elf_format_get_main_address; + exe->refine_portions = (refine_portions_fc)g_elf_format_refine_portions; + + exe->translate_phys = (translate_phys_fc)g_elf_format_translate_offset_into_vmpa; + exe->translate_virt = (translate_virt_fc)g_elf_format_translate_address_into_vmpa; + + exe->get_range_by_name = (get_range_by_name_fc)g_elf_format_get_section_range_by_name; + +} + + +/****************************************************************************** +* * +* 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) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_format_dispose(GElfFormat *format) +{ + G_OBJECT_CLASS(g_elf_format_parent_class)->dispose(G_OBJECT(format)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_format_finalize(GElfFormat *format) +{ + G_OBJECT_CLASS(g_elf_format_parent_class)->finalize(G_OBJECT(format)); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* parent = éventuel format exécutable déjà chargé. * + status = barre de statut à tenir informée. * +* * +* 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(GBinContent *content, GExeFormat *parent, GtkStatusStack *status) +{ + GElfFormat *result; /* Structure à retourner */ + GBinFormat *base; /* Version basique du format */ + GExeFormat *exe_format; /* Autre version du format */ + + result = g_object_new(G_TYPE_ELF_FORMAT, NULL); + + base = G_BIN_FORMAT(result); + exe_format = G_EXE_FORMAT(result); + + g_binary_format_set_content(base, content); + + if (!read_elf_header(result, &result->header, &result->is_32b, &result->endian)) + { + /* TODO */ + return NULL; + } + + + /* Vérification des tailles d'entrée de table */ + + if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result)) + { + log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), + ELF_HDR(result, result->header, e_phentsize), + ELF_HDR(result, result->header, e_phentsize), + ELF_SIZEOF_PHDR(result), ELF_HDR_OFFSET_OF(result, e_phentsize)); + ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result)); + } + + if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result)) + { + log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), + ELF_HDR(result, result->header, e_shentsize), + ELF_HDR(result, result->header, e_shentsize), + ELF_SIZEOF_SHDR(result), ELF_HDR_OFFSET_OF(result, e_shentsize)); + ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result)); + } + + /* FIXME : à améliorer */ + /* + if ((ELF_HDR(result, result->header, e_shnum) * ELF_HDR(result, result->header, e_shentsize)) >= length) + { + log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), + ELF_HDR(result, result->header, e_shnum), + 0, ELF_HDR_OFFSET_OF(result, e_shnum)); + ELF_HDR_SET(result, result->header, e_shnum, 0); + } + */ + + + + /** + * On inscrit les éléments préchargés avant tout ! + * + * Cela permet de partir d'une base vide, et d'ajouter les instructions et + * leurs commentaires par paires. + * + * Ensuite, on inscrit le reste (comme les chaînes de caractères). + */ + + preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status); + + + if (!load_elf_symbols(result, status)) + { + /* TODO */ + return NULL; + } + + + if (!find_all_elf_strings(result)) + { + /* TODO */ + return NULL; + } + + + if (!g_executable_format_complete_loading(exe_format, status)) + goto gefn_error; + + return base; + + gefn_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Informe quant au boutisme utilisé. * +* * +* Retour : Indicateur de boutisme. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static SourceEndian g_elf_format_get_endianness(const GElfFormat *format) +{ + return format->endian; + +} + + +/****************************************************************************** +* * +* 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 const char *g_elf_format_get_target_machine(const GElfFormat *format) +{ + const char *result; /* Identifiant à retourner */ + + switch (ELF_HDR(format, format->header, e_machine)) + { + case EM_386: + result = "i386"; + break; + + case EM_MIPS: + result = "mips"; + break; + + case EM_ARM: + result = "armv7"; + break; + + case EM_NONE: + default: + result = NULL; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse principale trouvée si possible. [OUT] * +* * +* Description : Fournit l'adresse principale associée à un format Elf. * +* * +* Retour : Bilan des recherches. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_get_main_address(GElfFormat *format, vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + GBinSymbol *symbol; /* Point d'entrée trouvé */ + GBinFormat *base; /* Version d'instance parente */ + const mrange_t *range; /* Emplacement de ce point */ + + result = false; + symbol = NULL; + + base = G_BIN_FORMAT(format); + + if (g_binary_format_find_symbol_by_label(base, "main", &symbol)) + goto done; + + if (g_binary_format_find_symbol_by_label(base, "_start", &symbol)) + goto done; + + if (g_binary_format_find_symbol_by_label(base, "entry_point", &symbol)) + goto done; + + done: + + if (symbol != NULL) + { + result = true; + + range = g_binary_symbol_get_range(symbol); + + copy_vmpa(addr, get_mrange_addr(range)); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Etend la définition des portions au sein d'un binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_format_refine_portions(GElfFormat *format) +{ + GExeFormat *exe_format; /* Autre version du format */ + uint16_t max; /* Décompte d'éléments traités */ + uint16_t i; /* Boucle de parcours */ + off_t offset; /* Début de part de programme */ + vmpa2t origin; /* Origine d'une définition */ + elf_phdr phdr; /* En-tête de programme ELF */ + uint32_t p_flags; /* Droits associés à une partie*/ + const char *background; /* Fond signigicatif */ + GBinPortion *new; /* Nouvelle portion définie */ + char desc[MAX_PORTION_DESC]; /* Description d'une portion */ + vmpa2t addr; /* Emplacement dans le binaire */ + PortionAccessRights rights; /* Droits d'une portion */ + elf_shdr strings; /* Section des descriptions */ + bool has_strings; /* Section trouvée ? */ + elf_shdr shdr; /* En-tête de section ELF */ + uint64_t sh_flags; /* Droits associés à une partie*/ + mrange_t range; /* Emplacement d'une section */ + const char *name; /* Nom trouvé ou NULL */ + + exe_format = G_EXE_FORMAT(format); + + /** + * La copie des différents en-têtes cherche à reproduire l'inclusion native + * du format : + * + * EXIDX 0x001178 0x00009178 0x00009178 0x00008 0x00008 R 0x4 + * PHDR 0x000034 0x00008034 0x00008034 0x00120 0x00120 R E 0x4 + * INTERP 0x000154 0x00008154 0x00008154 0x00019 0x00019 R 0x1 + * LOAD 0x000000 0x00008000 0x00008000 0x01184 0x01184 R E 0x8000 + * + */ + + /** + * Côté segments basiques. + */ + + max = ELF_HDR(format, format->header, e_phnum); + + for (i = 0; i < max; i++) + { + offset = ELF_HDR(format, format->header, e_phoff) + + ELF_HDR(format, format->header, e_phentsize) * i; + + init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); + + if (!read_elf_program_header(format, offset, &phdr)) + continue; + + if (ELF_PHDR(format, phdr, p_type) == PT_NULL) + continue; + + p_flags = ELF_PHDR(format, phdr, p_flags); + + if (p_flags & PF_X) background = BPC_CODE; + else if (p_flags & PF_W) background = BPC_DATA; + else background = BPC_DATA_RO; + + init_vmpa(&addr, ELF_PHDR(format, phdr, p_offset), ELF_PHDR(format, phdr, p_vaddr)); + + new = g_binary_portion_new(background, &addr, ELF_PHDR(format, phdr, p_filesz)); + + snprintf(desc, MAX_PORTION_DESC, "%s \"%s\"", + _("Segment"), + get_elf_program_type_desc(format, ELF_PHDR(format, phdr, p_type))); + + g_binary_portion_set_desc(new, desc); + + rights = PAC_NONE; + if (p_flags & PF_R) rights |= PAC_READ; + if (p_flags & PF_W) rights |= PAC_WRITE; + if (p_flags & PF_X) rights |= PAC_EXEC; + + g_binary_portion_set_rights(new, rights); + + g_exe_format_include_portion(exe_format, new, &origin); + + } + + /** + * Inclusion des sections, si possible... + */ + + has_strings = find_elf_section_by_index(format, + ELF_HDR(format, format->header, e_shstrndx), + &strings); + + max = ELF_HDR(format, format->header, e_shnum); + + for (i = 0; i < max; i++) + { + if (!find_elf_section_by_index(format, i, &shdr)) + continue; + + if (ELF_SHDR(format, shdr, sh_offset) == 0) + continue; + + sh_flags = ELF_SHDR(format, shdr, sh_flags); + + if (sh_flags & SHF_EXECINSTR) background = BPC_CODE; + else if (sh_flags & SHF_WRITE) background = BPC_DATA; + else background = BPC_DATA_RO; + + get_elf_section_range(format, &shdr, &range); + + new = g_binary_portion_new(background, get_mrange_addr(&range), get_mrange_length(&range)); + + if (has_strings) + name = extract_name_from_elf_string_section(format, &strings, + ELF_SHDR(format, shdr, sh_name)); + else name = NULL; + + if (name != NULL) + sprintf(desc, "%s \"%s\"", _("Section"), name); + else + sprintf(desc, "%s ???", _("Section")); + + g_binary_portion_set_desc(new, desc); + + rights = PAC_NONE; + if (sh_flags & SHF_ALLOC) rights |= PAC_READ; + if (sh_flags & SHF_WRITE) rights |= PAC_WRITE; + if (sh_flags & SHF_EXECINSTR) rights |= PAC_EXEC; + + g_binary_portion_set_rights(new, rights); + + offset = ELF_HDR(format, format->header, e_shoff) + + ELF_HDR(format, format->header, e_shentsize) * i; + + init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); + + g_exe_format_include_portion(exe_format, new, &origin); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* off = position physique à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une position physique. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *format, phys_t off, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + + result = translate_offset_into_vmpa_using_elf_sections(format, off, pos); + + if (!result) + result = translate_offset_into_vmpa_using_elf_programs(format, off, pos); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *format, virt_t addr, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + + result = translate_address_into_vmpa_using_elf_sections(format, addr, pos); + + if (!result) + result = translate_address_into_vmpa_using_elf_programs(format, addr, pos); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* name = nom de la section recherchée. * +* range = emplacement en mémoire à renseigner. [OUT] * +* * +* Description : Fournit l'emplacement d'une section donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_get_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range) +{ + bool result; /* Bilan à retourner */ + phys_t offset; /* Position physique de section*/ + phys_t size; /* Taille de la section trouvée*/ + virt_t address; /* Adresse virtuelle de section*/ + vmpa2t tmp; /* Adresse à initialiser */ + + result = find_elf_section_content_by_name(format, name, &offset, &size, &address); + + if (result) + { + init_vmpa(&tmp, offset, address); + init_mrange(range, &tmp, size); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Présente l'en-tête ELF du format chargé. * +* * +* Retour : Pointeur vers la description principale. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const elf_header *g_elf_format_get_header(const GElfFormat *format) +{ + return &format->header; + +} diff --git a/plugins/elf/elf.h b/plugins/elf/elf.h new file mode 100644 index 0000000..7e1895b --- /dev/null +++ b/plugins/elf/elf.h @@ -0,0 +1,68 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf.h - prototypes pour le support du format ELF + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_ELF_H +#define _FORMAT_ELF_ELF_H + + +#include +#include +#include + + +#include + + +#include "elf_def.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. */ +FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **); + +/* 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(GBinContent *, GExeFormat *, GtkStatusStack *); + +/* Présente l'en-tête ELF du format chargé. */ +const elf_header *g_elf_format_get_header(const GElfFormat *); + + + +#endif /* _FORMAT_ELF_ELF_H */ diff --git a/plugins/elf/elf_def.h b/plugins/elf/elf_def.h new file mode 100644 index 0000000..0d91e00 --- /dev/null +++ b/plugins/elf/elf_def.h @@ -0,0 +1,634 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf_def.h - liste des structures et constantes utilisées par le format ELF + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_ELF_DEF_H +#define _FORMAT_ELF_ELF_DEF_H + + +#include + + + +/* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */ + + +#define EI_NIDENT 16 + + +/* En-tête de fichier ELF (32 et 64 bits) */ + +typedef struct _elf32_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 */ + uint32_t e_entry; /* Point d'entrée du programme */ + uint32_t e_phoff; /* Début de la table 'Program' */ + uint32_t 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*/ + +} elf32_header; + +typedef struct _elf64_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 */ + uint64_t e_entry; /* Point d'entrée du programme */ + uint64_t e_phoff; /* Début de la table 'Program' */ + uint64_t 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*/ + +} elf64_header; + +typedef union _elf_header +{ + elf32_header hdr32; /* Version 32 bits */ + elf64_header hdr64; /* Version 64 bits */ + +} elf_header; + + +#define ELF_HDR(fmt, hdr, fld) (fmt->is_32b ? (hdr).hdr32.fld : (hdr).hdr64.fld) + +#define ELF_HDR_SET(fmt, hdr, fld, val) \ + do \ + { \ + if (fmt->is_32b) (hdr).hdr32.fld = val; \ + else (hdr).hdr64.fld = val; \ + } \ + while (0) + +#define ELF_HDR_OFFSET_OF(fmt, fld) (fmt->is_32b ? offsetof(elf32_header, fld) : offsetof(elf64_header, fld)) + +#define ELF_SIZEOF_HDR(fmt) (fmt->is_32b ? sizeof(elf32_header) : sizeof(elf64_header)) + + +/* Composition du champ e_ident */ + + +#define EI_CLASS 4 /* Indice de classe du fichier */ +#define EI_DATA 5 /* Indice de l'encodage */ +#define EI_VERSION 6 /* Version de fichier ELF */ +#define EI_OSABI 7 /* Identification de l'ABI OS */ + + +/* ... 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. */ + +/* ... EI_VERSION */ + +#define EV_NONE 0 /* Version ELF invalide */ +#define EV_CURRENT 1 /* Version d'ELF courante */ + +/* ... EI_OSABI */ + +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ +#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +/* Valeurs possibles pour e_type */ + +#define ET_NONE 0 /* Aucun type défini */ +#define ET_REL 1 /* Fichier relogeable */ +#define ET_EXEC 2 /* Fichier exécutable */ +#define ET_DYN 3 /* Bibliothèque dynamique */ +#define ET_CORE 4 /* Fichier Core */ +#define ET_LOOS 0xfe00 /* Spécifique OS : début */ +#define ET_HIOS 0xfeff /* Spécifique OS : fin */ +#define ET_LOPROC 0xff00 /* Spécifique processeur : deb.*/ +#define ET_HIPROC 0xffff /* Spécifique processeur : fin */ + +/* Valeurs possibles pour e_machine */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_AARCH64 183 /* ARM AARCH64 */ +#define EM_TILEPRO 188 /* Tilera TILEPro */ +#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ +#define EM_TILEGX 191 /* Tilera TILE-Gx */ + + + +/* --------------------------- 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_type */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* 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 */ +#define PF_MASKOS 0x0ff00000 /* Spécifique à l'OS */ +#define PF_MASKPROC 0xf0000000 /* Spécifique au processeur */ + + + +/* ---------------------------- 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 64 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_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ + +#define SHT_DYNAMIC 6 /* Info. de liaison dynamique */ + +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + + +/* Valeurs possibles pour sh_flags */ + +#define SHF_WRITE (1 << 0) /* Accessible en écriture */ +#define SHF_ALLOC (1 << 1) /* Copie en mémoire pdt l'exec.*/ +#define SHF_EXECINSTR (1 << 2) /* Section exécutable */ +#define SHF_MERGE (1 << 4) /* Peut être fusionné */ +#define SHF_STRINGS (1 << 5) /* Contient des chaînes ('\0') */ +#define SHF_INFO_LINK (1 << 6) /* 'sh_info' contient un index */ +#define SHF_LINK_ORDER (1 << 7) /* Préservation de l'ordre */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Gestion non standard requise*/ +#define SHF_GROUP (1 << 9) /* Section membre d'un groupe */ +#define SHF_TLS (1 << 10) /* Données pour un thread local*/ + +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ + + + + + +/* ----------------------------- 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 */ + + +#define DT_PLTGOT 3 /* Processor defined value */ + +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ + +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ + +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ + + + +/* ---------------------------- 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 */ + +/* Type de relocalisation (ARM) */ + +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ + + + +/* --------------------------- NOTES ARBITRAIRES LAISSEES --------------------------- */ + + +/** + * Notes contenues dans un fichier ELF. + * Se rapporter au chapitre 5, partie "Note Section", des spécifications ABI + * du Système V pour d'avantage d'informations. + */ + +typedef struct _elf_note +{ + uint32_t namesz; /* Taille du nom éventuel */ + uint32_t descsz; /* Qté de données éventuelles */ + uint32_t type; /* Indication supplémentaire */ + + const char *name; /* Auteur de la note */ + const void *desc; /* Données complémentaires */ + +} elf_note; + + + +#endif /* _FORMAT_ELF_ELF_DEF_H */ diff --git a/plugins/elf/elf_def_arm.h b/plugins/elf/elf_def_arm.h new file mode 100644 index 0000000..5b0191e --- /dev/null +++ b/plugins/elf/elf_def_arm.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf_def_arm.h - liste des structures et constantes utilisées par le format ELF et dédiées à ARM + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_ELF_DEF_ARM_H +#define _FORMAT_ELF_ELF_DEF_ARM_H + + +#include "elf_def.h" + + + +/* Valeurs spécifiques pour le champ p_type des en-tête de programme */ + +#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment */ + + +/* Valeurs spécifiques pour le champ sh_type des en-têtes de section */ + +#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section */ +#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details */ +#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section */ + + + +#endif /* _FORMAT_ELF_ELF_DEF_ARM_H */ diff --git a/plugins/elf/helper_arm.c b/plugins/elf/helper_arm.c new file mode 100644 index 0000000..737e4ac --- /dev/null +++ b/plugins/elf/helper_arm.c @@ -0,0 +1,173 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helper_x86.c - gestion auxiliaire de l'architecture x86 + * + * Copyright (C) 2014-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "helper_arm.h" + + +#include + + +#include + + +#include "elf_def_arm.h" +#include "elf-int.h" +#include "symbols.h" + + + +/****************************************************************************** +* * +* Paramètres : p_type = type associé à un en-tête de programme. * +* * +* Description : Fournit la description humaine d'un type de segment ELF. * +* * +* Retour : Désignation prête à emploi ou NULL si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_elf_program_arm_type_desc(uint32_t p_type) +{ + const char *result; /* Description à renvoyer */ + +#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break; + + switch(p_type) + { + MAKE_STRING_FROM_PT(PT_ARM_EXIDX); + + default: + result = NULL; + break; + } + + return result; + +} + + +/****************************************************************************** +* * +* 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 relogés. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) +{ + bool result; /* Bilan à retourner */ + phys_t rel_start; /* Début de la zone à traiter */ + phys_t rel_size; /* Taille de cette même zone */ + GBinFormat *base; /* Autre version du format */ + phys_t iter; /* Boucle de parcours */ + elf_rel reloc; /* Infos de relocalisation */ + off_t index; /* Indice de la portion visée */ + elf_sym sym; /* Définition complète */ + const char *name; /* Nom du symbole trouvé */ + + + + virt_t virt; /* Adresse en mémoire virtuelle*/ + virt_t final_virt; /* Adresse virtuelle retenue */ + bool status; /* Bilan d'une opération */ + vmpa2t addr; /* Localisation d'une routine */ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + mrange_t range; /* Couverture mémoire associée */ + + + + + result = true; + + + + get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); + + base = G_BIN_FORMAT(format); + + for (iter = rel_start; iter < (rel_start + rel_size); ) + { + result = read_elf_relocation(format, &iter, &reloc); + if (!result) break; + + index = ELF_REL_SYM(format, reloc); + + if (!get_elf_symbol_by_index(format, dynsym, index, &sym)) + continue; + + name = get_elf_symbol_name(format, dynsym, dynstr, index); + if (name == NULL) + { + /* FIXME */ + name = "unknown"; + } + + switch (ELF_REL_TYPE(format, reloc)) + { + case R_ARM_JUMP_SLOT: + + virt = ELF_SYM(format, sym, st_value); + if (virt == 0) continue; + + final_virt = virt & ~0x1; + + status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr); + if (!status) continue; + + routine = try_to_demangle_routine(name); + symbol = G_BIN_SYMBOL(routine); + + init_mrange(&range, &addr, 0); + g_binary_symbol_set_range(symbol, &range); + + /* Comptabilisation pour le désassemblage brut */ + g_binary_format_register_code_point(base, virt, false); + + break; + + default: + assert(false); + symbol = NULL; + break; + + } + + if (symbol != NULL) + g_binary_format_add_symbol(base, symbol); + + } + + return result; + +} diff --git a/plugins/elf/helper_arm.h b/plugins/elf/helper_arm.h new file mode 100644 index 0000000..e971ed6 --- /dev/null +++ b/plugins/elf/helper_arm.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helper_arm.h - prototypes pour la gestion auxiliaire de l'architecture ARM + * + * Copyright (C) 2014-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_HELPER_ARM_H +#define _FORMAT_ELF_HELPER_ARM_H + + +#include "section.h" + + + +/* Fournit la description humaine d'un type de segment ELF. */ +const char *get_elf_program_arm_type_desc(uint32_t); + +/* Charge en mémoire la liste des symboles relogés. */ +bool load_elf_arm_relocated_symbols(GElfFormat *, const elf_shdr *, const elf_shdr *, const elf_shdr *); + + + +#endif /* _FORMAT_ELF_HELPER_ARM_H */ diff --git a/plugins/elf/loading.c b/plugins/elf/loading.c new file mode 100644 index 0000000..168c9c6 --- /dev/null +++ b/plugins/elf/loading.c @@ -0,0 +1,291 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loading.c - chargements parallèles des symboles de format ELF + * + * Copyright (C) 2016-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "loading.h" + + +#include +#include +#include + + +#include "elf-int.h" +#include "section.h" + + + +/* Fraction de routines à limiter (instance) */ +struct _GElfLoading +{ + GDelayedWork parent; /* A laisser en premier */ + + GElfFormat *format; /* Format à faire évoluer */ + + union + { + struct + { + const elf_shdr *section; /* Section à éplucher */ + bool use_virt; /* Représentatio par défaut */ + + elf_shdr strtab; /* Section .strtab trouvée */ + bool has_strtab; /* Présence de cette section */ + + }; + + }; + + elf_loading_cb callback; /* Routine de traitement finale*/ + phys_t first; /* Position du premier élément */ + phys_t begin; /* Point de départ du parcours */ + phys_t end; /* Point d'arrivée exclu */ + + activity_id_t id; /* Identifiant pour messages */ + +}; + +/* Fraction de routines à limiter (classe) */ +struct _GElfLoadingClass +{ + GDelayedWorkClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des tâches des chargements pour ELF. */ +static void g_elf_loading_class_init(GElfLoadingClass *); + +/* Initialise une tâche de chargements pour ELF. */ +static void g_elf_loading_init(GElfLoading *); + +/* Supprime toutes les références externes. */ +static void g_elf_loading_dispose(GElfLoading *); + +/* Procède à la libération totale de la mémoire. */ +static void g_elf_loading_finalize(GElfLoading *); + +/* Assure le chargement pour un format ELF en différé. */ +static void g_elf_loading_process(GElfLoading *, GtkStatusStack *); + + + +/* Indique le type défini pour les tâches de chargements pour format ELF. */ +G_DEFINE_TYPE(GElfLoading, g_elf_loading, G_TYPE_DELAYED_WORK); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des tâches des chargements pour ELF. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_loading_class_init(GElfLoadingClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDelayedWorkClass *work; /* Version en classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_loading_dispose; + object->finalize = (GObjectFinalizeFunc)g_elf_loading_finalize; + + work = G_DELAYED_WORK_CLASS(klass); + + work->run = (run_task_fc)g_elf_loading_process; + +} + + +/****************************************************************************** +* * +* Paramètres : loading = instance à initialiser. * +* * +* Description : Initialise une tâche de chargements pour ELF. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_loading_init(GElfLoading *loading) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : loading = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_loading_dispose(GElfLoading *loading) +{ + G_OBJECT_CLASS(g_elf_loading_parent_class)->dispose(G_OBJECT(loading)); + +} + + +/****************************************************************************** +* * +* Paramètres : loading = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_loading_finalize(GElfLoading *loading) +{ + G_OBJECT_CLASS(g_elf_loading_parent_class)->finalize(G_OBJECT(loading)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = = ensemble d'instructions désassemblées. * +* section = prototypes existants à insérer. * +* use_virt = quantité de ces prototypes. * +* first = position du premier élément. * +* begin = point de départ du parcours de liste. * +* end = point d'arrivée exclu du parcours. * +* id = identifiant du message affiché à l'utilisateur. * +* callback = routine de traitements particuliers. * +* * +* Description : Crée une tâche de chargement pour ELF différée. * +* * +* Retour : Tâche créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GElfLoading *g_elf_loading_new(GElfFormat *format, const elf_shdr *section, bool use_virt, phys_t first, phys_t begin, phys_t end, activity_id_t id, elf_loading_cb callback) +{ + GElfLoading *result; /* Tâche à retourner */ + + result = g_object_new(G_TYPE_ELF_LOADING, NULL); + + result->format = format; + + result->section = section; + result->use_virt = use_virt; + + result->has_strtab = find_elf_section_by_index(format, + ELF_SHDR(format, *section, sh_link), + &result->strtab); + + result->callback = callback; + result->first = first; + result->begin = begin; + result->end = end; + + result->id = id; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : study = étude de routines à mener. * +* status = barre de statut à tenir informée. * +* * +* Description : Assure le chargement pour un format ELF en différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status) +{ + phys_t iter; /* Boucle de parcours */ + phys_t old; /* Sauvegarde du point d'avant */ + bool ret; /* Bilan d'un appel */ + + for (iter = loading->begin; iter < loading->end; ) + { + old = iter; + ret = loading->callback(loading, loading->format, &iter); + + if (!ret) + { + log_variadic_message(LMT_ERROR, _("Error while loading ELF data @ 0x%08x!"), old); + break; + } + + gtk_status_stack_update_activity_value(status, loading->id, 1); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : loading = chargement pour ELF à mener. * +* section = prototypes existants à insérer. [OUT] * +* use_virt = quantité de ces prototypes. [OUT] * +* strtab = informations quant à la table des chaînes. [OUT]* +* has_strtab = validité du champ précédemment renseigné. [OUT] * +* first = position du premier élément. [OUT] * +* * +* Description : Fournit les infos utiles au chargement de symbols internes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_elf_loading_get_internal_info(GElfLoading *loading, const elf_shdr **section, bool *use_virt, const elf_shdr **strtab, bool *has_strtab, phys_t *first) +{ + *section = loading->section; + *use_virt = loading->use_virt; + + *strtab = &loading->strtab; + *has_strtab = loading->has_strtab; + + *first = loading->first; + +} diff --git a/plugins/elf/loading.h b/plugins/elf/loading.h new file mode 100644 index 0000000..ff5d7bb --- /dev/null +++ b/plugins/elf/loading.h @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loading.h - prototypes pour les chargements parallèles des symboles de format ELF + * + * Copyright (C) 2016-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_LOADING_H +#define _FORMAT_ELF_LOADING_H + + +#include + + +#include "elf.h" + + + + +//#include "../routine.h" +//#include "../../arch/processor.h" +//#include "../../format/executable.h" +//#include "../../gtkext/gtkstatusstack.h" + + + +#define G_TYPE_ELF_LOADING g_elf_loading_get_type() +#define G_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_elf_loading_get_type(), GElfLoading)) +#define G_IS_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_elf_loading_get_type())) +#define G_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ELF_LOADING, GElfLoadingClass)) +#define G_IS_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ELF_LOADING)) +#define G_ELF_LOADING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ELF_LOADING, GElfLoadingClass)) + + +/* Fraction de loading à limiter (instance) */ +typedef struct _GElfLoading GElfLoading; + +/* Fraction de loading à limiter (classe) */ +typedef struct _GElfLoadingClass GElfLoadingClass; + + +/* Assure un chargement pour ELF en différé. */ +typedef bool (* elf_loading_cb) (GElfLoading *, GElfFormat *, phys_t *); + + +/* Indique le type défini pour les tâches de chargements pour format ELF. */ +GType g_elf_loading_get_type(void); + +/* Crée une tâche de chargement pour ELF différée. */ +GElfLoading *g_elf_loading_new(GElfFormat *, const elf_shdr *, bool, phys_t, phys_t, phys_t, activity_id_t, elf_loading_cb); + +/* Fournit les infos utiles au chargement de symbols internes. */ +void g_elf_loading_get_internal_info(GElfLoading *, const elf_shdr **, bool *, const elf_shdr **, bool *, phys_t *); + + + +#endif /* _FORMAT_ELF_LOADING_H */ diff --git a/plugins/elf/program.c b/plugins/elf/program.c new file mode 100644 index 0000000..3016feb --- /dev/null +++ b/plugins/elf/program.c @@ -0,0 +1,217 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * program.c - gestion des en-têtes de programme d'un ELF + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "program.h" + + +#include "elf-int.h" +#include "helper_arm.h" + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* p_type = type associé à un en-tête de programme. * +* * +* Description : Fournit la description humaine d'un type de segment ELF. * +* * +* Retour : Désignation prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_elf_program_type_desc(const GElfFormat *format, uint32_t p_type) +{ + const char *result; /* Description à renvoyer */ + +#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break; + + switch(p_type) + { + MAKE_STRING_FROM_PT(PT_NULL); + MAKE_STRING_FROM_PT(PT_LOAD); + MAKE_STRING_FROM_PT(PT_DYNAMIC); + MAKE_STRING_FROM_PT(PT_INTERP); + MAKE_STRING_FROM_PT(PT_NOTE); + MAKE_STRING_FROM_PT(PT_SHLIB); + MAKE_STRING_FROM_PT(PT_PHDR); + MAKE_STRING_FROM_PT(PT_TLS); + MAKE_STRING_FROM_PT(PT_NUM); + MAKE_STRING_FROM_PT(PT_LOOS); + MAKE_STRING_FROM_PT(PT_GNU_EH_FRAME); + MAKE_STRING_FROM_PT(PT_GNU_STACK); + MAKE_STRING_FROM_PT(PT_GNU_RELRO); + MAKE_STRING_FROM_PT(PT_LOSUNW); + MAKE_STRING_FROM_PT(PT_SUNWSTACK); + MAKE_STRING_FROM_PT(PT_HIOS); + MAKE_STRING_FROM_PT(PT_LOPROC); + MAKE_STRING_FROM_PT(PT_HIPROC); + + default: + result = NULL; + break; + + } + + if (result == NULL) + switch (ELF_HDR(format, format->header, e_machine)) + { + case EM_ARM: + result = get_elf_program_arm_type_desc(p_type); + break; + + default: + break; + + } + + if (result == NULL) + switch(p_type) + { + MAKE_STRING_FROM_PT(PT_LOOS); + MAKE_STRING_FROM_PT(PT_HIOS); + MAKE_STRING_FROM_PT(PT_LOPROC); + MAKE_STRING_FROM_PT(PT_HIPROC); + + default: + result = "PT_???"; + break; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* index = indice de la section recherchée. * +* program = ensemble d'informations à faire remonter. [OUT] * +* * +* Description : Recherche un programme donné au sein de binaire par indice. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_program_by_index(const GElfFormat *format, uint16_t index, elf_phdr *program) +{ + off_t offset; /* Emplacement à venir lire */ + + if (index >= ELF_HDR(format, format->header, e_phnum)) return false; + + offset = ELF_HDR(format, format->header, e_phoff) + + ELF_HDR(format, format->header, e_phentsize) * index; + + return read_elf_program_header(format, offset, program); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* off = position physique à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une position physique. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *format, phys_t off, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + elf_phdr program; /* Programme à analyser */ + virt_t addr; /* Adresse virtuelle calculée */ + + result = false; + + for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++) + { + find_elf_program_by_index(format, i, &program); + + if (ELF_PHDR(format, program, p_offset) <= off + && off < (ELF_PHDR(format, program, p_offset) + ELF_PHDR(format, program, p_filesz))) + { + addr = ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_offset) - off; + init_vmpa(pos, off, addr); + result = true; + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *format, virt_t addr, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + elf_phdr program; /* Programme à analyser */ + phys_t off; /* Position physique calculée */ + + result = false; + + for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++) + { + find_elf_program_by_index(format, i, &program); + + if (ELF_PHDR(format, program, p_vaddr) <= addr + && addr < (ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_filesz))) + { + off = ELF_PHDR(format, program, p_offset) + addr - ELF_PHDR(format, program, p_vaddr); + init_vmpa(pos, off, addr); + result = true; + } + + } + + return result; + +} diff --git a/plugins/elf/program.h b/plugins/elf/program.h new file mode 100644 index 0000000..bf05d2a --- /dev/null +++ b/plugins/elf/program.h @@ -0,0 +1,47 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * program.h - prototypes pour la gestion des en-têtes de programme d'un ELF + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_PROGRAM_H +#define _FORMAT_ELF_PROGRAM_H + + +#include "elf.h" +#include "elf_def.h" + + + +/* Fournit la description humaine d'un type de segment ELF. */ +const char *get_elf_program_type_desc(const GElfFormat *, uint32_t); + +/* Recherche un programme donné au sein de binaire par indice. */ +bool find_elf_program_by_index(const GElfFormat *, uint16_t, elf_phdr *); + +/* Fournit l'emplacement correspondant à une position physique. */ +bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *, phys_t, vmpa2t *); + +/* Fournit l'emplacement correspondant à une adresse virtuelle. */ +bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *, virt_t, vmpa2t *); + + + +#endif /* _FORMAT_ELF_PROGRAM_H */ diff --git a/plugins/elf/python/Makefile.am b/plugins/elf/python/Makefile.am new file mode 100644 index 0000000..4de3e3c --- /dev/null +++ b/plugins/elf/python/Makefile.am @@ -0,0 +1,15 @@ + +noinst_LTLIBRARIES = libelfpython.la + +libelfpython_la_SOURCES = \ + elf.h elf.c \ + module.h module.c + + +libelfpython_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../src -I../../.. + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/elf/python/elf.c b/plugins/elf/python/elf.c new file mode 100644 index 0000000..1f5ddb2 --- /dev/null +++ b/plugins/elf/python/elf.c @@ -0,0 +1,198 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf.c - équivalent Python du fichier "format/elf/elf.c" + * + * Copyright (C) 2013-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "elf.h" + + +#include + + +#include +#include +#include +#include +#include +#include + + +#include "../elf.h" + + + +/* Crée un nouvel objet Python de type 'ElfFormat'. */ +static PyObject *py_elf_format_new(PyTypeObject *, PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ElfFormat'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + PyObject *content_obj; /* Objet pour le contenu */ + PyObject *parent_obj; /* Objet pour le parent */ + PyObject *status_obj; /* Objet pour la progression */ + int ret; /* Bilan de lecture des args. */ + GBinContent *content; /* Instance GLib du contenu */ + GExeFormat *parent; /* Instance GLib du parent */ + GtkStatusStack *status; /* Instance GTK de suivi */ + GBinFormat *format; /* Création GLib à transmettre */ + + ret = PyArg_ParseTuple(args, "O!OO", get_python_binary_content_type(), &content_obj, &parent_obj, &status_obj); + if (!ret) return NULL; + + content = G_BIN_CONTENT(pygobject_get(content_obj)); + + if (parent_obj == Py_None) + parent = NULL; + + else + { + ret = PyObject_IsInstance(parent_obj, (PyObject *)get_python_executable_format_type()); + if (!ret) + { + PyErr_SetString(PyExc_TypeError, _("The second argument must be a container format or None.")); + return NULL; + } + + parent = G_EXE_FORMAT(pygobject_get(parent_obj)); + + } + + if (status_obj == Py_None) + status = NULL; + + else + { + ret = PyObject_IsInstance(status_obj, (PyObject *)get_python_binary_content_type()); + if (!ret) + { + PyErr_SetString(PyExc_TypeError, _("The third argument must be a status bar object or None.")); + return NULL; + } + + status = GTK_STATUS_STACK(pygobject_get(status_obj)); + + } + + format = g_elf_format_new(content, parent, status); + if (format == NULL) + { + PyErr_SetString(PyExc_RuntimeError, _("Unable to load the ELF format.")); + return NULL; + } + + result = pygobject_new(G_OBJECT(format)); + + g_object_unref(format); + + return (PyObject *)result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_elf_format_type(void) +{ + static PyMethodDef py_elf_format_methods[] = { + { NULL } + }; + + static PyGetSetDef py_elf_format_getseters[] = { + { NULL } + }; + + static PyTypeObject py_elf_format_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.format.elf.ElfFormat", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide Elf format", + + .tp_methods = py_elf_format_methods, + .tp_getset = py_elf_format_getseters, + .tp_new = (newfunc)py_elf_format_new + + }; + + return &py_elf_format_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.format.elf.ElfFormat'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_elf_format(PyObject *module) +{ + PyTypeObject *py_elf_format_type; /* Type Python 'ElfFormat' */ + PyObject *dict; /* Dictionnaire du module */ + + py_elf_format_type = get_python_elf_format_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_ELF_FORMAT, + py_elf_format_type, get_python_executable_format_type())) + return false; + + return true; + +} diff --git a/plugins/elf/python/elf.h b/plugins/elf/python/elf.h new file mode 100644 index 0000000..cf6a706 --- /dev/null +++ b/plugins/elf/python/elf.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * elf.h - prototypes pour l'équivalent Python du fichier "format/elf/elf.h" + * + * Copyright (C) 2013-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H +#define _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_elf_format_type(void); + +/* Prend en charge l'objet 'pychrysalide.format.elf.ElfFormat'. */ +bool register_python_elf_format(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H */ diff --git a/plugins/elf/python/module.c b/plugins/elf/python/module.c new file mode 100644 index 0000000..faf0458 --- /dev/null +++ b/plugins/elf/python/module.c @@ -0,0 +1,91 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire elf en tant que module + * + * Copyright (C) 2013-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "module.h" + + +#include + + +#include + + +#include "elf.h" + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Ajoute le module 'format.elf' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_format_elf_module_to_python_module(void) +{ + bool result; /* Bilan à retourner */ + PyObject *super; /* Module à compléter */ + PyObject *module; /* Sous-module mis en place */ + int ret; /* Bilan d'un appel */ + + static PyModuleDef py_chrysalide_elf_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.format.elf", + .m_doc = "Python module for Chrysalide.format.elf", + + .m_size = -1, + + }; + + result = false; + + super = get_access_to_python_module("pychrysalide.format"); + + module = PyModule_Create(&py_chrysalide_elf_module); + if (module == NULL) return false; + + ret = PyState_AddModule(super, &py_chrysalide_elf_module); + if (ret != 0) goto loading_failed; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.format.elf"); + if (ret != 0) goto loading_failed; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "elf", module); + if (ret != 0) goto loading_failed; + + result = register_python_elf_format(module); + + loading_failed: + + return result; + +} diff --git a/plugins/elf/python/module.h b/plugins/elf/python/module.h new file mode 100644 index 0000000..de3ce42 --- /dev/null +++ b/plugins/elf/python/module.h @@ -0,0 +1,38 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire elf en tant que module + * + * Copyright (C) 2013-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H +#define _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H + + +#include + + + +/* Ajoute le module 'format.elf' au module Python. */ +bool add_format_elf_module_to_python_module(void); + + + +#endif /* _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H */ diff --git a/plugins/elf/section.c b/plugins/elf/section.c new file mode 100644 index 0000000..556c0ed --- /dev/null +++ b/plugins/elf/section.c @@ -0,0 +1,425 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * section.h - prototypes pour la gestion des sections d'un ELF + * + * Copyright (C) 2008-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "section.h" + + +#include +#include + + +#include "elf-int.h" + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* index = indice de la section recherchée. * +* section = ensemble d'informations à faire remonter. [OUT] * +* * +* Description : Recherche une section donnée au sein de binaire par indice. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shdr *section) +{ + phys_t offset; /* Emplacement à venir lire */ + + if (index >= ELF_HDR(format, format->header, e_shnum)) return false; + + offset = ELF_HDR(format, format->header, e_shoff) + + ELF_HDR(format, format->header, e_shentsize) * index; + + return read_elf_section_header(format, offset, section); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* name = nom de la section recherchée. * +* section = ensemble d'informations à faire remonter. [OUT] * +* * +* Description : Recherche une section donnée au sein de binaire par nom. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_shdr *section) +{ + 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 */ + + if (!find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings)) + return false; + + result = false; + + for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) + { + find_elf_section_by_index(format, i, section); + + secname = extract_name_from_elf_string_section(format, &strings, + ELF_SHDR(format, *section, sh_name)); + + if (secname != NULL) + result = (strcmp(name, secname) == 0); + + } + + return result; + +} + + +/****************************************************************************** +* * +* 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. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_section_by_virtual_address(const GElfFormat *format, virt_t addr, elf_shdr *section) +{ + bool result; /* Bilan à faire remonter */ + uint16_t i; /* Boucle de parcours */ + + result = false; + + for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) + { + find_elf_section_by_index(format, i, section); + + result = (addr == ELF_SHDR(format, *section, sh_addr)); + + } + + return result; + +} + + +/****************************************************************************** +* * +* 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 type. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr **sections, size_t *count) +{ + uint16_t i; /* Boucle de parcours */ + elf_shdr section; /* Section à analyser */ + + *sections = NULL; + *count = 0; + + for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++) + { + find_elf_section_by_index(format, i, §ion); + + if (type == ELF_SHDR(format, section, sh_type)) + { + *sections = (elf_shdr *)realloc(*sections, ++(*count) * sizeof(elf_shdr)); + (*sections)[*count - 1] = section; + } + + } + + return (*count > 0); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* section = section à consulter. * +* offset = position de la section trouvée. [OUT] * +* size = taille 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. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, phys_t *offset, phys_t *size, virt_t *addr) +{ + *offset = ELF_SHDR(format, *section, sh_offset); + *size = ELF_SHDR(format, *section, sh_size); + + if (addr != NULL) + *addr = ELF_SHDR(format, *section, sh_addr); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* section = section à consulter. * +* range = emplacement de la fonction à renseigner. [OUT] * +* * +* Description : Fournit la localisation d'une section. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void get_elf_section_range(const GElfFormat *format, const elf_shdr *section, mrange_t *range) +{ + virt_t virt; /* Emplacement virtuel */ + vmpa2t tmp; /* Enregistrement intermédiaire*/ + + virt = ELF_SHDR(format, *section, sh_addr); + + if (virt == 0) + virt = VMPA_NO_VIRTUAL; + + init_vmpa(&tmp, ELF_SHDR(format, *section, sh_offset), virt); + + init_mrange(range, &tmp, ELF_SHDR(format, *section, sh_size)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* name = nom de la section recherchée. * +* offset = position de la section trouvée. [OUT] * +* size = taille 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. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, phys_t *offset, phys_t *size, virt_t *address) +{ + bool result; /* Bilan à retourner */ + elf_shdr section; /* Section trouvée ou non */ + + result = find_elf_section_by_name(format, name, §ion); + + if (result) + get_elf_section_content(format, §ion, offset, size, address); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* name = nom de la section recherchée. * +* range = emplacement de la fonction à renseigner. [OUT] * +* * +* Description : Recherche une zone donnée au sein de binaire par nom. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range) +{ + bool result; /* Bilan à retourner */ + elf_shdr section; /* Section trouvée ou non */ + + result = find_elf_section_by_name(format, name, §ion); + + if (result) + get_elf_section_range(format, §ion, range); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* section = section contenant des chaînes terminées par '\0'. * +* index = indice du premier caractères à cerner. * +* * +* Description : Identifie une chaîne de caractères dans une section adéquate.* +* * +* Retour : Pointeur vers la chaîne recherchée ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *extract_name_from_elf_string_section(const GElfFormat *format, const elf_shdr *section, off_t index) +{ + const char *result; /* Nom trouvé à renvoyer */ + phys_t last; /* Dernier '\0' possible */ + phys_t phys; /* Point de lecture physique */ + vmpa2t pos; /* Position de lecture */ + const GBinContent *content; /* Contenu binaire à lire */ + + last = ELF_SHDR(format, *section, sh_offset) + ELF_SHDR(format, *section, sh_size); + + phys = ELF_SHDR(format, *section, sh_offset) + index; + + if ((phys + 1) >= last) + return NULL; + + init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); + + content = G_BIN_FORMAT(format)->content; + + result = (const char *)g_binary_content_get_raw_access(content, &pos, 1); + + if (result == NULL) + return NULL; + + if ((phys + strlen(result)) > last) + return NULL; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* off = position physique à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une position physique. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_offset_into_vmpa_using_elf_sections(const GElfFormat *format, phys_t off, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + elf_shdr section; /* Section à analyser */ + virt_t addr; /* Adresse virtuelle calculée */ + + result = false; + + for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) + { + find_elf_section_by_index(format, i, §ion); + + if (ELF_SHDR(format, section, sh_offset) <= off + && off < (ELF_SHDR(format, section, sh_offset) + ELF_SHDR(format, section, sh_size))) + { + addr = ELF_SHDR(format, section, sh_addr) + off - ELF_SHDR(format, section, sh_offset); + init_vmpa(pos, off, addr); + result = true; + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_address_into_vmpa_using_elf_sections(const GElfFormat *format, virt_t addr, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + elf_shdr section; /* Section à analyser */ + phys_t off; /* Position physique calculée */ + + result = false; + + for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) + { + find_elf_section_by_index(format, i, §ion); + + if (ELF_SHDR(format, section, sh_addr) <= addr + && addr < (ELF_SHDR(format, section, sh_addr) + ELF_SHDR(format, section, sh_size))) + { + off = ELF_SHDR(format, section, sh_offset) + addr - ELF_SHDR(format, section, sh_addr); + init_vmpa(pos, off, addr); + result = true; + } + + } + + return result; + +} diff --git a/plugins/elf/section.h b/plugins/elf/section.h new file mode 100644 index 0000000..f3be0f4 --- /dev/null +++ b/plugins/elf/section.h @@ -0,0 +1,68 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * section.h - prototypes pour la gestion des sections d'un ELF + * + * Copyright (C) 2008-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_SECTION_H +#define _FORMAT_ELF_SECTION_H + + +#include "elf.h" +#include "elf_def.h" + + + +/* 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 GElfFormat *, const char *, elf_shdr *); + +/* Recherche une section donnée au sein de binaire par type. */ +bool find_elf_section_by_virtual_address(const GElfFormat *, virt_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 GElfFormat *, const elf_shdr *, phys_t *, phys_t *, virt_t *); + +/* Fournit la localisation d'une section. */ +void get_elf_section_range(const GElfFormat *, const elf_shdr *, mrange_t *); + +/* Recherche une zone donnée au sein de binaire par nom. */ +bool find_elf_section_content_by_name(const GElfFormat *, const char *, phys_t *, phys_t *, virt_t *); + +/* Recherche une zone donnée au sein de binaire par nom. */ +bool find_elf_section_range_by_name(const GElfFormat *, const char *, mrange_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 *, off_t); + +/* Fournit l'emplacement correspondant à une position physique. */ +bool translate_offset_into_vmpa_using_elf_sections(const GElfFormat *, phys_t, vmpa2t *); + +/* Fournit l'emplacement correspondant à une adresse virtuelle. */ +bool translate_address_into_vmpa_using_elf_sections(const GElfFormat *, virt_t, vmpa2t *); + + + +#endif /* _FORMAT_ELF_SECTION_H */ diff --git a/plugins/elf/strings.c b/plugins/elf/strings.c new file mode 100644 index 0000000..3bec414 --- /dev/null +++ b/plugins/elf/strings.c @@ -0,0 +1,250 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * strings.c - recherche des chaînes contenues dans un ELF + * + * Copyright (C) 2008-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "strings.h" + + +#include +#include +#include +#include +#include + + +#include + + +#include "elf-int.h" +#include "section.h" + + + +/* Enregistre toutes les chaînes de caractères trouvées. */ +static bool parse_elf_string_data(GElfFormat *, phys_t, phys_t, virt_t); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à analyser. * +* * +* Description : Charge en mémoire toutes les chaînes trouvées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_all_elf_strings(GElfFormat *format) +{ + bool got_string; /* Indique un remplissage */ + phys_t str_start; /* Début de section */ + phys_t str_size; /* Taille de section */ + virt_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 #1 */ + phys_t max; /* Borne à ne pas dépasser */ + phys_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_addr)) + got_string |= parse_elf_string_data(format, str_start, str_size, str_addr); + + else + { + if (find_elf_sections_by_type(format, SHT_PROGBITS, §ions, &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, §ions[i], &str_start, &str_size, &str_addr); + got_string |= parse_elf_string_data(format, str_start, str_size, str_addr); + } + + free(sections); + + } + + } + + /* Chaîne de caractères déclarées */ + + if (find_elf_sections_by_type(format, SHT_STRTAB, §ions, &count)) + { + for (i = 0; i < count; i++) + { + get_elf_section_content(format, §ions[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 (!got_string) + { + max = ELF_HDR(format, format->header, e_phoff) + + ELF_HDR(format, format->header, e_phnum) * ELF_SIZEOF_PHDR(format); + + for (iter = ELF_HDR(format, format->header, e_phoff); iter < max; iter += ELF_SIZEOF_PHDR(format)) + { + 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)); + + } + + } + + return true; + +} + + +/****************************************************************************** +* * +* 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 : true si des chaînes ont été ajoutées sans erreur, ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t address) +{ + bool result; /* Bilan à faire remonter */ + GBinFormat *base; /* Autre version du format */ + GBinContent *content; /* Contenu binaire à lire */ + const bin_t *data; /* Contenu complet et original */ + vmpa2t pos; /* Tête de lecture */ + bool cut; /* Séparation nette ? */ + phys_t i; /* Boucle de parcours */ + phys_t end; /* Position de fin de chaîne */ + GArchInstruction *instr; /* Instruction décodée */ + bool inserted; /* Bilan d'une insertion */ + const mrange_t *range; /* Espace occupé par une chaîne*/ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *label; /* Désignation de la chaîne */ + + if (address == 0) + return false; + + result = false; + + /* Préparation des accès */ + + base = G_BIN_FORMAT(format); + + content = g_binary_format_get_content(base); + + init_vmpa(&pos, start, address); + + data = g_binary_content_get_raw_access(content, &pos, size); + + if (data == NULL) + goto pesd_error; + + /* Boucle de parcours */ + + cut = true; + + for (i = 0; i < size; i++) + if (isprint(data[i])) + { + for (end = i + 1; end < size; end++) + if (!isprint(data[end])) break; + + if (end < size && isspace(data[end])) + end++; + + if (end < size && data[end] == '\0') + end++; + + init_vmpa(&pos, start + i, address + i); + + instr = g_raw_instruction_new_array(content, MDS_8_BITS, end - i, &pos, format->endian); + assert(instr != NULL); + + g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); + + inserted = g_preload_info_add_instruction(base->info, instr); + + if (inserted) + { + range = g_arch_instruction_get_range(instr); + + symbol = g_binary_symbol_new(range, STP_RO_STRING); + g_binary_format_add_symbol(base, symbol); + + /* Jointure avec la chaîne précédente ? */ + + if (cut) + { + label = create_string_label(base, get_mrange_addr(range), end - i); + + g_binary_symbol_set_alt_label(symbol, label); + + free(label); + + } + + } + + /* Conclusion */ + + cut = (data[end - 1] == '\0'); + + i = end - 1; + result = true; + + } + else cut = true; + + pesd_error: + + g_object_unref(G_OBJECT(content)); + + return result; + +} diff --git a/plugins/elf/strings.h b/plugins/elf/strings.h new file mode 100644 index 0000000..bea52da --- /dev/null +++ b/plugins/elf/strings.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * strings.h - prototypes pour la recherche des chaînes contenues dans un ELF + * + * Copyright (C) 2008-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_STRINGS_H +#define _FORMAT_ELF_STRINGS_H + + +#include "elf.h" + + + +/*Charge en mémoire toutes les chaînes trouvées. */ +bool find_all_elf_strings(GElfFormat *); + + + +#endif /* _FORMAT_ELF_STRINGS_H */ diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c new file mode 100644 index 0000000..292913b --- /dev/null +++ b/plugins/elf/symbols.c @@ -0,0 +1,891 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.c - gestion des symboles d'un ELF + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "symbols.h" + + +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include + + +#include "dynamic.h" +#include "elf-int.h" +#include "helper_arm.h" +#include "loading.h" +#include "program.h" +#include "section.h" + + + + + + + + + + +/* Enregistre un point d'entrée au sein d'un binaire ELF. */ +static void register_elf_entry_point(GElfFormat *, virt_t, phys_t, GBinRoutine *); + +/* Enumère tous les points d'entrée principaux d'un binaire ELF. */ +static bool load_all_elf_basic_entry_points(GElfFormat *); + + + + + + + + + +/* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */ + + +/* Assure le chargement des symboles internes ELF en différé. */ +static bool do_elf_internal_symbol_loading(GElfLoading *, GElfFormat *, phys_t *); + +/* Charge tous les symboles internes possibles. */ +static bool load_elf_internal_symbols(GElfFormat *, wgroup_id_t, GtkStatusStack *); + + + +/* -------------------------- 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. * + status = barre de statut à tenir informée. * +* * +* Description : Charge en mémoire la liste humaine des symboles. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_elf_symbols(GElfFormat *format, GtkStatusStack *status) +{ + bool result; /* Bilan à retourner */ + wgroup_id_t gid; /* Identifiant pour les tâches */ + + elf_shdr *sections; /* Groupe de sections trouvées */ + size_t count; /* Quantité de données */ + + result = true; + + gid = g_work_queue_define_work_group(get_work_queue()); + + /* Symboles internes */ + + result &= load_elf_internal_symbols(format, gid, status); + + + + + /* Symboles externes */ + + if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) + { + log_variadic_message(LMT_INFO, _("Binary is dynamically linked")); + + result &= load_elf_external_symbols(format, §ions[0]); + + free(sections); + + } + else log_variadic_message(LMT_INFO, _("Binary is statically linked")); + + + + + /* Symboles d'entrée, si encore besoin */ + + /** + * Le tri en préalable + */ + + + + + + result &= load_all_elf_basic_entry_points(format); + + return result; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* vaddr = adresse virtuelle du symbole à insérer. * +* len = taille de la routine à ajouter. * +* routine = représentation de la fonction repérée. * +* * +* Description : Enregistre un point d'entrée au sein d'un binaire ELF. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t len, GBinRoutine *routine) +{ + GBinFormat *base; /* Version basique du format */ + virt_t final_vaddr; /* Adresse virtuelle retenue */ + bool status; /* Bilan d'une opération */ + vmpa2t addr; /* Localisation d'une routine */ + mrange_t range; /* Couverture mémoire associée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + /* Localisation complète du symbole */ + + if (ELF_HDR(format, format->header, e_machine) == EM_ARM) + final_vaddr = vaddr & ~0x1; + else + final_vaddr = vaddr; + + status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_vaddr, &addr); + if (!status) return; + + /* Comptabilisation en tant que symbole */ + + if (g_binary_format_find_symbol_at(G_BIN_FORMAT(format), &addr, &symbol)) + g_object_unref(G_OBJECT(routine)); + + else + { + base = G_BIN_FORMAT(format); + + init_mrange(&range, &addr, len); + + symbol = G_BIN_SYMBOL(routine); + + g_binary_symbol_set_range(symbol, &range); + g_binary_symbol_set_target_type(symbol, STP_ENTRY_POINT); + + g_binary_format_add_symbol(base, symbol); + + /* Comptabilisation pour le désassemblage brut */ + g_binary_format_register_code_point(base, vaddr, true); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Enumère tous les points d'entrée principaux d'un binaire ELF.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool load_all_elf_basic_entry_points(GElfFormat *format) +{ + virt_t ep; /* Point d'entrée détecté */ + GBinRoutine *routine; /* Routine à associer à un pt. */ + elf_phdr dynamic; /* En-tête de programme DYNAMIC*/ + elf_dyn item_a; /* Premier élément DYNAMIC */ + elf_dyn item_b; /* Second élément DYNAMIC */ + const GBinContent *content; /* Contenu binaire à lire */ + phys_t length; /* Taille totale du contenu */ + bool status; /* Bilan d'une opération */ + vmpa2t pos; /* Tête de lecture courante */ + uint32_t virt_32; /* Adresse virtuelle sur 32b */ + uint64_t virt_64; /* Adresse virtuelle sur 64b */ + + /* Point d'entrée principal éventuel */ + + ep = ELF_HDR(format, format->header, e_entry); + + if (ep != 0x0) + { + routine = try_to_demangle_routine("entry_point"); + register_elf_entry_point(format, ep, 0, routine); + } + + /* Chargemet de l'en-tête de programme DYNAMIC */ + + if (!find_elf_dynamic_program_header(format, &dynamic)) + goto laebep_exit; + + /* Détection des constructeurs & destructeurs */ + + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_INIT, &item_a)) + { + ep = ELF_DYN(format, item_a, d_un.d_ptr); + + if (ep != 0x0) + { + routine = try_to_demangle_routine("init_function"); + register_elf_entry_point(format, ep, 0, routine); + } + + } + + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_FINI, &item_a)) + { + ep = ELF_DYN(format, item_a, d_un.d_ptr); + + if (ep != 0x0) + { + routine = try_to_demangle_routine("termination_function"); + register_elf_entry_point(format, ep, 0, routine); + } + + } + + void load_entry_points_from_array(GElfFormat *fmt, const elf_dyn *ar, const elf_dyn *sz, const char *prefix) + { + unsigned int i; /* Boucle de parcours */ + char fullname[64]; /* Désignation humaine */ + + assert(sizeof(fullname) >= (strlen(prefix) + sizeof(XSTR(UINT64_MAX) + 1))); + + content = G_BIN_FORMAT(fmt)->content; + + status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), + ELF_DYN(fmt, *ar, d_un.d_val), + &pos); + if (!status) return; + + length = get_phy_addr(&pos) + ELF_DYN(fmt, *sz, d_un.d_val); + + for (i = 0; get_phy_addr(&pos) < length; i++) + { + /** + * Selon la libc d'Android (https://www.codeaurora.org/.../android/bionic/linker/README.TXT) : + * + * DT_INIT_ARRAY + * Points to an array of function addresses that must be + * called, in-order, to perform initialization. Some of + * the entries in the array can be 0 or -1, and should + * be ignored. + * + * On étend le principe aux sections DT_FINI_ARRAY et DT_PREINIT_ARRAY. + */ + + if (fmt->is_32b) + { + status = g_binary_content_read_u32(content, &pos, fmt->endian, &virt_32); + status &= (virt_32 != 0x0 && virt_32 != 0xffffffff); + ep = virt_32; + } + else + { + status = g_binary_content_read_u64(content, &pos, fmt->endian, &virt_64); + status &= (virt_64 != 0x0 && virt_64 != 0xffffffffffffffff); + ep = virt_64; + } + + if (!status) break; + + snprintf(fullname, sizeof(fullname), "%s%u", prefix, i); + + routine = try_to_demangle_routine(fullname); + register_elf_entry_point(fmt, ep, 0, routine); + + } + + } + + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_INIT_ARRAY, &item_a)) + { + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_INIT_ARRAYSZ, &item_b)) + { + load_entry_points_from_array(format, &item_a, &item_b, "init_array_function_"); + } + + } + + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_FINI_ARRAY, &item_a)) + { + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_FINI_ARRAYSZ, &item_b)) + { + load_entry_points_from_array(format, &item_a, &item_b, "fini_array_function_"); + } + + } + + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PREINIT_ARRAY, &item_a)) + { + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PREINIT_ARRAYSZ, &item_b)) + { + load_entry_points_from_array(format, &item_a, &item_b, "preinit_array_function_"); + } + + } + + /* Identification de l'entrée de la PLT */ + + if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PLTGOT, &item_a)) + { + status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), + ELF_DYN(format, item_a, d_un.d_val), + &pos); + + if (status) + { + content = G_BIN_FORMAT(format)->content; + + /* On saute le premier élément... */ + if (format->is_32b) + status = g_binary_content_read_u32(content, &pos, format->endian, &virt_32); + else + status = g_binary_content_read_u64(content, &pos, format->endian, &virt_64); + + while (1) + { + if (format->is_32b) + { + status = g_binary_content_read_u32(content, &pos, format->endian, &virt_32); + ep = virt_32; + } + else + { + status = g_binary_content_read_u64(content, &pos, format->endian, &virt_64); + ep = virt_64; + } + + if (!status) break; + + if (ep != 0x0) + { + routine = try_to_demangle_routine("plt_entry"); + register_elf_entry_point(format, ep, 0, routine); + break; + } + + } + + } + + } + + laebep_exit: + + return true; + +} + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* sym = section comprenant les symboles à venir lire. * +* index = indice de l'entrée à venir lire. * +* symbol = ensemble d'informations lues. [OUT] * +* * +* Description : Récupère la définition complète d'un symbole donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool get_elf_symbol_by_index(GElfFormat *format, const elf_shdr *sym, off_t index, elf_sym *symbol) +{ + phys_t sym_start; /* Début de section */ + phys_t sym_size; /* Taille de section */ + phys_t offset; /* Emplacement à venir lire */ + + get_elf_section_content(format, sym, &sym_start, &sym_size, NULL); + + offset = sym_start + index * ELF_SIZEOF_SYM(format); + if ((offset + ELF_SIZEOF_SYM(format)) > (sym_start + sym_size)) return NULL; + + return read_elf_symbol(format, &offset, symbol); + +} + + +/****************************************************************************** +* * +* 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 */ + elf_sym symbol; /* Symbole aux infos visées */ + + result = NULL; + + if (get_elf_symbol_by_index(format, sym, index, &symbol)) + result = extract_name_from_elf_string_section(format, str, ELF_SYM(format, symbol, st_name)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DETAIL DES SYMBOLES INTERNES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : loading = chargement de symboles internes en cours. * +* format = format ELF à compléter. * +* iter = tête de lecture évoluant avec le temps. [OUT] * +* * +* Description : Assure le chargement des symboles internes ELF en différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *format, phys_t *iter) +{ + bool result; /* Bilan à retourner */ + elf_sym sym; /* Symbole aux infos visées */ + virt_t virt; /* Adresse virtuelle */ + const elf_shdr *section; /* Groupe de sections trouvées */ + bool use_virt; /* Choix de construction de nom*/ + const elf_shdr *strtab; /* Section .strtab trouvée */ + bool has_strtab; /* Présence de cette section */ + phys_t first; /* Position du premier élément */ + const char *name; /* Nom du symbole trouvé */ + GBinFormat *base; /* Version basique du format */ + vmpa2t addr; /* Localisation d'une routine */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ + virt_t final_virt; /* Adresse virtuelle retenue */ + mrange_t range; /* Couverture mémoire associée */ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + + result = read_elf_symbol(format, iter, &sym); + if (!result) goto geslp_done; + + /* On rejette les symboles qui ne sont pas définis au sein du binaire */ + + if (ELF_SYM(format, sym, st_shndx) == 0) goto geslp_done; + + /* Résolution précise d'adresse */ + + virt = ELF_SYM(format, sym, st_value); + if (virt == 0) goto geslp_done; + + + /* TODO */ + + //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value)); + + + //init_mrange(&range, &addr, 0); + + + /* Première ébauche de nom */ + + g_elf_loading_get_internal_info(loading, §ion, &use_virt, &strtab, &has_strtab, &first); + + if (!has_strtab) + name = NULL; + + else + name = get_elf_symbol_name(format, section, strtab, + ((*iter - first) / ELF_SIZEOF_SYM(format)) - 1); + + /* Traitements particuliers */ + + base = G_BIN_FORMAT(format); + + switch (ELF_ST_TYPE(format, sym)) + { + case STT_OBJECT: + + /* Ajustement de la position */ + + if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr)) + { + symbol = NULL; + break; + } + + /* Création d'un nom unique ? */ + + if (name == NULL) + { + strcpy(alt_name, "obj_"); + + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); + + name = alt_name; + + } + + + /* TODO */ + + symbol = NULL; + + + break; + + case STT_FUNC: + + /* Ajustement de la position */ + + if (ELF_HDR(format, format->header, e_machine) == EM_ARM) + final_virt = virt & ~0x1; + else + final_virt = virt; + + if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr)) + { + symbol = NULL; + break; + } + + init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); + + /* Création d'un nom unique ? */ + + if (name == NULL) + { + strcpy(alt_name, "func_"); + + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + + name = alt_name; + + } + + /* Routine */ + + routine = try_to_demangle_routine(name); + symbol = G_BIN_SYMBOL(routine); + + g_binary_symbol_set_range(symbol, &range); + + /* Comptabilisation pour le désassemblage brut */ + + g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false); + + break; + + default: + symbol = NULL; + break; + + } + + if (symbol != NULL) + g_binary_format_add_symbol(base, symbol); + + geslp_done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* gid = groupe de travail impliqué. * + status = barre de statut à tenir informée. * +* * +* Description : Charge tous les symboles internes possibles. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool load_elf_internal_symbols(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + bool result; /* Bilan à retourner */ + bool no_name; /* Choix de construction de nom*/ + activity_id_t msg; /* Message de progression */ + GWorkQueue *queue; /* Gestionnaire de différés */ + elf_shdr *dynsym_sections; /* Groupe de sections trouvées */ + size_t count; /* Quantité de données */ + elf_shdr *symtab_sections; /* Groupe de sections trouvées */ + size_t i; /* Boucle de parcours */ + + result = true; + + /* Charge tous les symboles définis dans une section */ + void add_all_symbols_from_section(const elf_shdr *section, bool use_virt, GWorkQueue *wq, activity_id_t id) + { + phys_t start; /* Début de la zone à traiter */ + phys_t size; /* Taille de cette même zone */ + phys_t sym_size; /* Taille de chaque symbole lu */ + guint runs_count; /* Qté d'exécutions parallèles */ + phys_t run_size; /* Volume réparti par exécution*/ + guint i; /* Boucle de parcours */ + phys_t begin; /* Début de zone de traitement */ + phys_t end; /* Fin d'un zone de traitement */ + GElfLoading *loading; /* Tâche de chargement à lancer*/ + + get_elf_section_content(format, section, &start, &size, NULL); + + sym_size = ELF_SIZEOF_SYM(format); + + runs_count = g_get_num_processors(); + + run_size = size / (sym_size * runs_count); + + gtk_status_stack_extend_activity(status, id, size / sym_size); + + for (i = 0; i < runs_count; i++) + { + begin = start + i * run_size * sym_size; + + if ((i + 1) == runs_count) + end = start + size; + else + end = begin + run_size * sym_size; + + loading = g_elf_loading_new(format, section, use_virt, start, begin, end, + id, do_elf_internal_symbol_loading); + + g_work_queue_schedule_work(wq, G_DELAYED_WORK(loading), gid); + + } + + } + + if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name)) + return false; + + msg = gtk_status_stack_add_activity(status, _("Loading internal symbols..."), 0); + + queue = get_work_queue(); + + if (find_elf_sections_by_type(format, SHT_DYNSYM, &dynsym_sections, &count)) + for (i = 0; i < count; i++) + add_all_symbols_from_section(&dynsym_sections[i], no_name, queue, msg); + + if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtab_sections, &count)) + for (i = 0; i < count; i++) + add_all_symbols_from_section(&symtab_sections[i], no_name, queue, msg); + + g_work_queue_wait_for_completion(queue, gid); + + gtk_status_stack_remove_activity(status, msg); + + if (dynsym_sections != NULL) free(dynsym_sections); + if (symtab_sections != NULL) free(symtab_sections); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* 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 GBinContent *content; /* Contenu binaire à lire */ + phys_t pos; /* Position de lecture */ + vmpa2t 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; + + for (pos = ELF_SHDR(format, *section, sh_offset); + result; + pos += ELF_SIZEOF_DYN(format)) + { + init_vmpa(&tmp, pos, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + result = g_binary_content_read_s32(content, &tmp, format->endian, &tag32); + if (tag32 == type) break; + } + else + { + result = g_binary_content_read_s64(content, &tmp, format->endian, &tag64); + if (tag64 == type) break; + } + + } + + if (result) + { + init_vmpa(&tmp, pos, VMPA_NO_VIRTUAL); + + if (format->is_32b) + { + result = g_binary_content_read_s32(content, &tmp, format->endian, &item->dyn32.d_tag); + result &= g_binary_content_read_s32(content, &tmp, format->endian, &item->dyn32.d_un.d_val); + } + else + { + result = g_binary_content_read_s64(content, &tmp, format->endian, &item->dyn64.d_tag); + result &= g_binary_content_read_s64(content, &tmp, format->endian, &item->dyn64.d_un.d_val); + } + + } + + 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 */ + + 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 (ELF_HDR(format, format->header, e_machine)) + { + case EM_ARM: + result = load_elf_arm_relocated_symbols(format, &relxxx, &dynsym, &dynstr); + break; + + default: + break; + + } + + } + + return result; + +} diff --git a/plugins/elf/symbols.h b/plugins/elf/symbols.h new file mode 100644 index 0000000..f0bfa0d --- /dev/null +++ b/plugins/elf/symbols.h @@ -0,0 +1,53 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.h - prototypes pour la gestion des symboles d'un ELF + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _FORMAT_ELF_SYMBOLS_H +#define _FORMAT_ELF_SYMBOLS_H + + +#include "elf.h" + + +#include +#include + + + +/* Charge en mémoire la liste humaine des symboles. */ +bool load_elf_symbols(GElfFormat *, GtkStatusStack *); + +/* Récupère la définition complète d'un symbole donné. */ +bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *); + +/* 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); + +/* Récupère la définition complète d'un symbole donné. */ +bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *); + +/* 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); + + + +#endif /* _FORMAT_ELF_SYMBOLS_H */ diff --git a/plugins/libcsem/Makefile.am b/plugins/libcsem/Makefile.am index c09ba86..3759070 100644 --- a/plugins/libcsem/Makefile.am +++ b/plugins/libcsem/Makefile.am @@ -10,6 +10,6 @@ liblibcsem_la_SOURCES = \ liblibcsem_la_CFLAGS = $(AM_CFLAGS) -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src -I../.. AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/libcsem/semantic.c b/plugins/libcsem/semantic.c index 355bc9b..8fdc549 100644 --- a/plugins/libcsem/semantic.c +++ b/plugins/libcsem/semantic.c @@ -24,6 +24,7 @@ #include "semantic.h" +#include #include diff --git a/plugins/libcsem/semantic.h b/plugins/libcsem/semantic.h index 0fa79cf..2f8d70d 100644 --- a/plugins/libcsem/semantic.h +++ b/plugins/libcsem/semantic.h @@ -25,7 +25,6 @@ #define _PLUGINS_LIBCSEM_SEMANTIC_H -#include #include #include diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am index fe23e99..e8c2bed 100644 --- a/plugins/pychrysa/Makefile.am +++ b/plugins/pychrysa/Makefile.am @@ -4,6 +4,7 @@ pkglib_LTLIBRARIES = pychrysalide.la libdir = $(pluginsdir) pychrysalide_la_SOURCES = \ + access.h access.c \ helpers.h helpers.c \ plugin.h plugin.c \ pychrysa.h pychrysa.c \ diff --git a/plugins/pychrysa/access.c b/plugins/pychrysa/access.c new file mode 100644 index 0000000..21ff68f --- /dev/null +++ b/plugins/pychrysa/access.c @@ -0,0 +1,137 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * access.c - accès aux modules Python en cours d'enregistrement + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "access.h" + + +#include +#include + + +#include + + + +/* Lien entre un module et sa désignation */ +typedef struct _module_access +{ + const char *path; /* Chemin d'accès */ + PyObject *mod; /* Module Python en place */ + +} module_access; + + +/* Conservation de tous les accès */ +static module_access *_pychrysalide_modules = NULL; +static size_t _pychrysalide_count = 0; + + +/* Effectue la comparaison entre deux accès à des modules. */ +static int compare_python_module_accesses(const module_access *, const module_access *); + + + +/****************************************************************************** +* * +* Paramètres : a = premier accès à analyser. * +* b = second accès à analyser. * +* * +* Description : Effectue la comparaison entre deux accès à des modules. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int compare_python_module_accesses(const module_access *a, const module_access *b) +{ + int result; /* Bilan à retourner */ + + result = strcmp(a->path, b->path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à un module Python. * +* mod = module Python en question. * +* * +* Description : Enregistre une référence à un module Python en chargement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_access_to_python_module(const char *path, PyObject *mod) +{ + module_access access; /* Nouvel enregistrement */ + + access.path = path; + access.mod = mod; + + Py_INCREF(mod); + + _pychrysalide_modules = qinsert(_pychrysalide_modules, &_pychrysalide_count, + sizeof(module_access), (__compar_fn_t)compare_python_module_accesses, + &access); + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à un module Python. * +* * +* Description : Fournit la référence à un module Python défini. * +* * +* Retour : Module Python correspondant, ou NULL si aucun de trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *get_access_to_python_module(const char *path) +{ + PyObject *result; /* Référence à renvoyer */ + module_access key; /* Définition à retrouver */ + module_access *access; /* Accès trouvé à consulter */ + + key.path = path; + + access = bsearch(&key, _pychrysalide_modules, _pychrysalide_count, + sizeof(module_access), (__compar_fn_t)compare_python_module_accesses); + + if (access != NULL) + result = access->mod; + else + result = NULL; + + return result; + +} diff --git a/plugins/pychrysa/access.h b/plugins/pychrysa/access.h new file mode 100644 index 0000000..52883ec --- /dev/null +++ b/plugins/pychrysa/access.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * access.h - prototypes pour l'accès aux modules Python en cours d'enregistrement + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _PLUGINS_PYCHRYSA_ACCESS_H +#define _PLUGINS_PYCHRYSA_ACCESS_H + + +#include + + + +/* Enregistre une référence à un module Python en chargement. */ +void register_access_to_python_module(const char *, PyObject *); + +/* Fournit la référence à un module Python défini. */ +PyObject *get_access_to_python_module(const char *path); + + + +#endif /* _PLUGINS_PYCHRYSA_ACCESS_H */ diff --git a/plugins/pychrysa/analysis/contents/module.c b/plugins/pychrysa/analysis/contents/module.c index d504534..2daa62c 100644 --- a/plugins/pychrysa/analysis/contents/module.c +++ b/plugins/pychrysa/analysis/contents/module.c @@ -30,6 +30,7 @@ #include "file.h" #include "restricted.h" +#include "../../access.h" @@ -84,6 +85,9 @@ bool add_analysis_contents_module_to_python_module(PyObject *super) result &= register_python_file_content(module); result &= register_python_restricted_content(module); + if (result) + register_access_to_python_module("pychrysalide.analysis.contents", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/analysis/db/items/module.c b/plugins/pychrysa/analysis/db/items/module.c index 73ea3d3..cf0fe56 100644 --- a/plugins/pychrysa/analysis/db/items/module.c +++ b/plugins/pychrysa/analysis/db/items/module.c @@ -29,6 +29,7 @@ #include "comment.h" +#include "../../../access.h" @@ -80,6 +81,9 @@ bool add_analysis_db_items_module_to_python_module(PyObject *super) result &= register_python_db_comment(module); + if (result) + register_access_to_python_module("pychrysalide.analysis.db.items", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/analysis/db/module.c b/plugins/pychrysa/analysis/db/module.c index eac3641..1c4da25 100644 --- a/plugins/pychrysa/analysis/db/module.c +++ b/plugins/pychrysa/analysis/db/module.c @@ -32,6 +32,7 @@ #include "collection.h" #include "item.h" #include "items/module.h" +#include "../../access.h" @@ -87,6 +88,9 @@ bool add_analysis_db_module_to_python_module(PyObject *super) result &= add_analysis_db_items_module_to_python_module(module); + if (result) + register_access_to_python_module("pychrysalide.analysis.db", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c index ecae63c..253fe76 100644 --- a/plugins/pychrysa/analysis/module.c +++ b/plugins/pychrysa/analysis/module.c @@ -34,6 +34,7 @@ #include "routine.h" #include "contents/module.h" #include "db/module.h" +#include "../access.h" @@ -91,6 +92,9 @@ bool add_analysis_module_to_python_module(PyObject *super) result &= add_analysis_contents_module_to_python_module(module); result &= add_analysis_db_module_to_python_module(module); + if (result) + register_access_to_python_module("pychrysalide.analysis", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/arch/module.c b/plugins/pychrysa/arch/module.c index d9eabed..ae90b5d 100644 --- a/plugins/pychrysa/arch/module.c +++ b/plugins/pychrysa/arch/module.c @@ -39,6 +39,7 @@ #include "raw.h" #include "vmpa.h" #include "arm/module.h" +#include "../access.h" #include "../helpers.h" @@ -155,6 +156,9 @@ bool add_arch_module_to_python_module(PyObject *super) result &= add_arch_arm_module_to_python_module(module); + if (result) + register_access_to_python_module("pychrysalide.arch", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/common/module.c b/plugins/pychrysa/common/module.c index cc2623a..7ff7528 100644 --- a/plugins/pychrysa/common/module.c +++ b/plugins/pychrysa/common/module.c @@ -28,6 +28,7 @@ #include "bits.h" #include "fnv1a.h" #include "pathname.h" +#include "../access.h" @@ -81,6 +82,9 @@ bool add_common_module_to_python_module(PyObject *super) result &= register_python_fnv1a(module); result &= register_python_pathname(module); + if (result) + register_access_to_python_module("pychrysalide.common", module); + acmtpm_exit: if (!result) diff --git a/plugins/pychrysa/core/module.c b/plugins/pychrysa/core/module.c index f42f08f..6c44197 100644 --- a/plugins/pychrysa/core/module.c +++ b/plugins/pychrysa/core/module.c @@ -30,6 +30,7 @@ #include "formats.h" #include "params.h" +#include "../access.h" @@ -82,6 +83,9 @@ bool add_core_module_to_python_module(PyObject *super) result &= register_python_formats(module); result &= register_python_params(module); + if (result) + register_access_to_python_module("pychrysalide.core", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/debug/module.c b/plugins/pychrysa/debug/module.c index db33a13..ea586be 100644 --- a/plugins/pychrysa/debug/module.c +++ b/plugins/pychrysa/debug/module.c @@ -27,6 +27,7 @@ #include "debugger.h" #include "gdbrsp/module.h" +#include "../access.h" @@ -80,6 +81,9 @@ bool add_debug_module_to_python_module(PyObject *super) result &= add_debug_gdbrsp_module_to_python_module(module); + if (result) + register_access_to_python_module("pychrysalide.debug", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/format/Makefile.am b/plugins/pychrysa/format/Makefile.am index bef87ca..71f0022 100644 --- a/plugins/pychrysa/format/Makefile.am +++ b/plugins/pychrysa/format/Makefile.am @@ -8,8 +8,7 @@ libpychrysaformat_la_SOURCES = \ symbol.h symbol.c libpychrysaformat_la_LIBADD = \ - dex/libpychrysaformatdex.la \ - elf/libpychrysaformatelf.la + dex/libpychrysaformatdex.la libpychrysaformat_la_LDFLAGS = @@ -19,4 +18,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = dex elf +SUBDIRS = dex diff --git a/plugins/pychrysa/format/elf/Makefile.am b/plugins/pychrysa/format/elf/Makefile.am deleted file mode 100644 index b8f9074..0000000 --- a/plugins/pychrysa/format/elf/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ - -noinst_LTLIBRARIES = libpychrysaformatelf.la - -libpychrysaformatelf_la_SOURCES = \ - elf.h elf.c \ - module.h module.c - - -libpychrysaformatelf_la_LDFLAGS = - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ - -I../../../../src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pychrysa/format/elf/elf.c b/plugins/pychrysa/format/elf/elf.c deleted file mode 100644 index 102c60d..0000000 --- a/plugins/pychrysa/format/elf/elf.c +++ /dev/null @@ -1,206 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf.c - équivalent Python du fichier "format/elf/elf.c" - * - * Copyright (C) 2013-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "elf.h" - - -#include - - -#include - - -#include - - -#include "../executable.h" -#include "../../analysis/content.h" -#include "../../helpers.h" - - - -/* Crée un nouvel objet Python de type 'ElfFormat'. */ -static PyObject *py_elf_format_new(PyTypeObject *, PyObject *, PyObject *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'ElfFormat'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - PyObject *content_obj; /* Objet pour le contenu */ - PyObject *parent_obj; /* Objet pour le parent */ - PyObject *status_obj; /* Objet pour la progression */ - int ret; /* Bilan de lecture des args. */ - GBinContent *content; /* Instance GLib du contenu */ - GExeFormat *parent; /* Instance GLib du parent */ - GtkStatusStack *status; /* Instance GTK de suivi */ - GBinFormat *format; /* Création GLib à transmettre */ - - - ret = PyArg_ParseTuple(args, "OOO", &content_obj, &parent_obj, &status_obj); - if (!ret) return NULL; - - ret = PyObject_IsInstance(content_obj, (PyObject *)get_python_binary_content_type()); - if (!ret) - { - PyErr_SetString(PyExc_TypeError, _("The first argument must be an instance of BinContent.")); - return NULL; - } - - content = G_BIN_CONTENT(pygobject_get(content_obj)); - - if (parent_obj == Py_None) - parent = NULL; - - else - { - ret = PyObject_IsInstance(parent_obj, (PyObject *)get_python_executable_format_type()); - if (!ret) - { - PyErr_SetString(PyExc_TypeError, _("The second argument must be a container format or None.")); - return NULL; - } - - parent = G_EXE_FORMAT(pygobject_get(parent_obj)); - - } - - if (status_obj == Py_None) - status = NULL; - - else - { - ret = PyObject_IsInstance(status_obj, (PyObject *)get_python_binary_content_type()); - if (!ret) - { - PyErr_SetString(PyExc_TypeError, _("The third argument must be a status bar object or None.")); - return NULL; - } - - status = GTK_STATUS_STACK(pygobject_get(status_obj)); - - } - - format = g_elf_format_new(content, parent, status); - if (format == NULL) - { - PyErr_SetString(PyExc_RuntimeError, _("Unable to load the ELF format.")); - return NULL; - } - - result = pygobject_new(G_OBJECT(format)); - - g_object_unref(format); - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_elf_format_type(void) -{ - static PyMethodDef py_elf_format_methods[] = { - { NULL } - }; - - static PyGetSetDef py_elf_format_getseters[] = { - { NULL } - }; - - static PyTypeObject py_elf_format_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.format.elf.ElfFormat", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = "PyChrysalide Elf format", - - .tp_methods = py_elf_format_methods, - .tp_getset = py_elf_format_getseters, - .tp_new = (newfunc)py_elf_format_new - - }; - - return &py_elf_format_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.format.elf.ElfFormat'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_elf_format(PyObject *module) -{ - PyTypeObject *py_elf_format_type; /* Type Python 'ElfFormat' */ - PyObject *dict; /* Dictionnaire du module */ - - py_elf_format_type = get_python_elf_format_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_ELF_FORMAT, - py_elf_format_type, get_python_executable_format_type())) - return false; - - return true; - -} diff --git a/plugins/pychrysa/format/elf/elf.h b/plugins/pychrysa/format/elf/elf.h deleted file mode 100644 index cf6a706..0000000 --- a/plugins/pychrysa/format/elf/elf.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf.h - prototypes pour l'équivalent Python du fichier "format/elf/elf.h" - * - * Copyright (C) 2013-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H -#define _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H - - -#include -#include - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_elf_format_type(void); - -/* Prend en charge l'objet 'pychrysalide.format.elf.ElfFormat'. */ -bool register_python_elf_format(PyObject *); - - - -#endif /* _PLUGINS_PYCHRYSA_FORMAT_ELF_ELF_H */ diff --git a/plugins/pychrysa/format/elf/module.c b/plugins/pychrysa/format/elf/module.c deleted file mode 100644 index 421e4d2..0000000 --- a/plugins/pychrysa/format/elf/module.c +++ /dev/null @@ -1,84 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * module.c - intégration du répertoire elf en tant que module - * - * Copyright (C) 2013-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "module.h" - - -#include "elf.h" - - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Ajoute le module 'format.elf' au module Python. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_format_elf_module_to_python_module(PyObject *super) -{ - bool result; /* Bilan à retourner */ - PyObject *module; /* Sous-module mis en place */ - int ret; /* Bilan d'un appel */ - - static PyModuleDef py_chrysalide_elf_module = { - - .m_base = PyModuleDef_HEAD_INIT, - - .m_name = "pychrysalide.format.elf", - .m_doc = "Python module for Chrysalide.format.elf", - - .m_size = -1, - - }; - - result = false; - - module = PyModule_Create(&py_chrysalide_elf_module); - if (module == NULL) return false; - - ret = PyState_AddModule(super, &py_chrysalide_elf_module); - if (ret != 0) goto loading_failed; - - ret = _PyImport_FixupBuiltin(module, "pychrysalide.format.elf"); - if (ret != 0) goto loading_failed; - - Py_INCREF(module); - ret = PyModule_AddObject(super, "elf", module); - if (ret != 0) goto loading_failed; - - result = true; - - result &= register_python_elf_format(module); - - loading_failed: - - return result; - -} diff --git a/plugins/pychrysa/format/elf/module.h b/plugins/pychrysa/format/elf/module.h deleted file mode 100644 index 998674f..0000000 --- a/plugins/pychrysa/format/elf/module.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * module.h - prototypes pour l'intégration du répertoire elf en tant que module - * - * Copyright (C) 2013-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H -#define _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H - - -#include -#include - - - -/* Ajoute le module 'format.elf' au module Python. */ -bool add_format_elf_module_to_python_module(PyObject *); - - - -#endif /* _PLUGINS_PYCHRYSA_FORMAT_ELF_MODULE_H */ diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c index 29170b1..d15fea8 100644 --- a/plugins/pychrysa/format/module.c +++ b/plugins/pychrysa/format/module.c @@ -32,7 +32,7 @@ #include "format.h" #include "symbol.h" #include "dex/module.h" -#include "elf/module.h" +#include "../access.h" @@ -88,7 +88,9 @@ bool add_format_module_to_python_module(PyObject *super) result &= register_python_binary_symbol(module); result &= add_format_dex_module_to_python_module(module); - result &= add_format_elf_module_to_python_module(module); + + if (result) + register_access_to_python_module("pychrysalide.format", module); loading_failed: diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c index f62b17b..01a2cc8 100644 --- a/plugins/pychrysa/glibext/module.c +++ b/plugins/pychrysa/glibext/module.c @@ -32,6 +32,7 @@ #include "bufferline.h" #include "configuration.h" #include "linegen.h" +#include "../access.h" @@ -88,6 +89,9 @@ bool add_glibext_module_to_python_module(PyObject *super) result &= register_python_generic_config(module); result &= register_python_line_generator(module); + if (result) + register_access_to_python_module("pychrysalide.glibext", module); + agmtpm_exit: assert(result); diff --git a/plugins/pychrysa/gui/module.c b/plugins/pychrysa/gui/module.c index 6a55151..192b1e6 100644 --- a/plugins/pychrysa/gui/module.c +++ b/plugins/pychrysa/gui/module.c @@ -31,6 +31,7 @@ #include "editem.h" #include "panels/module.h" +#include "../access.h" @@ -84,6 +85,9 @@ bool add_gui_module_to_python_module(PyObject *super) result &= add_gui_panels_module_to_python_module(module); + if (result) + register_access_to_python_module("pychrysalide.gui", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/gui/panels/module.c b/plugins/pychrysa/gui/panels/module.c index ea0e234..d5040e3 100644 --- a/plugins/pychrysa/gui/panels/module.c +++ b/plugins/pychrysa/gui/panels/module.c @@ -30,6 +30,7 @@ #include "log.h" #include "panel.h" +#include "../../access.h" @@ -82,6 +83,9 @@ bool add_gui_panels_module_to_python_module(PyObject *super) result &= register_python_panel_item(module); result &= register_python_log_panel(module); + if (result) + register_access_to_python_module("pychrysalide.gui.panels", module); + loading_failed: assert(result); diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h index 3eee6a0..295ec28 100644 --- a/plugins/pychrysa/helpers.h +++ b/plugins/pychrysa/helpers.h @@ -21,8 +21,8 @@ */ -#ifndef _PLUGINS_HELPERS_H -#define _PLUGINS_HELPERS_H +#ifndef _PLUGINS_PYCHRYSA_HELPERS_H +#define _PLUGINS_PYCHRYSA_HELPERS_H #include @@ -90,4 +90,4 @@ bool _register_class_for_pygobject(PyObject *, GType, PyTypeObject *, PyTypeObje -#endif /* _PLUGINS_HELPERS_H */ +#endif /* _PLUGINS_PYCHRYSA_HELPERS_H */ diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index 4d32ee1..7c082d6 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -59,6 +59,10 @@ DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("PyChrysalide", "Provides bindings to Python", "0.1.0", PGA_PLUGIN_INIT); +/* Note la nature du chargement */ +static bool _standalone = true; + + /* Fournit la révision du programme global. */ static PyObject *py_chrysalide_revision(PyObject *, PyObject *); @@ -395,6 +399,9 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) return NULL; } + if (_standalone) + init_all_plugins(); + return result; } @@ -533,6 +540,8 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) /* Chargement du module pour Python */ + _standalone = false; + ret = PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalide); if (ret == -1) diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c index 33cf107..8b124a4 100644 --- a/plugins/readelf/header.c +++ b/plugins/readelf/header.c @@ -24,7 +24,7 @@ #include "header.h" -#include +#include #include diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c index 107f048..f63d10e 100644 --- a/plugins/readelf/program.c +++ b/plugins/readelf/program.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include diff --git a/plugins/readelf/program.h b/plugins/readelf/program.h index 0710577..4c4cde4 100644 --- a/plugins/readelf/program.h +++ b/plugins/readelf/program.h @@ -26,7 +26,7 @@ #include -#include +#include diff --git a/plugins/readelf/reader.c b/plugins/readelf/reader.c index 6f81b3f..4d766da 100644 --- a/plugins/readelf/reader.c +++ b/plugins/readelf/reader.c @@ -24,7 +24,7 @@ #include "reader.h" -#include +#include #include diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c index 3a71225..ae3bd6f 100644 --- a/plugins/readelf/section.c +++ b/plugins/readelf/section.c @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include #include diff --git a/plugins/readelf/section.h b/plugins/readelf/section.h index 60e8f34..33be014 100644 --- a/plugins/readelf/section.h +++ b/plugins/readelf/section.h @@ -26,7 +26,7 @@ #include -#include +#include diff --git a/plugins/readelf/strtab.c b/plugins/readelf/strtab.c index dc022cf..d8133fc 100644 --- a/plugins/readelf/strtab.c +++ b/plugins/readelf/strtab.c @@ -29,7 +29,7 @@ #include -#include +#include diff --git a/plugins/readelf/strtab.h b/plugins/readelf/strtab.h index 89c178d..9adcd46 100644 --- a/plugins/readelf/strtab.h +++ b/plugins/readelf/strtab.h @@ -26,7 +26,7 @@ #include -#include +#include diff --git a/plugins/ropgadgets/plugin.c b/plugins/ropgadgets/plugin.c index 8b35647..11d1715 100644 --- a/plugins/ropgadgets/plugin.c +++ b/plugins/ropgadgets/plugin.c @@ -65,7 +65,8 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) GtkContainer *menubar; /* Support pour éléments */ GtkWidget *submenuitem; /* Sous-élément de menu */ - ref = G_OBJECT(get_editor_window()); /* FIXME */ + ref = G_OBJECT(get_editor_window()); + if (ref == NULL) return false; menubar = GTK_CONTAINER(g_object_get_data(ref, "menubar_plugins")); if (menubar == NULL) return false; diff --git a/src/core/formats.c b/src/core/formats.c index bf58c2e..0e1e8e7 100644 --- a/src/core/formats.c +++ b/src/core/formats.c @@ -34,7 +34,6 @@ #include "../format/dwarf/v2/dwarf.h" #include "../format/dwarf/v3/dwarf.h" #include "../format/dwarf/v4/dwarf.h" -#include "../format/elf/elf.h" @@ -200,8 +199,6 @@ bool load_hard_coded_formats_definitions(void) result &= register_format_matcher(dwarf_is_matching, NULL); - result &= register_format_matcher(elf_is_matching, NULL); - /* Chargements */ result &= register_format_loader("dex", "Dalvik Executable format", g_dex_format_new); @@ -215,8 +212,6 @@ bool load_hard_coded_formats_definitions(void) result &= register_format_loader("dwarf_v4", "Debugging With Arbitrary Record Formats (v4)", g_dwarfv4_format_new); - result &= register_format_loader("elf", "Executable and Linkable Format", g_elf_format_new); - return result; } diff --git a/src/format/Makefile.am b/src/format/Makefile.am index 3501dda..3a63fbf 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -16,7 +16,6 @@ libformat_la_SOURCES = \ libformat_la_LIBADD = \ dex/libformatdex.la \ dwarf/libformatdwarf.la \ - elf/libformatelf.la \ java/libformatjava.la \ mangling/libformatmangling.la \ pe/libformatpe.la @@ -28,4 +27,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = dex dwarf elf java mangling pe +SUBDIRS = dex dwarf java mangling pe diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am deleted file mode 100644 index 53139d4..0000000 --- a/src/format/elf/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ - -noinst_LTLIBRARIES = libformatelf.la - -libformatelf_la_SOURCES = \ - elf-int.h elf-int.c \ - elf.h elf.c \ - elf_def.h \ - elf_def_arm.h \ - dynamic.h dynamic.c \ - helper_arm.h helper_arm.c \ - helper_x86.h helper_x86.c \ - loading.h loading.c \ - program.h program.c \ - section.h section.c \ - strings.h strings.c \ - symbols.h symbols.c - -# helper_mips.h helper_mips.c - -libformatelf_la_LDFLAGS = - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/format/elf/dynamic.c b/src/format/elf/dynamic.c deleted file mode 100644 index 782167c..0000000 --- a/src/format/elf/dynamic.c +++ /dev/null @@ -1,109 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * program.c - gestion des en-têtes de programme d'un ELF - * - * Copyright (C) 2015-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "dynamic.h" - - -#include "elf-int.h" -#include "program.h" - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de la section recherchée. * -* dynamic = ensemble d'informations à faire remonter. [OUT] * -* * -* Description : Recherche un en-tête de programme DYNAMIC au sein de binaire.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_dynamic_program_header(const GElfFormat *format, elf_phdr *dynamic) -{ - bool result; /* Bilan d'opération à renvoyer*/ - uint16_t max; /* Nombre d'en-têtes présents */ - uint16_t i; /* Boucle de parcours */ - - result = false; - - max = ELF_HDR(format, format->header, e_phnum); - - for (i = 0; i < max && !result; i++) - { - if (!find_elf_program_by_index(format, i, dynamic)) - break; - - result = (ELF_PHDR(format, *dynamic, p_type) == PT_DYNAMIC); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* dynamic = programme de type PT_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 : - * -* * -******************************************************************************/ - -bool find_elf_dynamic_item_from_pheader(const GElfFormat *format, const elf_phdr *dynamic, int64_t type, elf_dyn *item) -{ - bool result; /* Bilan à retourner */ - off_t max; /* Nombre d'entités présentes */ - off_t i; /* Boucle de parcours */ - phys_t pos; /* Position de lecture */ - - result = false; - - max = ELF_PHDR(format, *dynamic, p_filesz) / ELF_SIZEOF_DYN(format); - - for (i = 0; i < max && !result; i++) - { - pos = ELF_PHDR(format, *dynamic, p_offset) + i * ELF_SIZEOF_DYN(format); - - if (!read_elf_dynamic_entry(format, pos, item)) - break; - - result = (ELF_DYN(format, *item, d_tag) == type); - - } - - return result; - -} diff --git a/src/format/elf/dynamic.h b/src/format/elf/dynamic.h deleted file mode 100644 index 7fce1d4..0000000 --- a/src/format/elf/dynamic.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * dynamic.h - prototypes pour la manipulation de l'en-ête de programme 'DYNAMIC' - * - * Copyright (C) 2015-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_DYNAMIC_H -#define _FORMAT_ELF_DYNAMIC_H - - -#include "elf.h" -#include "elf_def.h" - - - -/* Recherche un en-tête de programme DYNAMIC au sein de binaire. */ -bool find_elf_dynamic_program_header(const GElfFormat *, elf_phdr *); - -/* Retrouve un élément donné dans la section dynamique. */ -bool find_elf_dynamic_item_from_pheader(const GElfFormat *, const elf_phdr *, int64_t, elf_dyn *); - - - -#endif /* _FORMAT_ELF_DYNAMIC_H */ diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c deleted file mode 100644 index 36a0f93..0000000 --- a/src/format/elf/elf-int.c +++ /dev/null @@ -1,431 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf-int.c - structures internes du format ELF - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "elf-int.h" - - -#include - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* 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 ELF. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool read_elf_header(GElfFormat *format, elf_header *header, bool *is_32b, SourceEndian *endian) -{ - bool result; /* Bilan à retourner */ - const GBinContent *content; /* Contenu binaire à lire */ - vmpa2t pos; /* Position de lecture */ - - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, 0, VMPA_NO_VIRTUAL); - - result = g_binary_content_read_raw(content, &pos, EI_NIDENT, (bin_t *)header->hdr32.e_ident); - - /* Détermination de l'espace d'adressage */ - if (result) - switch (header->hdr32.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->hdr32.e_ident[EI_DATA]) - { - case ELFDATA2LSB: - *endian = SRE_LITTLE; - break; - case ELFDATA2MSB: - *endian = SRE_BIG; - break; - default: - result = false; - break; - } - - if (*is_32b) - { - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_type); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_machine); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_version); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_entry); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_phoff); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_shoff); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr32.e_flags); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_ehsize); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_phentsize); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_phnum); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shentsize); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shnum); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr32.e_shstrndx); - } - else - { - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_type); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_machine); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr64.e_version); - result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_entry); - result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_phoff); - result &= g_binary_content_read_u64(content, &pos, *endian, &header->hdr64.e_shoff); - result &= g_binary_content_read_u32(content, &pos, *endian, &header->hdr64.e_flags); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_ehsize); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_phentsize); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_phnum); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shentsize); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shnum); - result &= g_binary_content_read_u16(content, &pos, *endian, &header->hdr64.e_shstrndx); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* phys = position de début de lecture. * -* 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, phys_t phys, elf_phdr *header) -{ - bool result; /* Bilan à retourner */ - const GBinContent *content; /* Contenu binaire à lire */ - vmpa2t pos; /* Position de lecture */ - - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - result = g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_type); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_offset); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_vaddr); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_paddr); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_filesz); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_memsz); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_flags); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr32.p_align); - } - else - { - result = g_binary_content_read_u32(content, &pos, format->endian, &header->phdr64.p_type); - result &= g_binary_content_read_u32(content, &pos, format->endian, &header->phdr64.p_flags); - result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_offset); - result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_vaddr); - result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_paddr); - result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_filesz); - result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_memsz); - result &= g_binary_content_read_u64(content, &pos, format->endian, &header->phdr64.p_align); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* phys = position de début 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, phys_t phys, elf_shdr *section) -{ - bool result; /* Bilan à retourner */ - const GBinContent *content; /* Contenu binaire à lire */ - vmpa2t pos; /* Position de lecture */ - elf32_shdr *shdr32; /* Version 32 bits */ - elf64_shdr *shdr64; /* Version 32 bits */ - - result = true; - - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - shdr32 = §ion->shdr32; - - result = g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_name); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_type); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_flags); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_addr); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_offset); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_size); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_link); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_info); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_addralign); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr32->sh_entsize); - - } - else - { - shdr64 = §ion->shdr64; - - result = g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_name); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_type); - result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_flags); - result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_addr); - result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_offset); - result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_size); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_link); - result &= g_binary_content_read_u32(content, &pos, format->endian, &shdr64->sh_info); - result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_addralign); - result &= g_binary_content_read_u64(content, &pos, format->endian, &shdr64->sh_entsize); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* phys = position de début de lecture. * -* dyn = structure lue à retourner. [OUT] * -* * -* Description : Procède à la lecture d'une entrée de type 'DYNAMIC' ELF. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool read_elf_dynamic_entry(const GElfFormat *format, phys_t phys, elf_dyn *dyn) -{ - bool result; /* Bilan à retourner */ - const GBinContent *content; /* Contenu binaire à lire */ - vmpa2t pos; /* Position de lecture */ - - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - result = g_binary_content_read_s32(content, &pos, format->endian, &dyn->dyn32.d_tag); - result &= g_binary_content_read_u32(content, &pos, format->endian, &dyn->dyn32.d_un.d_val); - } - else - { - result = g_binary_content_read_s64(content, &pos, format->endian, &dyn->dyn64.d_tag); - result &= g_binary_content_read_u64(content, &pos, format->endian, &dyn->dyn64.d_un.d_val); - } - - 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, phys_t *phys, elf_sym *sym) -{ - bool result; /* Bilan à retourner */ - const GBinContent *content; /* Contenu binaire à lire */ - vmpa2t pos; /* Position de lecture */ - - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - result = g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_name); - result &= g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_value); - result &= g_binary_content_read_u32(content, &pos, format->endian, &sym->sym32.st_size); - result &= g_binary_content_read_u8(content, &pos, &sym->sym32.st_info); - result &= g_binary_content_read_u8(content, &pos, &sym->sym32.st_other); - result &= g_binary_content_read_u16(content, &pos, format->endian, &sym->sym32.st_shndx); - } - else - { - result = g_binary_content_read_u32(content, &pos, format->endian, &sym->sym64.st_name); - result &= g_binary_content_read_u8(content, &pos, &sym->sym64.st_info); - result &= g_binary_content_read_u8(content, &pos, &sym->sym64.st_other); - result &= g_binary_content_read_u16(content, &pos, format->endian, &sym->sym64.st_shndx); - result &= g_binary_content_read_u64(content, &pos, format->endian, &sym->sym64.st_value); - result &= g_binary_content_read_u64(content, &pos, format->endian, &sym->sym64.st_size); - } - - if (result) - *phys = get_phy_addr(&pos); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* phys = 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, phys_t *phys, elf_rel *reloc) -{ - bool result; /* Bilan à retourner */ - const GBinContent *content; /* Contenu binaire à lire */ - vmpa2t pos; /* Position de lecture */ - - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - result = g_binary_content_read_u32(content, &pos, format->endian, &reloc->rel32.r_offset); - result &= g_binary_content_read_u32(content, &pos, format->endian, &reloc->rel32.r_info); - } - else - { - result = g_binary_content_read_u64(content, &pos, format->endian, &reloc->rel64.r_offset); - result &= g_binary_content_read_u64(content, &pos, format->endian, &reloc->rel64.r_info); - } - - if (result) - *phys = get_phy_addr(&pos); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* content = contenu binaire mis à disposition ou NULL. * -* pos = position de début de lecture. [OUT] * -* note = structure lue à retourner. [OUT] * -* * -* Description : Procède à la lecture d'une note ELF. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool read_elf_note(const GElfFormat *format, GBinContent *content, phys_t *phys, elf_note *note) -{ - bool result; /* Bilan à retourner */ - vmpa2t pos; /* Position de lecture */ - - if (content == NULL) - content = G_BIN_FORMAT(format)->content; - - init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL); - - result = g_binary_content_read_u32(content, &pos, format->endian, ¬e->namesz); - result &= g_binary_content_read_u32(content, &pos, format->endian, ¬e->descsz); - result &= g_binary_content_read_u32(content, &pos, format->endian, ¬e->type); - - if (result && note->namesz > 0) - { - align_vmpa(&pos, 4); - - note->name = (const char *)g_binary_content_get_raw_access(content, &pos, note->namesz); - - result &= (note->name != NULL); - - } - else note->name = NULL; - - if (result && note->descsz > 0) - { - align_vmpa(&pos, 4); - - note->desc = (const void *)g_binary_content_get_raw_access(content, &pos, note->descsz); - - result &= (note->desc != NULL); - - } - else note->desc = NULL; - - return result; - -} diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h deleted file mode 100644 index ddaebb4..0000000 --- a/src/format/elf/elf-int.h +++ /dev/null @@ -1,78 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf-int.h - prototypes pour les structures internes du format ELF - * - * Copyright (C) 2008-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_ELF_INT_H -#define _FORMAT_ELF_ELF_INT_H - - -#include "elf.h" -#include "elf_def.h" -#include "../executable-int.h" -#include "../../common/endianness.h" - - - -/* Format d'exécutable générique (instance) */ -struct _GElfFormat -{ - GExeFormat parent; /* A laisser en premier */ - - elf_header header; /* En-tête du format */ - bool is_32b; /* Format du binaire */ - SourceEndian endian; /* Boutisme du format */ - -}; - -/* Format d'exécutable générique (classe) */ -struct _GElfFormatClass -{ - GExeFormatClass parent; /* A laisser en premier */ - -}; - - - -/* Procède à la lecture de l'en-tête d'un contenu binaire ELF. */ -bool read_elf_header(GElfFormat *, elf_header *, bool *, SourceEndian *); - -/* Procède à la lecture d'une en-tête de programme ELF. */ -bool read_elf_program_header(const GElfFormat *, phys_t, elf_phdr *); - -/* Procède à la lecture d'une en-tête de section ELF. */ -bool read_elf_section_header(const GElfFormat *, phys_t, elf_shdr *); - -/* Procède à la lecture d'une entrée de type 'DYNAMIC' ELF. */ -bool read_elf_dynamic_entry(const GElfFormat *, phys_t, elf_dyn *); - -/* Procède à la lecture d'un symbole ELF. */ -bool read_elf_symbol(const GElfFormat *, phys_t *, elf_sym *); - -/* Procède à la lecture d'une relocalisation ELF. */ -bool read_elf_relocation(const GElfFormat *, phys_t *, elf_rel *); - -/* Procède à la lecture d'une note ELF. */ -bool read_elf_note(const GElfFormat *, GBinContent *, phys_t *, elf_note *); - - - -#endif /* _FORMAT_ELF_ELF_INT_H */ diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c deleted file mode 100644 index acdd01f..0000000 --- a/src/format/elf/elf.c +++ /dev/null @@ -1,711 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf.c - support du format ELF - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "elf.h" - - -#include -#include -#include -#include - - -#include - - -#include "elf-int.h" -#include "program.h" -#include "section.h" -#include "strings.h" -#include "symbols.h" -#include "../../gui/panels/log.h" -#include "../../plugins/pglist.h" - - - - - - -/* Taille maximale d'une description */ -#define MAX_PORTION_DESC 256 - - - -/* 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 *); - -/* Supprime toutes les références externes. */ -static void g_elf_format_dispose(GElfFormat *); - -/* Procède à la libération totale de la mémoire. */ -static void g_elf_format_finalize(GElfFormat *); - -/* Informe quant au boutisme utilisé. */ -static SourceEndian g_elf_format_get_endianness(const GElfFormat *); - -/* Indique le type d'architecture visée par le format. */ -static const char *g_elf_format_get_target_machine(const GElfFormat *); - -/* Fournit l'adresse principale associée à un format Elf. */ -static bool g_elf_format_get_main_address(GElfFormat *, vmpa2t *); - -/* Etend la définition des portions au sein d'un binaire. */ -static void g_elf_format_refine_portions(GElfFormat *); - -/* Fournit l'emplacement correspondant à une position physique. */ -static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *, phys_t, vmpa2t *); - -/* Fournit l'emplacement correspondant à une position physique. */ -static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *, virt_t, vmpa2t *); - -/* Fournit l'emplacement d'une section donnée. */ -static bool g_elf_format_get_section_range_by_name(const GElfFormat *, const char *, mrange_t *); - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* parent = éventuel format exécutable déjà chargé. * -* unused = adresse non utilisée ici. * -* key = identifiant de format trouvé ou NULL. [OUT] * -* * -* Description : Indique si le format peut être pris en charge ici. * -* * -* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -FormatMatchStatus elf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key) -{ - FormatMatchStatus result; /* Bilan à renvoyer */ - vmpa2t addr; /* Tête de lecture initiale */ - bool status; /* Bilan des accès mémoire */ - char magic[4]; /* Idenfiant standard */ - - if (parent != NULL) - return FMS_UNKNOWN; - - init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - - status = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); - - status &= (memcmp(magic, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); - - if (status) - { - result = FMS_MATCHED; - *key = strdup("elf"); - } - else - result = FMS_UNKNOWN; - - 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) -{ - GObjectClass *object; /* Autre version de la classe */ - GBinFormatClass *fmt; /* Version en format basique */ - GExeFormatClass *exe; /* Version en exécutable */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_format_dispose; - object->finalize = (GObjectFinalizeFunc)g_elf_format_finalize; - - fmt = G_BIN_FORMAT_CLASS(klass); - - fmt->get_endian = (format_get_endian_fc)g_elf_format_get_endianness; - - exe = G_EXE_FORMAT_CLASS(klass); - - exe->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; - exe->get_main_addr = (get_main_addr_fc)g_elf_format_get_main_address; - exe->refine_portions = (refine_portions_fc)g_elf_format_refine_portions; - - exe->translate_phys = (translate_phys_fc)g_elf_format_translate_offset_into_vmpa; - exe->translate_virt = (translate_virt_fc)g_elf_format_translate_address_into_vmpa; - - exe->get_range_by_name = (get_range_by_name_fc)g_elf_format_get_section_range_by_name; - -} - - -/****************************************************************************** -* * -* 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) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_format_dispose(GElfFormat *format) -{ - G_OBJECT_CLASS(g_elf_format_parent_class)->dispose(G_OBJECT(format)); - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_format_finalize(GElfFormat *format) -{ - G_OBJECT_CLASS(g_elf_format_parent_class)->finalize(G_OBJECT(format)); - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* parent = éventuel format exécutable déjà chargé. * - status = barre de statut à tenir informée. * -* * -* 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(GBinContent *content, GExeFormat *parent, GtkStatusStack *status) -{ - GElfFormat *result; /* Structure à retourner */ - GBinFormat *base; /* Version basique du format */ - GExeFormat *exe_format; /* Autre version du format */ - - result = g_object_new(G_TYPE_ELF_FORMAT, NULL); - - base = G_BIN_FORMAT(result); - exe_format = G_EXE_FORMAT(result); - - g_binary_format_set_content(base, content); - - if (!read_elf_header(result, &result->header, &result->is_32b, &result->endian)) - { - /* TODO */ - return NULL; - } - - - /* Vérification des tailles d'entrée de table */ - - if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result)) - { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), - ELF_HDR(result, result->header, e_phentsize), - ELF_HDR(result, result->header, e_phentsize), - ELF_SIZEOF_PHDR(result), ELF_HDR_OFFSET_OF(result, e_phentsize)); - ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result)); - } - - if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result)) - { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), - ELF_HDR(result, result->header, e_shentsize), - ELF_HDR(result, result->header, e_shentsize), - ELF_SIZEOF_SHDR(result), ELF_HDR_OFFSET_OF(result, e_shentsize)); - ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result)); - } - - /* FIXME : à améliorer */ - /* - if ((ELF_HDR(result, result->header, e_shnum) * ELF_HDR(result, result->header, e_shentsize)) >= length) - { - log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), - ELF_HDR(result, result->header, e_shnum), - 0, ELF_HDR_OFFSET_OF(result, e_shnum)); - ELF_HDR_SET(result, result->header, e_shnum, 0); - } - */ - - - - /** - * On inscrit les éléments préchargés avant tout ! - * - * Cela permet de partir d'une base vide, et d'ajouter les instructions et - * leurs commentaires par paires. - * - * Ensuite, on inscrit le reste (comme les chaînes de caractères). - */ - - preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status); - - - if (!load_elf_symbols(result, status)) - { - /* TODO */ - return NULL; - } - - - if (!find_all_elf_strings(result)) - { - /* TODO */ - return NULL; - } - - - if (!g_executable_format_complete_loading(exe_format, status)) - goto gefn_error; - - return base; - - gefn_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Informe quant au boutisme utilisé. * -* * -* Retour : Indicateur de boutisme. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static SourceEndian g_elf_format_get_endianness(const GElfFormat *format) -{ - return format->endian; - -} - - -/****************************************************************************** -* * -* 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 const char *g_elf_format_get_target_machine(const GElfFormat *format) -{ - const char *result; /* Identifiant à retourner */ - - switch (ELF_HDR(format, format->header, e_machine)) - { - case EM_386: - result = "i386"; - break; - - case EM_MIPS: - result = "mips"; - break; - - case EM_ARM: - result = "armv7"; - break; - - case EM_NONE: - default: - result = NULL; - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse principale trouvée si possible. [OUT] * -* * -* Description : Fournit l'adresse principale associée à un format Elf. * -* * -* Retour : Bilan des recherches. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_elf_format_get_main_address(GElfFormat *format, vmpa2t *addr) -{ - bool result; /* Bilan à retourner */ - GBinSymbol *symbol; /* Point d'entrée trouvé */ - GBinFormat *base; /* Version d'instance parente */ - const mrange_t *range; /* Emplacement de ce point */ - - result = false; - symbol = NULL; - - base = G_BIN_FORMAT(format); - - if (g_binary_format_find_symbol_by_label(base, "main", &symbol)) - goto done; - - if (g_binary_format_find_symbol_by_label(base, "_start", &symbol)) - goto done; - - if (g_binary_format_find_symbol_by_label(base, "entry_point", &symbol)) - goto done; - - done: - - if (symbol != NULL) - { - result = true; - - range = g_binary_symbol_get_range(symbol); - - copy_vmpa(addr, get_mrange_addr(range)); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Etend la définition des portions au sein d'un binaire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_format_refine_portions(GElfFormat *format) -{ - GExeFormat *exe_format; /* Autre version du format */ - uint16_t max; /* Décompte d'éléments traités */ - uint16_t i; /* Boucle de parcours */ - off_t offset; /* Début de part de programme */ - vmpa2t origin; /* Origine d'une définition */ - elf_phdr phdr; /* En-tête de programme ELF */ - uint32_t p_flags; /* Droits associés à une partie*/ - const char *background; /* Fond signigicatif */ - GBinPortion *new; /* Nouvelle portion définie */ - char desc[MAX_PORTION_DESC]; /* Description d'une portion */ - vmpa2t addr; /* Emplacement dans le binaire */ - PortionAccessRights rights; /* Droits d'une portion */ - elf_shdr strings; /* Section des descriptions */ - bool has_strings; /* Section trouvée ? */ - elf_shdr shdr; /* En-tête de section ELF */ - uint64_t sh_flags; /* Droits associés à une partie*/ - mrange_t range; /* Emplacement d'une section */ - const char *name; /* Nom trouvé ou NULL */ - - exe_format = G_EXE_FORMAT(format); - - /** - * La copie des différents en-têtes cherche à reproduire l'inclusion native - * du format : - * - * EXIDX 0x001178 0x00009178 0x00009178 0x00008 0x00008 R 0x4 - * PHDR 0x000034 0x00008034 0x00008034 0x00120 0x00120 R E 0x4 - * INTERP 0x000154 0x00008154 0x00008154 0x00019 0x00019 R 0x1 - * LOAD 0x000000 0x00008000 0x00008000 0x01184 0x01184 R E 0x8000 - * - */ - - /** - * Côté segments basiques. - */ - - max = ELF_HDR(format, format->header, e_phnum); - - for (i = 0; i < max; i++) - { - offset = ELF_HDR(format, format->header, e_phoff) - + ELF_HDR(format, format->header, e_phentsize) * i; - - init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); - - if (!read_elf_program_header(format, offset, &phdr)) - continue; - - if (ELF_PHDR(format, phdr, p_type) == PT_NULL) - continue; - - p_flags = ELF_PHDR(format, phdr, p_flags); - - if (p_flags & PF_X) background = BPC_CODE; - else if (p_flags & PF_W) background = BPC_DATA; - else background = BPC_DATA_RO; - - init_vmpa(&addr, ELF_PHDR(format, phdr, p_offset), ELF_PHDR(format, phdr, p_vaddr)); - - new = g_binary_portion_new(background, &addr, ELF_PHDR(format, phdr, p_filesz)); - - snprintf(desc, MAX_PORTION_DESC, "%s \"%s\"", - _("Segment"), - get_elf_program_type_desc(format, ELF_PHDR(format, phdr, p_type))); - - g_binary_portion_set_desc(new, desc); - - rights = PAC_NONE; - if (p_flags & PF_R) rights |= PAC_READ; - if (p_flags & PF_W) rights |= PAC_WRITE; - if (p_flags & PF_X) rights |= PAC_EXEC; - - g_binary_portion_set_rights(new, rights); - - g_exe_format_include_portion(exe_format, new, &origin); - - } - - /** - * Inclusion des sections, si possible... - */ - - has_strings = find_elf_section_by_index(format, - ELF_HDR(format, format->header, e_shstrndx), - &strings); - - max = ELF_HDR(format, format->header, e_shnum); - - for (i = 0; i < max; i++) - { - if (!find_elf_section_by_index(format, i, &shdr)) - continue; - - if (ELF_SHDR(format, shdr, sh_offset) == 0) - continue; - - sh_flags = ELF_SHDR(format, shdr, sh_flags); - - if (sh_flags & SHF_EXECINSTR) background = BPC_CODE; - else if (sh_flags & SHF_WRITE) background = BPC_DATA; - else background = BPC_DATA_RO; - - get_elf_section_range(format, &shdr, &range); - - new = g_binary_portion_new(background, get_mrange_addr(&range), get_mrange_length(&range)); - - if (has_strings) - name = extract_name_from_elf_string_section(format, &strings, - ELF_SHDR(format, shdr, sh_name)); - else name = NULL; - - if (name != NULL) - sprintf(desc, "%s \"%s\"", _("Section"), name); - else - sprintf(desc, "%s ???", _("Section")); - - g_binary_portion_set_desc(new, desc); - - rights = PAC_NONE; - if (sh_flags & SHF_ALLOC) rights |= PAC_READ; - if (sh_flags & SHF_WRITE) rights |= PAC_WRITE; - if (sh_flags & SHF_EXECINSTR) rights |= PAC_EXEC; - - g_binary_portion_set_rights(new, rights); - - offset = ELF_HDR(format, format->header, e_shoff) - + ELF_HDR(format, format->header, e_shentsize) * i; - - init_vmpa(&origin, offset, VMPA_NO_VIRTUAL); - - g_exe_format_include_portion(exe_format, new, &origin); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* off = position physique à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une position physique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_elf_format_translate_offset_into_vmpa(const GElfFormat *format, phys_t off, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - - result = translate_offset_into_vmpa_using_elf_sections(format, off, pos); - - if (!result) - result = translate_offset_into_vmpa_using_elf_programs(format, off, pos); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse virtuelle à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_elf_format_translate_address_into_vmpa(const GElfFormat *format, virt_t addr, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - - result = translate_address_into_vmpa_using_elf_sections(format, addr, pos); - - if (!result) - result = translate_address_into_vmpa_using_elf_programs(format, addr, pos); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* name = nom de la section recherchée. * -* range = emplacement en mémoire à renseigner. [OUT] * -* * -* Description : Fournit l'emplacement d'une section donnée. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_elf_format_get_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range) -{ - bool result; /* Bilan à retourner */ - phys_t offset; /* Position physique de section*/ - phys_t size; /* Taille de la section trouvée*/ - virt_t address; /* Adresse virtuelle de section*/ - vmpa2t tmp; /* Adresse à initialiser */ - - result = find_elf_section_content_by_name(format, name, &offset, &size, &address); - - if (result) - { - init_vmpa(&tmp, offset, address); - init_mrange(range, &tmp, size); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Présente l'en-tête ELF du format chargé. * -* * -* Retour : Pointeur vers la description principale. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const elf_header *g_elf_format_get_header(const GElfFormat *format) -{ - return &format->header; - -} diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h deleted file mode 100644 index 31dd6a2..0000000 --- a/src/format/elf/elf.h +++ /dev/null @@ -1,66 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf.h - prototypes pour le support du format ELF - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_ELF_H -#define _FORMAT_ELF_ELF_H - - -#include -#include -#include - - -#include "elf_def.h" -#include "../../core/formats.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. */ -FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **); - -/* 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(GBinContent *, GExeFormat *, GtkStatusStack *); - -/* Présente l'en-tête ELF du format chargé. */ -const elf_header *g_elf_format_get_header(const GElfFormat *); - - - -#endif /* _FORMAT_ELF_ELF_H */ diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h deleted file mode 100644 index 0d91e00..0000000 --- a/src/format/elf/elf_def.h +++ /dev/null @@ -1,634 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf_def.h - liste des structures et constantes utilisées par le format ELF - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_ELF_DEF_H -#define _FORMAT_ELF_ELF_DEF_H - - -#include - - - -/* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */ - - -#define EI_NIDENT 16 - - -/* En-tête de fichier ELF (32 et 64 bits) */ - -typedef struct _elf32_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 */ - uint32_t e_entry; /* Point d'entrée du programme */ - uint32_t e_phoff; /* Début de la table 'Program' */ - uint32_t 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*/ - -} elf32_header; - -typedef struct _elf64_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 */ - uint64_t e_entry; /* Point d'entrée du programme */ - uint64_t e_phoff; /* Début de la table 'Program' */ - uint64_t 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*/ - -} elf64_header; - -typedef union _elf_header -{ - elf32_header hdr32; /* Version 32 bits */ - elf64_header hdr64; /* Version 64 bits */ - -} elf_header; - - -#define ELF_HDR(fmt, hdr, fld) (fmt->is_32b ? (hdr).hdr32.fld : (hdr).hdr64.fld) - -#define ELF_HDR_SET(fmt, hdr, fld, val) \ - do \ - { \ - if (fmt->is_32b) (hdr).hdr32.fld = val; \ - else (hdr).hdr64.fld = val; \ - } \ - while (0) - -#define ELF_HDR_OFFSET_OF(fmt, fld) (fmt->is_32b ? offsetof(elf32_header, fld) : offsetof(elf64_header, fld)) - -#define ELF_SIZEOF_HDR(fmt) (fmt->is_32b ? sizeof(elf32_header) : sizeof(elf64_header)) - - -/* Composition du champ e_ident */ - - -#define EI_CLASS 4 /* Indice de classe du fichier */ -#define EI_DATA 5 /* Indice de l'encodage */ -#define EI_VERSION 6 /* Version de fichier ELF */ -#define EI_OSABI 7 /* Identification de l'ABI OS */ - - -/* ... 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. */ - -/* ... EI_VERSION */ - -#define EV_NONE 0 /* Version ELF invalide */ -#define EV_CURRENT 1 /* Version d'ELF courante */ - -/* ... EI_OSABI */ - -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_SYSV 0 /* Alias. */ -#define ELFOSABI_HPUX 1 /* HP-UX */ -#define ELFOSABI_NETBSD 2 /* NetBSD. */ -#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -#define ELFOSABI_AIX 7 /* IBM AIX. */ -#define ELFOSABI_IRIX 8 /* SGI Irix. */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -/* Valeurs possibles pour e_type */ - -#define ET_NONE 0 /* Aucun type défini */ -#define ET_REL 1 /* Fichier relogeable */ -#define ET_EXEC 2 /* Fichier exécutable */ -#define ET_DYN 3 /* Bibliothèque dynamique */ -#define ET_CORE 4 /* Fichier Core */ -#define ET_LOOS 0xfe00 /* Spécifique OS : début */ -#define ET_HIOS 0xfeff /* Spécifique OS : fin */ -#define ET_LOPROC 0xff00 /* Spécifique processeur : deb.*/ -#define ET_HIPROC 0xffff /* Spécifique processeur : fin */ - -/* Valeurs possibles pour e_machine */ - -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 /* AT&T WE 32100 */ -#define EM_SPARC 2 /* SUN SPARC */ -#define EM_386 3 /* Intel 80386 */ -#define EM_68K 4 /* Motorola m68k family */ -#define EM_88K 5 /* Motorola m88k family */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ -#define EM_PARISC 15 /* HPPA */ -#define EM_VPP500 17 /* Fujitsu VPP500 */ -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -#define EM_960 19 /* Intel 80960 */ -#define EM_PPC 20 /* PowerPC */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_S390 22 /* IBM S390 */ -#define EM_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH-32 */ -#define EM_RCE 39 /* Motorola RCE */ -#define EM_ARM 40 /* ARM */ -#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -#define EM_SH 42 /* Hitachi SH */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_TRICORE 44 /* Siemens Tricore */ -#define EM_ARC 45 /* Argonaut RISC Core */ -#define EM_H8_300 46 /* Hitachi H8/300 */ -#define EM_H8_300H 47 /* Hitachi H8/300H */ -#define EM_H8S 48 /* Hitachi H8S */ -#define EM_H8_500 49 /* Hitachi H8/500 */ -#define EM_IA_64 50 /* Intel Merced */ -#define EM_MIPS_X 51 /* Stanford MIPS-X */ -#define EM_COLDFIRE 52 /* Motorola Coldfire */ -#define EM_68HC12 53 /* Motorola M68HC12 */ -#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -#define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -#define EM_STARCORE 58 /* Motorola Start*Core processor */ -#define EM_ME16 59 /* Toyota ME16 processor */ -#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -#define EM_X86_64 62 /* AMD x86-64 architecture */ -#define EM_PDSP 63 /* Sony DSP Processor */ -#define EM_FX66 66 /* Siemens FX66 microcontroller */ -#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -#define EM_SVX 73 /* Silicon Graphics SVx */ -#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -#define EM_VAX 75 /* Digital VAX */ -#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -#define EM_HUANY 81 /* Harvard University machine-independent object files */ -#define EM_PRISM 82 /* SiTera Prism */ -#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -#define EM_FR30 84 /* Fujitsu FR30 */ -#define EM_D10V 85 /* Mitsubishi D10V */ -#define EM_D30V 86 /* Mitsubishi D30V */ -#define EM_V850 87 /* NEC v850 */ -#define EM_M32R 88 /* Mitsubishi M32R */ -#define EM_MN10300 89 /* Matsushita MN10300 */ -#define EM_MN10200 90 /* Matsushita MN10200 */ -#define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -#define EM_AARCH64 183 /* ARM AARCH64 */ -#define EM_TILEPRO 188 /* Tilera TILEPro */ -#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ -#define EM_TILEGX 191 /* Tilera TILE-Gx */ - - - -/* --------------------------- 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_type */ - -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ -#define PT_DYNAMIC 2 /* Dynamic linking information */ -#define PT_INTERP 3 /* Program interpreter */ -#define PT_NOTE 4 /* Auxiliary information */ -#define PT_SHLIB 5 /* Reserved */ -#define PT_PHDR 6 /* Entry for header table itself */ -#define PT_TLS 7 /* Thread-local storage segment */ -#define PT_NUM 8 /* Number of defined types */ -#define PT_LOOS 0x60000000 /* Start of OS-specific */ -#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff /* End of OS-specific */ -#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -#define PT_HIPROC 0x7fffffff /* End of processor-specific */ - -/* 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 */ -#define PF_MASKOS 0x0ff00000 /* Spécifique à l'OS */ -#define PF_MASKPROC 0xf0000000 /* Spécifique au processeur */ - - - -/* ---------------------------- 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 64 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_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ - -#define SHT_DYNAMIC 6 /* Info. de liaison dynamique */ - -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -#define SHT_HIUSER 0x8fffffff /* End of application-specific */ - - -/* Valeurs possibles pour sh_flags */ - -#define SHF_WRITE (1 << 0) /* Accessible en écriture */ -#define SHF_ALLOC (1 << 1) /* Copie en mémoire pdt l'exec.*/ -#define SHF_EXECINSTR (1 << 2) /* Section exécutable */ -#define SHF_MERGE (1 << 4) /* Peut être fusionné */ -#define SHF_STRINGS (1 << 5) /* Contient des chaînes ('\0') */ -#define SHF_INFO_LINK (1 << 6) /* 'sh_info' contient un index */ -#define SHF_LINK_ORDER (1 << 7) /* Préservation de l'ordre */ -#define SHF_OS_NONCONFORMING (1 << 8) /* Gestion non standard requise*/ -#define SHF_GROUP (1 << 9) /* Section membre d'un groupe */ -#define SHF_TLS (1 << 10) /* Données pour un thread local*/ - -#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -#define SHF_ORDERED (1 << 30) /* Special ordering requirement - (Solaris). */ -#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless - referenced or allocated (Solaris).*/ - - - - - -/* ----------------------------- 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 */ - - -#define DT_PLTGOT 3 /* Processor defined value */ - -#define DT_INIT 12 /* Address of init function */ -#define DT_FINI 13 /* Address of termination function */ - -#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ - -#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ - - - -/* ---------------------------- 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 */ - -/* Type de relocalisation (ARM) */ - -#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ - - - -/* --------------------------- NOTES ARBITRAIRES LAISSEES --------------------------- */ - - -/** - * Notes contenues dans un fichier ELF. - * Se rapporter au chapitre 5, partie "Note Section", des spécifications ABI - * du Système V pour d'avantage d'informations. - */ - -typedef struct _elf_note -{ - uint32_t namesz; /* Taille du nom éventuel */ - uint32_t descsz; /* Qté de données éventuelles */ - uint32_t type; /* Indication supplémentaire */ - - const char *name; /* Auteur de la note */ - const void *desc; /* Données complémentaires */ - -} elf_note; - - - -#endif /* _FORMAT_ELF_ELF_DEF_H */ diff --git a/src/format/elf/elf_def_arm.h b/src/format/elf/elf_def_arm.h deleted file mode 100644 index 5b0191e..0000000 --- a/src/format/elf/elf_def_arm.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * elf_def_arm.h - liste des structures et constantes utilisées par le format ELF et dédiées à ARM - * - * Copyright (C) 2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_ELF_DEF_ARM_H -#define _FORMAT_ELF_ELF_DEF_ARM_H - - -#include "elf_def.h" - - - -/* Valeurs spécifiques pour le champ p_type des en-tête de programme */ - -#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment */ - - -/* Valeurs spécifiques pour le champ sh_type des en-têtes de section */ - -#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section */ -#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details */ -#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section */ - - - -#endif /* _FORMAT_ELF_ELF_DEF_ARM_H */ diff --git a/src/format/elf/helper_arm.c b/src/format/elf/helper_arm.c deleted file mode 100644 index 5b510b9..0000000 --- a/src/format/elf/helper_arm.c +++ /dev/null @@ -1,168 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helper_x86.c - gestion auxiliaire de l'architecture x86 - * - * Copyright (C) 2014-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "helper_arm.h" - - -#include "elf_def_arm.h" -#include "elf-int.h" -#include "symbols.h" -#include "../mangling/demangler.h" - - - -/****************************************************************************** -* * -* Paramètres : p_type = type associé à un en-tête de programme. * -* * -* Description : Fournit la description humaine d'un type de segment ELF. * -* * -* Retour : Désignation prête à emploi ou NULL si aucune. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *get_elf_program_arm_type_desc(uint32_t p_type) -{ - const char *result; /* Description à renvoyer */ - -#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break; - - switch(p_type) - { - MAKE_STRING_FROM_PT(PT_ARM_EXIDX); - - default: - result = NULL; - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* 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 relogés. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) -{ - bool result; /* Bilan à retourner */ - phys_t rel_start; /* Début de la zone à traiter */ - phys_t rel_size; /* Taille de cette même zone */ - GBinFormat *base; /* Autre version du format */ - phys_t iter; /* Boucle de parcours */ - elf_rel reloc; /* Infos de relocalisation */ - off_t index; /* Indice de la portion visée */ - elf_sym sym; /* Définition complète */ - const char *name; /* Nom du symbole trouvé */ - - - - virt_t virt; /* Adresse en mémoire virtuelle*/ - virt_t final_virt; /* Adresse virtuelle retenue */ - bool status; /* Bilan d'une opération */ - vmpa2t addr; /* Localisation d'une routine */ - GBinRoutine *routine; /* Nouvelle routine trouvée */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - mrange_t range; /* Couverture mémoire associée */ - - - - - result = true; - - - - get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); - - base = G_BIN_FORMAT(format); - - for (iter = rel_start; iter < (rel_start + rel_size); ) - { - result = read_elf_relocation(format, &iter, &reloc); - if (!result) break; - - index = ELF_REL_SYM(format, reloc); - - if (!get_elf_symbol_by_index(format, dynsym, index, &sym)) - continue; - - name = get_elf_symbol_name(format, dynsym, dynstr, index); - if (name == NULL) - { - /* FIXME */ - name = "unknown"; - } - - switch (ELF_REL_TYPE(format, reloc)) - { - case R_ARM_JUMP_SLOT: - - virt = ELF_SYM(format, sym, st_value); - if (virt == 0) continue; - - final_virt = virt & ~0x1; - - status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr); - if (!status) continue; - - routine = try_to_demangle_routine(name); - symbol = G_BIN_SYMBOL(routine); - - init_mrange(&range, &addr, 0); - g_binary_symbol_set_range(symbol, &range); - - /* Comptabilisation pour le désassemblage brut */ - g_binary_format_register_code_point(base, virt, false); - - break; - - default: - printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); - symbol = NULL; - break; - - } - - if (symbol != NULL) - g_binary_format_add_symbol(base, symbol); - - } - - return result; - -} diff --git a/src/format/elf/helper_arm.h b/src/format/elf/helper_arm.h deleted file mode 100644 index e971ed6..0000000 --- a/src/format/elf/helper_arm.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helper_arm.h - prototypes pour la gestion auxiliaire de l'architecture ARM - * - * Copyright (C) 2014-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_HELPER_ARM_H -#define _FORMAT_ELF_HELPER_ARM_H - - -#include "section.h" - - - -/* Fournit la description humaine d'un type de segment ELF. */ -const char *get_elf_program_arm_type_desc(uint32_t); - -/* Charge en mémoire la liste des symboles relogés. */ -bool load_elf_arm_relocated_symbols(GElfFormat *, const elf_shdr *, const elf_shdr *, const elf_shdr *); - - - -#endif /* _FORMAT_ELF_HELPER_ARM_H */ diff --git a/src/format/elf/helper_mips.c b/src/format/elf/helper_mips.c deleted file mode 100644 index e71c69e..0000000 --- a/src/format/elf/helper_mips.c +++ /dev/null @@ -1,85 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helper_mips.c - gestion auxiliaire de l'architecture MIPS - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "helper_mips.h" - - -#include - - -#include "elf-int.h" - - - -/****************************************************************************** -* * -* 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. * -* * -* Description : Déduit les adresses effectives des appels externes. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_elf_format_find_mips_dynamic_symbols(elf_format *format, off_t dyn_start, off_t dyn_size, off_t str_start, off_t str_size) -{ - off_t iter; /* Boucle de parcours */ - Elf_Sym symbol; /* Symbole ELF lu */ - off_t name_pos; /* Localisation du nom */ - - if (dyn_size % ELF_SIZEOF_SYM(format) != 0) return false; - - for (iter = dyn_start; iter < (dyn_start + dyn_size); iter += ELF_SIZEOF_SYM(format)) - { - memcpy(&symbol, &EXE_FORMAT(format)->content[iter], ELF_SIZEOF_SYM(format)); - - if (ELF_ST_TYPE(ELF_SYM(format, symbol, st_info)) != STT_FUNC) continue; - - if (ELF_SYM(format, symbol, st_value) == 0) continue; - - name_pos = ELF_SYM(format, symbol, st_name); - - /* Sécurité anti-débordements */ - if (name_pos >= str_size) continue; - - /* Si le symbole possède un nom... */ - if (strlen(&EXE_FORMAT(format)->content[str_start + name_pos]) > 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 + name_pos]; - format->symbols[format->sym_count - 1].address = ELF_SYM(format, symbol, st_value); - - } - - } - - return true; - -} diff --git a/src/format/elf/helper_mips.h b/src/format/elf/helper_mips.h deleted file mode 100644 index 2946f15..0000000 --- a/src/format/elf/helper_mips.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helper_mips.h - prototypes pour la gestion auxiliaire de l'architecture MIPS - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_HELPER_MIPS_H -#define _FORMAT_ELF_HELPER_MIPS_H - - -#include -#include - - -#include "e_elf.h" - - - -/* Déduit les adresses effectives des appels externes. */ -bool g_elf_format_find_mips_dynamic_symbols(elf_format *, off_t, off_t, off_t, off_t); - - - -#endif /* _FORMAT_ELF_HELPER_MIPS_H */ diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c deleted file mode 100644 index ba37bcb..0000000 --- a/src/format/elf/helper_x86.c +++ /dev/null @@ -1,451 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helper_x86.c - gestion auxiliaire de l'architecture x86 - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "helper_x86.h" - - - -bool load_elf_x86_relocated_symbols(GElfFormat *a, const elf_shdr *b, const elf_shdr *c, const elf_shdr *d) -{ - return false; -} - -/* Déduit les adresses effectives des appels externes. */ -bool find_elf_x86_dynamic_symbols(GElfFormat *a, const elf_shdr *b, const elf_shdr *c, const elf_shdr *d, const elf_shdr *e) -{ - return false; -} - - - - - - -#if 0 - -#include -#include -#include - - -#include "elf-int.h" -#include "../symbol.h" -#include "../mangling/demangler.h" -#include "../../arch/immediate.h" -#include "../../arch/processor.h" -#include "../../arch/x86/instruction.h" - - -// Désactivation -#define g_x86_instruction_get_opcode(i) 0 - - -/* 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(GElfFormat *, const elf_shdr *, size_t *); - -/* Déduit les adresses effectives des relocalisations. */ -void translate_exe_elf_relocations(GElfFormat *, GArchInstruction **, size_t); - -/* Déduit les adresses effectives des relocalisations. */ -void translate_dyn_elf_relocations(GElfFormat *, GArchInstruction **, size_t, const elf_shdr *, const elf_shdr *, const elf_shdr *); - - - -/****************************************************************************** -* * -* 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 = false;//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(NULL, STP_ROUTINE); - 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). * -* rel = section .rel.plt présentant la table des symboles. * -* dynsym = section listant tous les symboles. * -* dynstr = section contenant le nom de ces symboles. * -* * -* Description : Déduit les adresses effectives des appels externes. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt, const elf_shdr *rel, const elf_shdr *dynsym, const elf_shdr *dynstr) -{ - GArchInstruction **instructions; /* Instructions décodées */ - size_t count; /* Quantité d'instructions */ - size_t i; /* Boucle de parcours */ - - instructions = decode_elf_relocations(format, plt, &count); - - switch (ELF_HDR(format, format->header, e_type)) - { - case ET_EXEC: - translate_exe_elf_relocations(format, instructions, count); - break; - - case ET_DYN: - translate_dyn_elf_relocations(format, instructions, count, rel, dynsym, dynstr); - break; - - } - - for (i = 0; i < count; i++) - /* TODO : free instructions[i] */; - - if (instructions != NULL) - free(instructions); - - return true; - -} - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : Liste des instructions décodées ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -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 */ - GArchProcessor *proc; /* Processeur pour le décodage */ - off_t pos; /* Tête de lecture */ - vmpa_t address; /* Adresse virtuelle courante */ - GArchInstruction *instr; /* Instruction décodée */ - - result = NULL; - *count = 0; - - get_elf_section_content(format, plt, &plt_start, &plt_size, &plt_address); - - proc = NULL;//get_arch_processor_for_type(APT_386); - - for (pos = 0; pos < plt_size; ) - { - address = plt_address + pos; - -#if 0 - instr = g_arch_processor_decode_instruction(proc, NULL /*FIXME*/, &G_BIN_FORMAT(format)->content[plt_start], - &pos, plt_size, address, NULL /*FIXME*/); -#endif - - result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *)); - result[*count - 1] = instr; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* instructions = listes des instructions à interpréter. * -* count = nombre d'instructions lues. * -* * -* Description : Déduit les adresses effectives des relocalisations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void translate_exe_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 */ - 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; ) - { - opcode_n0 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i])); - opcode_n1 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 1])); - opcode_n2 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 2])); - - if (opcode_n0 == XOP_JMP_RM1632 - && opcode_n1 == XOP_PUSH_IMM1632 - && opcode_n2 == XOP_JMP_REL1632) - { - operand = g_arch_instruction_get_operand(instructions[i], 0); - - if (g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address)) - { - symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &symbols_count); - - for (j = 0; j < symbols_count; j++) - if (0 /* FIXME g_binary_symbol_get_address(symbols[j]) == address*/) - { - /* Nom final */ - - new_len = strlen(g_binary_symbol_get_label(symbols[j])) + 4 + 1; - new_name = calloc(new_len, sizeof(char)); - snprintf(new_name, new_len, "%s@plt", g_binary_symbol_get_label(symbols[j])); - - g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); - - /* Routine */ - - routine = try_to_demangle_routine(g_binary_symbol_get_label(symbols[j])); - - ///g_binary_routine_set_address(routine, address); - - ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); - - /* Symbole uniquement */ - - symbol = g_binary_symbol_new(NULL, STP_ROUTINE); - - g_binary_symbol_attach_routine(symbol, routine); - - g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); - - break; - - } - - } - - i += 3; - - } - else i++; - - } - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* instructions = listes des instructions à interpréter. * -* count = nombre d'instructions lues. * -* * -* Description : Déduit les adresses effectives des relocalisations. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instructions, size_t count, const elf_shdr *rel, const elf_shdr *dynsym, const elf_shdr *dynstr) -{ - off_t rel_start; /* Début de la zone à traiter */ - off_t rel_size; /* Taille de cette même zone */ - 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 */ - const GArchOperand *operand; /* Valeur du saut */ - off_t pos; /* Tête de lecture */ - bool negative; /* Tête de lecture invalide ? */ - elf_rel reloc; /* Infos de relocalisation */ - off_t index; /* Indice de la portion visée */ - const char *name; /* Nom du symbole trouvé */ - size_t new_len; /* Taille du nouveau nom */ - char *new_name; /* Nom avec suffixe @plt */ - vmpa_t address; /* Adresse virtuelle finale */ - GBinRoutine *routine; /* Nouvelle routine déduite */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - - get_elf_section_content(format, rel, &rel_start, &rel_size, NULL); - - for (i = 0; (i + 2) < count; ) - { - opcode_n0 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i])); - opcode_n1 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 1])); - opcode_n2 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 2])); - - if (opcode_n0 == XOP_JMP_RM1632 - && opcode_n1 == XOP_PUSH_IMM1632 - && opcode_n2 == XOP_JMP_REL1632) - { - operand = g_arch_instruction_get_operand(instructions[i + 1], 0); - - if (!g_imm_operand_to_off_t(G_IMM_OPERAND(operand), &pos, &negative)) - goto next_op; - - if ((pos + ELF_SIZEOF_REL(format)) > rel_size) - goto next_op; - - pos += rel_start; - - if (!false/*read_elf_relocation(format, &pos, &reloc)*/) - goto next_op; - - index = ELF_REL_SYM(format, reloc); - name = get_elf_symbol_name(format, dynsym, dynstr, index); - - if (name == NULL) - { - /* FIXME */ - name = "unknown"; - } - - /* Nom final */ - - new_len = strlen(name) + 4 + 1; - new_name = calloc(new_len, sizeof(char)); - snprintf(new_name, new_len, "%s@plt", name); - - g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); - - /* Routine */ - - routine = try_to_demangle_routine(name); - - ////g_binary_routine_set_address(routine, address); - - ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); - - /* Symbole uniquement */ - - symbol = g_binary_symbol_new(NULL, STP_ROUTINE); - - g_binary_symbol_attach_routine(symbol, routine); - - g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); - - next_op: - - i += 3; - - } - else i++; - - } - -} - -#endif diff --git a/src/format/elf/helper_x86.h b/src/format/elf/helper_x86.h deleted file mode 100644 index 4d61fac..0000000 --- a/src/format/elf/helper_x86.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helper_x86.h - prototypes pour la gestion auxiliaire de l'architecture x86 - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_HELPER_X86_H -#define _FORMAT_ELF_HELPER_X86_H - - -#include "section.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 find_elf_x86_dynamic_symbols(GElfFormat *, const elf_shdr *, const elf_shdr *, const elf_shdr *, const elf_shdr *); - - - -#endif /* _FORMAT_ELF_HELPER_X86_H */ diff --git a/src/format/elf/loading.c b/src/format/elf/loading.c deleted file mode 100644 index ca8832e..0000000 --- a/src/format/elf/loading.c +++ /dev/null @@ -1,291 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * loading.c - chargements parallèles des symboles de format ELF - * - * Copyright (C) 2016-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "loading.h" - - -#include - - -#include "elf-int.h" -#include "section.h" -#include "../../glibext/delayed-int.h" -#include "../../gui/panels/log.h" - - - -/* Fraction de routines à limiter (instance) */ -struct _GElfLoading -{ - GDelayedWork parent; /* A laisser en premier */ - - GElfFormat *format; /* Format à faire évoluer */ - - union - { - struct - { - const elf_shdr *section; /* Section à éplucher */ - bool use_virt; /* Représentatio par défaut */ - - elf_shdr strtab; /* Section .strtab trouvée */ - bool has_strtab; /* Présence de cette section */ - - }; - - }; - - elf_loading_cb callback; /* Routine de traitement finale*/ - phys_t first; /* Position du premier élément */ - phys_t begin; /* Point de départ du parcours */ - phys_t end; /* Point d'arrivée exclu */ - - activity_id_t id; /* Identifiant pour messages */ - -}; - -/* Fraction de routines à limiter (classe) */ -struct _GElfLoadingClass -{ - GDelayedWorkClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des tâches des chargements pour ELF. */ -static void g_elf_loading_class_init(GElfLoadingClass *); - -/* Initialise une tâche de chargements pour ELF. */ -static void g_elf_loading_init(GElfLoading *); - -/* Supprime toutes les références externes. */ -static void g_elf_loading_dispose(GElfLoading *); - -/* Procède à la libération totale de la mémoire. */ -static void g_elf_loading_finalize(GElfLoading *); - -/* Assure le chargement pour un format ELF en différé. */ -static void g_elf_loading_process(GElfLoading *, GtkStatusStack *); - - - -/* Indique le type défini pour les tâches de chargements pour format ELF. */ -G_DEFINE_TYPE(GElfLoading, g_elf_loading, G_TYPE_DELAYED_WORK); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des tâches des chargements pour ELF. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_loading_class_init(GElfLoadingClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GDelayedWorkClass *work; /* Version en classe parente */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_loading_dispose; - object->finalize = (GObjectFinalizeFunc)g_elf_loading_finalize; - - work = G_DELAYED_WORK_CLASS(klass); - - work->run = (run_task_fc)g_elf_loading_process; - -} - - -/****************************************************************************** -* * -* Paramètres : loading = instance à initialiser. * -* * -* Description : Initialise une tâche de chargements pour ELF. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_loading_init(GElfLoading *loading) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : loading = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_loading_dispose(GElfLoading *loading) -{ - G_OBJECT_CLASS(g_elf_loading_parent_class)->dispose(G_OBJECT(loading)); - -} - - -/****************************************************************************** -* * -* Paramètres : loading = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_loading_finalize(GElfLoading *loading) -{ - G_OBJECT_CLASS(g_elf_loading_parent_class)->finalize(G_OBJECT(loading)); - -} - - -/****************************************************************************** -* * -* Paramètres : format = = ensemble d'instructions désassemblées. * -* section = prototypes existants à insérer. * -* use_virt = quantité de ces prototypes. * -* first = position du premier élément. * -* begin = point de départ du parcours de liste. * -* end = point d'arrivée exclu du parcours. * -* id = identifiant du message affiché à l'utilisateur. * -* callback = routine de traitements particuliers. * -* * -* Description : Crée une tâche de chargement pour ELF différée. * -* * -* Retour : Tâche créée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GElfLoading *g_elf_loading_new(GElfFormat *format, const elf_shdr *section, bool use_virt, phys_t first, phys_t begin, phys_t end, activity_id_t id, elf_loading_cb callback) -{ - GElfLoading *result; /* Tâche à retourner */ - - result = g_object_new(G_TYPE_ELF_LOADING, NULL); - - result->format = format; - - result->section = section; - result->use_virt = use_virt; - - result->has_strtab = find_elf_section_by_index(format, - ELF_SHDR(format, *section, sh_link), - &result->strtab); - - result->callback = callback; - result->first = first; - result->begin = begin; - result->end = end; - - result->id = id; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : study = étude de routines à mener. * -* status = barre de statut à tenir informée. * -* * -* Description : Assure le chargement pour un format ELF en différé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status) -{ - phys_t iter; /* Boucle de parcours */ - phys_t old; /* Sauvegarde du point d'avant */ - bool ret; /* Bilan d'un appel */ - - for (iter = loading->begin; iter < loading->end; ) - { - old = iter; - ret = loading->callback(loading, loading->format, &iter); - - if (!ret) - { - log_variadic_message(LMT_ERROR, _("Error while loading ELF data @ 0x%08x!"), old); - break; - } - - gtk_status_stack_update_activity_value(status, loading->id, 1); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : loading = chargement pour ELF à mener. * -* section = prototypes existants à insérer. [OUT] * -* use_virt = quantité de ces prototypes. [OUT] * -* strtab = informations quant à la table des chaînes. [OUT]* -* has_strtab = validité du champ précédemment renseigné. [OUT] * -* first = position du premier élément. [OUT] * -* * -* Description : Fournit les infos utiles au chargement de symbols internes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_elf_loading_get_internal_info(GElfLoading *loading, const elf_shdr **section, bool *use_virt, const elf_shdr **strtab, bool *has_strtab, phys_t *first) -{ - *section = loading->section; - *use_virt = loading->use_virt; - - *strtab = &loading->strtab; - *has_strtab = loading->has_strtab; - - *first = loading->first; - -} diff --git a/src/format/elf/loading.h b/src/format/elf/loading.h deleted file mode 100644 index 97d6987..0000000 --- a/src/format/elf/loading.h +++ /dev/null @@ -1,71 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * loading.h - prototypes pour les chargements parallèles des symboles de format ELF - * - * Copyright (C) 2016-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_LOADING_H -#define _FORMAT_ELF_LOADING_H - - -#include "elf.h" -#include "../../gtkext/gtkstatusstack.h" - - - - -//#include "../routine.h" -//#include "../../arch/processor.h" -//#include "../../format/executable.h" -//#include "../../gtkext/gtkstatusstack.h" - - - -#define G_TYPE_ELF_LOADING g_elf_loading_get_type() -#define G_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_elf_loading_get_type(), GElfLoading)) -#define G_IS_ELF_LOADING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_elf_loading_get_type())) -#define G_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ELF_LOADING, GElfLoadingClass)) -#define G_IS_ELF_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ELF_LOADING)) -#define G_ELF_LOADING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ELF_LOADING, GElfLoadingClass)) - - -/* Fraction de loading à limiter (instance) */ -typedef struct _GElfLoading GElfLoading; - -/* Fraction de loading à limiter (classe) */ -typedef struct _GElfLoadingClass GElfLoadingClass; - - -/* Assure un chargement pour ELF en différé. */ -typedef bool (* elf_loading_cb) (GElfLoading *, GElfFormat *, phys_t *); - - -/* Indique le type défini pour les tâches de chargements pour format ELF. */ -GType g_elf_loading_get_type(void); - -/* Crée une tâche de chargement pour ELF différée. */ -GElfLoading *g_elf_loading_new(GElfFormat *, const elf_shdr *, bool, phys_t, phys_t, phys_t, activity_id_t, elf_loading_cb); - -/* Fournit les infos utiles au chargement de symbols internes. */ -void g_elf_loading_get_internal_info(GElfLoading *, const elf_shdr **, bool *, const elf_shdr **, bool *, phys_t *); - - - -#endif /* _FORMAT_ELF_LOADING_H */ diff --git a/src/format/elf/program.c b/src/format/elf/program.c deleted file mode 100644 index 3016feb..0000000 --- a/src/format/elf/program.c +++ /dev/null @@ -1,217 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * program.c - gestion des en-têtes de programme d'un ELF - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "program.h" - - -#include "elf-int.h" -#include "helper_arm.h" - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* p_type = type associé à un en-tête de programme. * -* * -* Description : Fournit la description humaine d'un type de segment ELF. * -* * -* Retour : Désignation prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *get_elf_program_type_desc(const GElfFormat *format, uint32_t p_type) -{ - const char *result; /* Description à renvoyer */ - -#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break; - - switch(p_type) - { - MAKE_STRING_FROM_PT(PT_NULL); - MAKE_STRING_FROM_PT(PT_LOAD); - MAKE_STRING_FROM_PT(PT_DYNAMIC); - MAKE_STRING_FROM_PT(PT_INTERP); - MAKE_STRING_FROM_PT(PT_NOTE); - MAKE_STRING_FROM_PT(PT_SHLIB); - MAKE_STRING_FROM_PT(PT_PHDR); - MAKE_STRING_FROM_PT(PT_TLS); - MAKE_STRING_FROM_PT(PT_NUM); - MAKE_STRING_FROM_PT(PT_LOOS); - MAKE_STRING_FROM_PT(PT_GNU_EH_FRAME); - MAKE_STRING_FROM_PT(PT_GNU_STACK); - MAKE_STRING_FROM_PT(PT_GNU_RELRO); - MAKE_STRING_FROM_PT(PT_LOSUNW); - MAKE_STRING_FROM_PT(PT_SUNWSTACK); - MAKE_STRING_FROM_PT(PT_HIOS); - MAKE_STRING_FROM_PT(PT_LOPROC); - MAKE_STRING_FROM_PT(PT_HIPROC); - - default: - result = NULL; - break; - - } - - if (result == NULL) - switch (ELF_HDR(format, format->header, e_machine)) - { - case EM_ARM: - result = get_elf_program_arm_type_desc(p_type); - break; - - default: - break; - - } - - if (result == NULL) - switch(p_type) - { - MAKE_STRING_FROM_PT(PT_LOOS); - MAKE_STRING_FROM_PT(PT_HIOS); - MAKE_STRING_FROM_PT(PT_LOPROC); - MAKE_STRING_FROM_PT(PT_HIPROC); - - default: - result = "PT_???"; - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de la section recherchée. * -* program = ensemble d'informations à faire remonter. [OUT] * -* * -* Description : Recherche un programme donné au sein de binaire par indice. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_program_by_index(const GElfFormat *format, uint16_t index, elf_phdr *program) -{ - off_t offset; /* Emplacement à venir lire */ - - if (index >= ELF_HDR(format, format->header, e_phnum)) return false; - - offset = ELF_HDR(format, format->header, e_phoff) - + ELF_HDR(format, format->header, e_phentsize) * index; - - return read_elf_program_header(format, offset, program); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* off = position physique à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une position physique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *format, phys_t off, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - elf_phdr program; /* Programme à analyser */ - virt_t addr; /* Adresse virtuelle calculée */ - - result = false; - - for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++) - { - find_elf_program_by_index(format, i, &program); - - if (ELF_PHDR(format, program, p_offset) <= off - && off < (ELF_PHDR(format, program, p_offset) + ELF_PHDR(format, program, p_filesz))) - { - addr = ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_offset) - off; - init_vmpa(pos, off, addr); - result = true; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse virtuelle à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *format, virt_t addr, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - elf_phdr program; /* Programme à analyser */ - phys_t off; /* Position physique calculée */ - - result = false; - - for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++) - { - find_elf_program_by_index(format, i, &program); - - if (ELF_PHDR(format, program, p_vaddr) <= addr - && addr < (ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_filesz))) - { - off = ELF_PHDR(format, program, p_offset) + addr - ELF_PHDR(format, program, p_vaddr); - init_vmpa(pos, off, addr); - result = true; - } - - } - - return result; - -} diff --git a/src/format/elf/program.h b/src/format/elf/program.h deleted file mode 100644 index bf05d2a..0000000 --- a/src/format/elf/program.h +++ /dev/null @@ -1,47 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * program.h - prototypes pour la gestion des en-têtes de programme d'un ELF - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_PROGRAM_H -#define _FORMAT_ELF_PROGRAM_H - - -#include "elf.h" -#include "elf_def.h" - - - -/* Fournit la description humaine d'un type de segment ELF. */ -const char *get_elf_program_type_desc(const GElfFormat *, uint32_t); - -/* Recherche un programme donné au sein de binaire par indice. */ -bool find_elf_program_by_index(const GElfFormat *, uint16_t, elf_phdr *); - -/* Fournit l'emplacement correspondant à une position physique. */ -bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *, phys_t, vmpa2t *); - -/* Fournit l'emplacement correspondant à une adresse virtuelle. */ -bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *, virt_t, vmpa2t *); - - - -#endif /* _FORMAT_ELF_PROGRAM_H */ diff --git a/src/format/elf/section.c b/src/format/elf/section.c deleted file mode 100644 index 556c0ed..0000000 --- a/src/format/elf/section.c +++ /dev/null @@ -1,425 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * section.h - prototypes pour la gestion des sections d'un ELF - * - * Copyright (C) 2008-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "section.h" - - -#include -#include - - -#include "elf-int.h" - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de la section recherchée. * -* section = ensemble d'informations à faire remonter. [OUT] * -* * -* Description : Recherche une section donnée au sein de binaire par indice. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shdr *section) -{ - phys_t offset; /* Emplacement à venir lire */ - - if (index >= ELF_HDR(format, format->header, e_shnum)) return false; - - offset = ELF_HDR(format, format->header, e_shoff) - + ELF_HDR(format, format->header, e_shentsize) * index; - - return read_elf_section_header(format, offset, section); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* name = nom de la section recherchée. * -* section = ensemble d'informations à faire remonter. [OUT] * -* * -* Description : Recherche une section donnée au sein de binaire par nom. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_shdr *section) -{ - 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 */ - - if (!find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings)) - return false; - - result = false; - - for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) - { - find_elf_section_by_index(format, i, section); - - secname = extract_name_from_elf_string_section(format, &strings, - ELF_SHDR(format, *section, sh_name)); - - if (secname != NULL) - result = (strcmp(name, secname) == 0); - - } - - return result; - -} - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_section_by_virtual_address(const GElfFormat *format, virt_t addr, elf_shdr *section) -{ - bool result; /* Bilan à faire remonter */ - uint16_t i; /* Boucle de parcours */ - - result = false; - - for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) - { - find_elf_section_by_index(format, i, section); - - result = (addr == ELF_SHDR(format, *section, sh_addr)); - - } - - return result; - -} - - -/****************************************************************************** -* * -* 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 type. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr **sections, size_t *count) -{ - uint16_t i; /* Boucle de parcours */ - elf_shdr section; /* Section à analyser */ - - *sections = NULL; - *count = 0; - - for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++) - { - find_elf_section_by_index(format, i, §ion); - - if (type == ELF_SHDR(format, section, sh_type)) - { - *sections = (elf_shdr *)realloc(*sections, ++(*count) * sizeof(elf_shdr)); - (*sections)[*count - 1] = section; - } - - } - - return (*count > 0); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* section = section à consulter. * -* offset = position de la section trouvée. [OUT] * -* size = taille 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. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void get_elf_section_content(const GElfFormat *format, const elf_shdr *section, phys_t *offset, phys_t *size, virt_t *addr) -{ - *offset = ELF_SHDR(format, *section, sh_offset); - *size = ELF_SHDR(format, *section, sh_size); - - if (addr != NULL) - *addr = ELF_SHDR(format, *section, sh_addr); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* section = section à consulter. * -* range = emplacement de la fonction à renseigner. [OUT] * -* * -* Description : Fournit la localisation d'une section. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void get_elf_section_range(const GElfFormat *format, const elf_shdr *section, mrange_t *range) -{ - virt_t virt; /* Emplacement virtuel */ - vmpa2t tmp; /* Enregistrement intermédiaire*/ - - virt = ELF_SHDR(format, *section, sh_addr); - - if (virt == 0) - virt = VMPA_NO_VIRTUAL; - - init_vmpa(&tmp, ELF_SHDR(format, *section, sh_offset), virt); - - init_mrange(range, &tmp, ELF_SHDR(format, *section, sh_size)); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* name = nom de la section recherchée. * -* offset = position de la section trouvée. [OUT] * -* size = taille 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. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_section_content_by_name(const GElfFormat *format, const char *name, phys_t *offset, phys_t *size, virt_t *address) -{ - bool result; /* Bilan à retourner */ - elf_shdr section; /* Section trouvée ou non */ - - result = find_elf_section_by_name(format, name, §ion); - - if (result) - get_elf_section_content(format, §ion, offset, size, address); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* name = nom de la section recherchée. * -* range = emplacement de la fonction à renseigner. [OUT] * -* * -* Description : Recherche une zone donnée au sein de binaire par nom. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_elf_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range) -{ - bool result; /* Bilan à retourner */ - elf_shdr section; /* Section trouvée ou non */ - - result = find_elf_section_by_name(format, name, §ion); - - if (result) - get_elf_section_range(format, §ion, range); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* section = section contenant des chaînes terminées par '\0'. * -* index = indice du premier caractères à cerner. * -* * -* Description : Identifie une chaîne de caractères dans une section adéquate.* -* * -* Retour : Pointeur vers la chaîne recherchée ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *extract_name_from_elf_string_section(const GElfFormat *format, const elf_shdr *section, off_t index) -{ - const char *result; /* Nom trouvé à renvoyer */ - phys_t last; /* Dernier '\0' possible */ - phys_t phys; /* Point de lecture physique */ - vmpa2t pos; /* Position de lecture */ - const GBinContent *content; /* Contenu binaire à lire */ - - last = ELF_SHDR(format, *section, sh_offset) + ELF_SHDR(format, *section, sh_size); - - phys = ELF_SHDR(format, *section, sh_offset) + index; - - if ((phys + 1) >= last) - return NULL; - - init_vmpa(&pos, phys, VMPA_NO_VIRTUAL); - - content = G_BIN_FORMAT(format)->content; - - result = (const char *)g_binary_content_get_raw_access(content, &pos, 1); - - if (result == NULL) - return NULL; - - if ((phys + strlen(result)) > last) - return NULL; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* off = position physique à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une position physique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool translate_offset_into_vmpa_using_elf_sections(const GElfFormat *format, phys_t off, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - elf_shdr section; /* Section à analyser */ - virt_t addr; /* Adresse virtuelle calculée */ - - result = false; - - for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) - { - find_elf_section_by_index(format, i, §ion); - - if (ELF_SHDR(format, section, sh_offset) <= off - && off < (ELF_SHDR(format, section, sh_offset) + ELF_SHDR(format, section, sh_size))) - { - addr = ELF_SHDR(format, section, sh_addr) + off - ELF_SHDR(format, section, sh_offset); - init_vmpa(pos, off, addr); - result = true; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse virtuelle à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool translate_address_into_vmpa_using_elf_sections(const GElfFormat *format, virt_t addr, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - elf_shdr section; /* Section à analyser */ - phys_t off; /* Position physique calculée */ - - result = false; - - for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++) - { - find_elf_section_by_index(format, i, §ion); - - if (ELF_SHDR(format, section, sh_addr) <= addr - && addr < (ELF_SHDR(format, section, sh_addr) + ELF_SHDR(format, section, sh_size))) - { - off = ELF_SHDR(format, section, sh_offset) + addr - ELF_SHDR(format, section, sh_addr); - init_vmpa(pos, off, addr); - result = true; - } - - } - - return result; - -} diff --git a/src/format/elf/section.h b/src/format/elf/section.h deleted file mode 100644 index f3be0f4..0000000 --- a/src/format/elf/section.h +++ /dev/null @@ -1,68 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * section.h - prototypes pour la gestion des sections d'un ELF - * - * Copyright (C) 2008-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_SECTION_H -#define _FORMAT_ELF_SECTION_H - - -#include "elf.h" -#include "elf_def.h" - - - -/* 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 GElfFormat *, const char *, elf_shdr *); - -/* Recherche une section donnée au sein de binaire par type. */ -bool find_elf_section_by_virtual_address(const GElfFormat *, virt_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 GElfFormat *, const elf_shdr *, phys_t *, phys_t *, virt_t *); - -/* Fournit la localisation d'une section. */ -void get_elf_section_range(const GElfFormat *, const elf_shdr *, mrange_t *); - -/* Recherche une zone donnée au sein de binaire par nom. */ -bool find_elf_section_content_by_name(const GElfFormat *, const char *, phys_t *, phys_t *, virt_t *); - -/* Recherche une zone donnée au sein de binaire par nom. */ -bool find_elf_section_range_by_name(const GElfFormat *, const char *, mrange_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 *, off_t); - -/* Fournit l'emplacement correspondant à une position physique. */ -bool translate_offset_into_vmpa_using_elf_sections(const GElfFormat *, phys_t, vmpa2t *); - -/* Fournit l'emplacement correspondant à une adresse virtuelle. */ -bool translate_address_into_vmpa_using_elf_sections(const GElfFormat *, virt_t, vmpa2t *); - - - -#endif /* _FORMAT_ELF_SECTION_H */ diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c deleted file mode 100644 index 2af08b2..0000000 --- a/src/format/elf/strings.c +++ /dev/null @@ -1,248 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * strings.c - recherche des chaînes contenues dans un ELF - * - * Copyright (C) 2008-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "strings.h" - - -#include -#include -#include -#include -#include - - -#include "elf-int.h" -#include "section.h" -#include "../../arch/raw.h" - - - -/* Enregistre toutes les chaînes de caractères trouvées. */ -static bool parse_elf_string_data(GElfFormat *, phys_t, phys_t, virt_t); - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à analyser. * -* * -* Description : Charge en mémoire toutes les chaînes trouvées. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_all_elf_strings(GElfFormat *format) -{ - bool got_string; /* Indique un remplissage */ - phys_t str_start; /* Début de section */ - phys_t str_size; /* Taille de section */ - virt_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 #1 */ - phys_t max; /* Borne à ne pas dépasser */ - phys_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_addr)) - got_string |= parse_elf_string_data(format, str_start, str_size, str_addr); - - else - { - if (find_elf_sections_by_type(format, SHT_PROGBITS, §ions, &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, §ions[i], &str_start, &str_size, &str_addr); - got_string |= parse_elf_string_data(format, str_start, str_size, str_addr); - } - - free(sections); - - } - - } - - /* Chaîne de caractères déclarées */ - - if (find_elf_sections_by_type(format, SHT_STRTAB, §ions, &count)) - { - for (i = 0; i < count; i++) - { - get_elf_section_content(format, §ions[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 (!got_string) - { - max = ELF_HDR(format, format->header, e_phoff) - + ELF_HDR(format, format->header, e_phnum) * ELF_SIZEOF_PHDR(format); - - for (iter = ELF_HDR(format, format->header, e_phoff); iter < max; iter += ELF_SIZEOF_PHDR(format)) - { - 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)); - - } - - } - - return true; - -} - - -/****************************************************************************** -* * -* 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 : true si des chaînes ont été ajoutées sans erreur, ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t address) -{ - bool result; /* Bilan à faire remonter */ - GBinFormat *base; /* Autre version du format */ - GBinContent *content; /* Contenu binaire à lire */ - const bin_t *data; /* Contenu complet et original */ - vmpa2t pos; /* Tête de lecture */ - bool cut; /* Séparation nette ? */ - phys_t i; /* Boucle de parcours */ - phys_t end; /* Position de fin de chaîne */ - GArchInstruction *instr; /* Instruction décodée */ - bool inserted; /* Bilan d'une insertion */ - const mrange_t *range; /* Espace occupé par une chaîne*/ - GBinSymbol *symbol; /* Symbole à intégrer */ - char *label; /* Désignation de la chaîne */ - - if (address == 0) - return false; - - result = false; - - /* Préparation des accès */ - - base = G_BIN_FORMAT(format); - - content = g_binary_format_get_content(base); - - init_vmpa(&pos, start, address); - - data = g_binary_content_get_raw_access(content, &pos, size); - - if (data == NULL) - goto pesd_error; - - /* Boucle de parcours */ - - cut = true; - - for (i = 0; i < size; i++) - if (isprint(data[i])) - { - for (end = i + 1; end < size; end++) - if (!isprint(data[end])) break; - - if (end < size && isspace(data[end])) - end++; - - if (end < size && data[end] == '\0') - end++; - - init_vmpa(&pos, start + i, address + i); - - instr = g_raw_instruction_new_array(content, MDS_8_BITS, end - i, &pos, format->endian); - assert(instr != NULL); - - g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); - - inserted = g_preload_info_add_instruction(base->info, instr); - - if (inserted) - { - range = g_arch_instruction_get_range(instr); - - symbol = g_binary_symbol_new(range, STP_RO_STRING); - g_binary_format_add_symbol(base, symbol); - - /* Jointure avec la chaîne précédente ? */ - - if (cut) - { - label = create_string_label(base, get_mrange_addr(range), end - i); - - g_binary_symbol_set_alt_label(symbol, label); - - free(label); - - } - - } - - /* Conclusion */ - - cut = (data[end - 1] == '\0'); - - i = end - 1; - result = true; - - } - else cut = true; - - pesd_error: - - g_object_unref(G_OBJECT(content)); - - return result; - -} diff --git a/src/format/elf/strings.h b/src/format/elf/strings.h deleted file mode 100644 index bea52da..0000000 --- a/src/format/elf/strings.h +++ /dev/null @@ -1,37 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * strings.h - prototypes pour la recherche des chaînes contenues dans un ELF - * - * Copyright (C) 2008-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_STRINGS_H -#define _FORMAT_ELF_STRINGS_H - - -#include "elf.h" - - - -/*Charge en mémoire toutes les chaînes trouvées. */ -bool find_all_elf_strings(GElfFormat *); - - - -#endif /* _FORMAT_ELF_STRINGS_H */ diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c deleted file mode 100644 index c6056ca..0000000 --- a/src/format/elf/symbols.c +++ /dev/null @@ -1,952 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * symbols.c - gestion des symboles d'un ELF - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "symbols.h" - - -#include -#include -#include - - -#include - - -#include "dynamic.h" -#include "elf-int.h" -#include "helper_arm.h" -#include "helper_x86.h" -#include "loading.h" -#include "program.h" -#include "section.h" -#include "../mangling/demangler.h" -#include "../../arch/raw.h" -#include "../../common/extstr.h" -#include "../../core/global.h" -#include "../../core/params.h" -#include "../../gui/panels/log.h" - - - - - - - - - - -/* Enregistre un point d'entrée au sein d'un binaire ELF. */ -static void register_elf_entry_point(GElfFormat *, virt_t, phys_t, GBinRoutine *); - -/* Enumère tous les points d'entrée principaux d'un binaire ELF. */ -static bool load_all_elf_basic_entry_points(GElfFormat *); - - - - - - - - - -/* -------------------------- DETAIL DES SYMBOLES INTERNES -------------------------- */ - - -/* Assure le chargement des symboles internes ELF en différé. */ -static bool do_elf_internal_symbol_loading(GElfLoading *, GElfFormat *, phys_t *); - -/* Charge tous les symboles internes possibles. */ -static bool load_elf_internal_symbols(GElfFormat *, wgroup_id_t, GtkStatusStack *); - - - -/* -------------------------- 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. * - status = barre de statut à tenir informée. * -* * -* Description : Charge en mémoire la liste humaine des symboles. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_symbols(GElfFormat *format, GtkStatusStack *status) -{ - bool result; /* Bilan à retourner */ - wgroup_id_t gid; /* Identifiant pour les tâches */ - - elf_shdr *sections; /* Groupe de sections trouvées */ - size_t count; /* Quantité de données */ - - result = true; - - gid = g_work_queue_define_work_group(get_work_queue()); - - /* Symboles internes */ - - result &= load_elf_internal_symbols(format, gid, status); - - - - - /* Symboles externes */ -#if 1 - if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) - { - log_variadic_message(LMT_INFO, _("Binary is dynamically linked")); - - result &= load_elf_external_symbols(format, §ions[0]); - - free(sections); - - } - else log_variadic_message(LMT_INFO, _("Binary is statically linked")); -#endif - /* Symboles internes */ - //result &= load_elf_internal_symbols(format); - - - - /* Symboles d'entrée, si encore besoin */ - - /** - * Le tri en préalable - */ - - - - - - result &= load_all_elf_basic_entry_points(format); - - return result; - -} - - - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* vaddr = adresse virtuelle du symbole à insérer. * -* len = taille de la routine à ajouter. * -* routine = représentation de la fonction repérée. * -* * -* Description : Enregistre un point d'entrée au sein d'un binaire ELF. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t len, GBinRoutine *routine) -{ - GBinFormat *base; /* Version basique du format */ - virt_t final_vaddr; /* Adresse virtuelle retenue */ - bool status; /* Bilan d'une opération */ - vmpa2t addr; /* Localisation d'une routine */ - mrange_t range; /* Couverture mémoire associée */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - - /* Localisation complète du symbole */ - - if (ELF_HDR(format, format->header, e_machine) == EM_ARM) - final_vaddr = vaddr & ~0x1; - else - final_vaddr = vaddr; - - status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_vaddr, &addr); - if (!status) return; - - /* Comptabilisation en tant que symbole */ - - if (g_binary_format_find_symbol_at(G_BIN_FORMAT(format), &addr, &symbol)) - g_object_unref(G_OBJECT(routine)); - - else - { - base = G_BIN_FORMAT(format); - - init_mrange(&range, &addr, len); - - symbol = G_BIN_SYMBOL(routine); - - g_binary_symbol_set_range(symbol, &range); - g_binary_symbol_set_target_type(symbol, STP_ENTRY_POINT); - - g_binary_format_add_symbol(base, symbol); - - /* Comptabilisation pour le désassemblage brut */ - g_binary_format_register_code_point(base, vaddr, true); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* * -* Description : Enumère tous les points d'entrée principaux d'un binaire ELF.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool load_all_elf_basic_entry_points(GElfFormat *format) -{ - virt_t ep; /* Point d'entrée détecté */ - GBinRoutine *routine; /* Routine à associer à un pt. */ - elf_phdr dynamic; /* En-tête de programme DYNAMIC*/ - elf_dyn item_a; /* Premier élément DYNAMIC */ - elf_dyn item_b; /* Second élément DYNAMIC */ - const GBinContent *content; /* Contenu binaire à lire */ - phys_t length; /* Taille totale du contenu */ - bool status; /* Bilan d'une opération */ - vmpa2t pos; /* Tête de lecture courante */ - uint32_t virt_32; /* Adresse virtuelle sur 32b */ - uint64_t virt_64; /* Adresse virtuelle sur 64b */ - - /* Point d'entrée principal éventuel */ - - ep = ELF_HDR(format, format->header, e_entry); - - if (ep != 0x0) - { - routine = try_to_demangle_routine("entry_point"); - register_elf_entry_point(format, ep, 0, routine); - } - - /* Chargemet de l'en-tête de programme DYNAMIC */ - - if (!find_elf_dynamic_program_header(format, &dynamic)) - goto laebep_exit; - - /* Détection des constructeurs & destructeurs */ - - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_INIT, &item_a)) - { - ep = ELF_DYN(format, item_a, d_un.d_ptr); - - if (ep != 0x0) - { - routine = try_to_demangle_routine("init_function"); - register_elf_entry_point(format, ep, 0, routine); - } - - } - - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_FINI, &item_a)) - { - ep = ELF_DYN(format, item_a, d_un.d_ptr); - - if (ep != 0x0) - { - routine = try_to_demangle_routine("termination_function"); - register_elf_entry_point(format, ep, 0, routine); - } - - } - - void load_entry_points_from_array(GElfFormat *fmt, const elf_dyn *ar, const elf_dyn *sz, const char *prefix) - { - unsigned int i; /* Boucle de parcours */ - char fullname[64]; /* Désignation humaine */ - - assert(sizeof(fullname) >= (strlen(prefix) + sizeof(XSTR(UINT64_MAX) + 1))); - - content = G_BIN_FORMAT(fmt)->content; - - status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), - ELF_DYN(fmt, *ar, d_un.d_val), - &pos); - if (!status) return; - - length = get_phy_addr(&pos) + ELF_DYN(fmt, *sz, d_un.d_val); - - for (i = 0; get_phy_addr(&pos) < length; i++) - { - /** - * Selon la libc d'Android (https://www.codeaurora.org/.../android/bionic/linker/README.TXT) : - * - * DT_INIT_ARRAY - * Points to an array of function addresses that must be - * called, in-order, to perform initialization. Some of - * the entries in the array can be 0 or -1, and should - * be ignored. - * - * On étend le principe aux sections DT_FINI_ARRAY et DT_PREINIT_ARRAY. - */ - - if (fmt->is_32b) - { - status = g_binary_content_read_u32(content, &pos, fmt->endian, &virt_32); - status &= (virt_32 != 0x0 && virt_32 != 0xffffffff); - ep = virt_32; - } - else - { - status = g_binary_content_read_u64(content, &pos, fmt->endian, &virt_64); - status &= (virt_64 != 0x0 && virt_64 != 0xffffffffffffffff); - ep = virt_64; - } - - if (!status) break; - - snprintf(fullname, sizeof(fullname), "%s%u", prefix, i); - - routine = try_to_demangle_routine(fullname); - register_elf_entry_point(fmt, ep, 0, routine); - - } - - } - - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_INIT_ARRAY, &item_a)) - { - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_INIT_ARRAYSZ, &item_b)) - { - load_entry_points_from_array(format, &item_a, &item_b, "init_array_function_"); - } - - } - - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_FINI_ARRAY, &item_a)) - { - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_FINI_ARRAYSZ, &item_b)) - { - load_entry_points_from_array(format, &item_a, &item_b, "fini_array_function_"); - } - - } - - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PREINIT_ARRAY, &item_a)) - { - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PREINIT_ARRAYSZ, &item_b)) - { - load_entry_points_from_array(format, &item_a, &item_b, "preinit_array_function_"); - } - - } - - /* Identification de l'entrée de la PLT */ - - if (find_elf_dynamic_item_from_pheader(format, &dynamic, DT_PLTGOT, &item_a)) - { - status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), - ELF_DYN(format, item_a, d_un.d_val), - &pos); - - if (status) - { - content = G_BIN_FORMAT(format)->content; - - /* On saute le premier élément... */ - if (format->is_32b) - status = g_binary_content_read_u32(content, &pos, format->endian, &virt_32); - else - status = g_binary_content_read_u64(content, &pos, format->endian, &virt_64); - - while (1) - { - if (format->is_32b) - { - status = g_binary_content_read_u32(content, &pos, format->endian, &virt_32); - ep = virt_32; - } - else - { - status = g_binary_content_read_u64(content, &pos, format->endian, &virt_64); - ep = virt_64; - } - - if (!status) break; - - if (ep != 0x0) - { - routine = try_to_demangle_routine("plt_entry"); - register_elf_entry_point(format, ep, 0, routine); - break; - } - - } - - } - - } - - laebep_exit: - - return true; - -} - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* sym = section comprenant les symboles à venir lire. * -* index = indice de l'entrée à venir lire. * -* symbol = ensemble d'informations lues. [OUT] * -* * -* Description : Récupère la définition complète d'un symbole donné. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_elf_symbol_by_index(GElfFormat *format, const elf_shdr *sym, off_t index, elf_sym *symbol) -{ - phys_t sym_start; /* Début de section */ - phys_t sym_size; /* Taille de section */ - phys_t offset; /* Emplacement à venir lire */ - - get_elf_section_content(format, sym, &sym_start, &sym_size, NULL); - - offset = sym_start + index * ELF_SIZEOF_SYM(format); - if ((offset + ELF_SIZEOF_SYM(format)) > (sym_start + sym_size)) return NULL; - - return read_elf_symbol(format, &offset, symbol); - -} - - -/****************************************************************************** -* * -* 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 */ - elf_sym symbol; /* Symbole aux infos visées */ - - result = NULL; - - if (get_elf_symbol_by_index(format, sym, index, &symbol)) - result = extract_name_from_elf_string_section(format, str, ELF_SYM(format, symbol, st_name)); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* DETAIL DES SYMBOLES INTERNES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : loading = chargement de symboles internes en cours. * -* format = format ELF à compléter. * -* iter = tête de lecture évoluant avec le temps. [OUT] * -* * -* Description : Assure le chargement des symboles internes ELF en différé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool do_elf_internal_symbol_loading(GElfLoading *loading, GElfFormat *format, phys_t *iter) -{ - bool result; /* Bilan à retourner */ - elf_sym sym; /* Symbole aux infos visées */ - virt_t virt; /* Adresse virtuelle */ - const elf_shdr *section; /* Groupe de sections trouvées */ - bool use_virt; /* Choix de construction de nom*/ - const elf_shdr *strtab; /* Section .strtab trouvée */ - bool has_strtab; /* Présence de cette section */ - phys_t first; /* Position du premier élément */ - const char *name; /* Nom du symbole trouvé */ - GBinFormat *base; /* Version basique du format */ - vmpa2t addr; /* Localisation d'une routine */ - GBinSymbol *symbol; /* Nouveau symbole construit */ - char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ - virt_t final_virt; /* Adresse virtuelle retenue */ - mrange_t range; /* Couverture mémoire associée */ - GBinRoutine *routine; /* Nouvelle routine trouvée */ - - result = read_elf_symbol(format, iter, &sym); - if (!result) goto geslp_done; - - /* On rejette les symboles qui ne sont pas définis au sein du binaire */ - - if (ELF_SYM(format, sym, st_shndx) == 0) goto geslp_done; - - /* Résolution précise d'adresse */ - - virt = ELF_SYM(format, sym, st_value); - if (virt == 0) goto geslp_done; - - - /* TODO */ - - //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value)); - - - //init_mrange(&range, &addr, 0); - - - /* Première ébauche de nom */ - - g_elf_loading_get_internal_info(loading, §ion, &use_virt, &strtab, &has_strtab, &first); - - if (!has_strtab) - name = NULL; - - else - name = get_elf_symbol_name(format, section, strtab, - ((*iter - first) / ELF_SIZEOF_SYM(format)) - 1); - - /* Traitements particuliers */ - - base = G_BIN_FORMAT(format); - - switch (ELF_ST_TYPE(format, sym)) - { - case STT_OBJECT: - - /* Ajustement de la position */ - - if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr)) - { - symbol = NULL; - break; - } - - /* Création d'un nom unique ? */ - - if (name == NULL) - { - strcpy(alt_name, "obj_"); - - if (use_virt) - vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); - else - vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); - - name = alt_name; - - } - - - /* TODO */ - - symbol = NULL; - - - break; - - case STT_FUNC: - - /* Ajustement de la position */ - - if (ELF_HDR(format, format->header, e_machine) == EM_ARM) - final_virt = virt & ~0x1; - else - final_virt = virt; - - if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr)) - { - symbol = NULL; - break; - } - - init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); - - /* Création d'un nom unique ? */ - - if (name == NULL) - { - strcpy(alt_name, "func_"); - - if (use_virt) - vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); - else - vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); - - name = alt_name; - - } - - /* Routine */ - - routine = try_to_demangle_routine(name); - symbol = G_BIN_SYMBOL(routine); - - g_binary_symbol_set_range(symbol, &range); - - /* Comptabilisation pour le désassemblage brut */ - - g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false); - - break; - - default: - symbol = NULL; - break; - - } - - if (symbol != NULL) - g_binary_format_add_symbol(base, symbol); - - geslp_done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* gid = groupe de travail impliqué. * - status = barre de statut à tenir informée. * -* * -* Description : Charge tous les symboles internes possibles. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool load_elf_internal_symbols(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status) -{ - bool result; /* Bilan à retourner */ - bool no_name; /* Choix de construction de nom*/ - activity_id_t msg; /* Message de progression */ - GWorkQueue *queue; /* Gestionnaire de différés */ - elf_shdr *dynsym_sections; /* Groupe de sections trouvées */ - size_t count; /* Quantité de données */ - elf_shdr *symtab_sections; /* Groupe de sections trouvées */ - size_t i; /* Boucle de parcours */ - - result = true; - - /* Charge tous les symboles définis dans une section */ - void add_all_symbols_from_section(const elf_shdr *section, bool use_virt, GWorkQueue *wq, activity_id_t id) - { - phys_t start; /* Début de la zone à traiter */ - phys_t size; /* Taille de cette même zone */ - phys_t sym_size; /* Taille de chaque symbole lu */ - guint runs_count; /* Qté d'exécutions parallèles */ - phys_t run_size; /* Volume réparti par exécution*/ - guint i; /* Boucle de parcours */ - phys_t begin; /* Début de zone de traitement */ - phys_t end; /* Fin d'un zone de traitement */ - GElfLoading *loading; /* Tâche de chargement à lancer*/ - - get_elf_section_content(format, section, &start, &size, NULL); - - sym_size = ELF_SIZEOF_SYM(format); - - runs_count = g_get_num_processors(); - - run_size = size / (sym_size * runs_count); - - gtk_status_stack_extend_activity(status, id, size / sym_size); - - for (i = 0; i < runs_count; i++) - { - begin = start + i * run_size * sym_size; - - if ((i + 1) == runs_count) - end = start + size; - else - end = begin + run_size * sym_size; - - loading = g_elf_loading_new(format, section, use_virt, start, begin, end, - id, do_elf_internal_symbol_loading); - - g_work_queue_schedule_work(wq, G_DELAYED_WORK(loading), gid); - - } - - } - - if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name)) - return false; - - msg = gtk_status_stack_add_activity(status, _("Loading internal symbols..."), 0); - - queue = get_work_queue(); - - if (find_elf_sections_by_type(format, SHT_DYNSYM, &dynsym_sections, &count)) - for (i = 0; i < count; i++) - add_all_symbols_from_section(&dynsym_sections[i], no_name, queue, msg); - - if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtab_sections, &count)) - for (i = 0; i < count; i++) - add_all_symbols_from_section(&symtab_sections[i], no_name, queue, msg); - - g_work_queue_wait_for_completion(queue, gid); - - gtk_status_stack_remove_activity(status, msg); - - if (dynsym_sections != NULL) free(dynsym_sections); - if (symtab_sections != NULL) free(symtab_sections); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* 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 GBinContent *content; /* Contenu binaire à lire */ - phys_t pos; /* Position de lecture */ - vmpa2t 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; - - for (pos = ELF_SHDR(format, *section, sh_offset); - result; - pos += ELF_SIZEOF_DYN(format)) - { - init_vmpa(&tmp, pos, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - result = g_binary_content_read_s32(content, &tmp, format->endian, &tag32); - if (tag32 == type) break; - } - else - { - result = g_binary_content_read_s64(content, &tmp, format->endian, &tag64); - if (tag64 == type) break; - } - - } - - if (result) - { - init_vmpa(&tmp, pos, VMPA_NO_VIRTUAL); - - if (format->is_32b) - { - result = g_binary_content_read_s32(content, &tmp, format->endian, &item->dyn32.d_tag); - result &= g_binary_content_read_s32(content, &tmp, format->endian, &item->dyn32.d_un.d_val); - } - else - { - result = g_binary_content_read_s64(content, &tmp, format->endian, &item->dyn64.d_tag); - result &= g_binary_content_read_s64(content, &tmp, format->endian, &item->dyn64.d_un.d_val); - } - - } - - 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 (ELF_HDR(format, format->header, e_machine)) - { - case EM_ARM: - result = load_elf_arm_relocated_symbols(format, &relxxx, &dynsym, &dynstr); - break; - - case EM_386: - result = load_elf_x86_relocated_symbols(format, &relxxx, &dynsym, &dynstr); - break; - - default: - break; - - } - - } - -#if 0 - - /* 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); - - - printf("VMA :: 0x%08llx\n", ELF_DYN(format, item, d_un.d_ptr)); - - - - 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, &relxxx, &dynsym, &dynstr); - - } - - break; - - default: - break; - - } - - } - -#endif - - return result; - -} diff --git a/src/format/elf/symbols.h b/src/format/elf/symbols.h deleted file mode 100644 index 03be46c..0000000 --- a/src/format/elf/symbols.h +++ /dev/null @@ -1,53 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * symbols.h - prototypes pour la gestion des symboles d'un ELF - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _FORMAT_ELF_SYMBOLS_H -#define _FORMAT_ELF_SYMBOLS_H - - -#include "elf.h" - - -#include "../../glibext/delayed.h" -#include "../../gtkext/gtkstatusstack.h" - - - -/* Charge en mémoire la liste humaine des symboles. */ -bool load_elf_symbols(GElfFormat *, GtkStatusStack *); - -/* Récupère la définition complète d'un symbole donné. */ -bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *); - -/* 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); - -/* Récupère la définition complète d'un symbole donné. */ -bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *); - -/* 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); - - - -#endif /* _FORMAT_ELF_SYMBOLS_H */ diff --git a/src/format/format.c b/src/format/format.c index 293e5da..8b1bf0a 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -32,11 +32,6 @@ #include "format-int.h" #include "preload.h" -#include "dex/dex.h" -#include "dwarf/dwarf.h" -#include "elf/elf.h" -#include "java/java.h" -#include "pe/pe.h" #include "../arch/processor.h" #include "../common/sort.h" #include "../gui/panels/log.h" -- cgit v0.11.2-87-g4458