diff options
Diffstat (limited to 'plugins/elf')
-rw-r--r-- | plugins/elf/core.c | 50 | ||||
-rw-r--r-- | plugins/elf/core.h | 3 | ||||
-rw-r--r-- | plugins/elf/elf_def.h | 5 | ||||
-rw-r--r-- | plugins/elf/format.c | 129 | ||||
-rw-r--r-- | plugins/elf/format.h | 2 | ||||
-rw-r--r-- | plugins/elf/python/format.c | 58 |
6 files changed, 151 insertions, 96 deletions
diff --git a/plugins/elf/core.c b/plugins/elf/core.c index 0cfd49c..7486242 100644 --- a/plugins/elf/core.c +++ b/plugins/elf/core.c @@ -24,7 +24,7 @@ #include "core.h" -#include <core/formats.h> +#include <core/global.h> #include <plugins/plugin-def.h> @@ -34,7 +34,7 @@ DEFINE_CHRYSALIDE_PLUGIN("elf", "Add support for the ELF format", "0.1.0", - RL("PyChrysalide"), AL(PGA_PLUGIN_INIT)); + RL("PyChrysalide"), AL(PGA_PLUGIN_INIT, PGA_CONTENT_RESOLVER)); @@ -65,3 +65,49 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) return result; } + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* content = contenu binaire à traiter. * +* gid = identifiant du groupe de traitement. * +* status = barre de statut à tenir informée. * +* * +* Description : Procède à une opération liée à un contenu binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +G_MODULE_EXPORT void chrysalide_plugin_handle_binary_content(const GPluginModule *plugin, PluginAction action, GBinContent *content, gid_t gid, GtkStatusStack *status) +{ + vmpa2t addr; /* Tête de lecture initiale */ + bool test; /* Bilan des accès mémoire */ + char magic[SELFMAG]; /* Idenfiant standard */ + GExeFormat *format; /* Format ELF reconnu */ + GLoadedContent *loaded; /* Représentation chargée */ + GContentResolver *resolver; /* Resolveur de contenus */ + + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + + test = g_binary_content_read_raw(content, &addr, SELFMAG, (bin_t *)magic); + + if (test) + test = (memcmp(magic, ELFMAG, SELFMAG) == 0); + + if (test) + { + format = g_elf_format_new(content); + loaded = g_loaded_binary_new(format); + + resolver = get_current_content_resolver(); + g_content_resolver_add_detected(resolver, gid, loaded); + g_object_unref(G_OBJECT(resolver)); + + } + +} diff --git a/plugins/elf/core.h b/plugins/elf/core.h index 52ded90..ec9ed5c 100644 --- a/plugins/elf/core.h +++ b/plugins/elf/core.h @@ -33,6 +33,9 @@ /* Prend acte du chargement du greffon. */ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *); +/* Procède à une opération liée à un contenu binaire. */ +G_MODULE_EXPORT void chrysalide_plugin_handle_binary_content(const GPluginModule *, PluginAction, GBinContent *, gid_t, GtkStatusStack *); + #endif /* _PLUGINS_ELF_CORE_H */ diff --git a/plugins/elf/elf_def.h b/plugins/elf/elf_def.h index bb33d6d..a820eac 100644 --- a/plugins/elf/elf_def.h +++ b/plugins/elf/elf_def.h @@ -111,6 +111,11 @@ typedef union _elf_header #define EI_ABIVERSION 8 /* Version de l'ABI */ #define EI_PAD 9 /* Premier octet de bourrage */ +/* ... EI_MAG* */ + +#define ELFMAG "\x7f\x45\x4c\x46" /* .ELF */ +#define SELFMAG 4 + /* ... EI_CLASS */ #define ELFCLASSNONE 0 /* Objet invalide */ diff --git a/plugins/elf/format.c b/plugins/elf/format.c index eb22059..0fb2d1e 100644 --- a/plugins/elf/format.c +++ b/plugins/elf/format.c @@ -60,6 +60,12 @@ static void g_elf_format_dispose(GElfFormat *); /* Procède à la libération totale de la mémoire. */ static void g_elf_format_finalize(GElfFormat *); +/* Indique la désignation interne du format. */ +static const char *g_elf_format_get_name(const GElfFormat *); + +/* Assure l'interprétation d'un format en différé. */ +static bool g_elf_format_analyze(GElfFormat *, wgroup_id_t, GtkStatusStack *); + /* Informe quant au boutisme utilisé. */ static SourceEndian g_elf_format_get_endianness(const GElfFormat *); @@ -159,6 +165,8 @@ static void g_elf_format_class_init(GElfFormatClass *klass) fmt = G_BIN_FORMAT_CLASS(klass); + fmt->get_name = (format_get_name_fc)g_elf_format_get_name; + fmt->analyze = (format_analyze_fc)g_elf_format_analyze; fmt->get_endian = (format_get_endian_fc)g_elf_format_get_endianness; fmt->complete = (format_complete_analysis_fc)g_elf_format_complete_analysis; @@ -236,8 +244,6 @@ static void g_elf_format_finalize(GElfFormat *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. * * * @@ -247,65 +253,113 @@ static void g_elf_format_finalize(GElfFormat *format) * * ******************************************************************************/ -GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatusStack *status) +GExeFormat *g_elf_format_new(GBinContent *content) { 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(G_BIN_FORMAT(result), content); + + return G_EXE_FORMAT(result); - g_binary_format_set_content(base, content); +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Indique la désignation interne du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_elf_format_get_name(const GElfFormat *format) +{ + const char *result; /* Désignation à retourner */ + + result = "elf"; + + return result; + +} - if (!read_elf_header(result, &result->header, &result->is_32b, &result->endian)) - goto gefn_error; + +/****************************************************************************** +* * +* Paramètres : format = format chargé dont l'analyse est lancée. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Assure l'interprétation d'un format en différé. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_analyze(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + bool result; /* Bilan à retourner */ + GBinFormat *base; /* Version basique du format */ + GExeFormat *exe; /* Autre version du format */ + + result = false; + + base = G_BIN_FORMAT(format); + exe = G_EXE_FORMAT(format); + + if (!read_elf_header(format, &format->header, &format->is_32b, &format->endian)) + goto gefa_error; /* Vérification des tailles d'entrée de table */ - if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result)) + if (ELF_HDR(format, format->header, e_phentsize) != ELF_SIZEOF_PHDR(format)) { 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(format, format->header, e_phentsize), + ELF_HDR(format, format->header, e_phentsize), + ELF_SIZEOF_PHDR(format), + ELF_HDR_OFFSET_OF(format, e_phentsize)); - ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result)); + ELF_HDR_SET(format, format->header, e_phentsize, ELF_SIZEOF_PHDR(format)); } - if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result)) + if (ELF_HDR(format, format->header, e_shentsize) != ELF_SIZEOF_SHDR(format)) { 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(format, format->header, e_shentsize), + ELF_HDR(format, format->header, e_shentsize), + ELF_SIZEOF_SHDR(format), + ELF_HDR_OFFSET_OF(format, e_shentsize)); - ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result)); + ELF_HDR_SET(format, format->header, e_shentsize, ELF_SIZEOF_SHDR(format)); } /* Opérations spécifiques à l'architecture */ - switch (ELF_HDR(result, result->header, e_machine)) + switch (ELF_HDR(format, format->header, e_machine)) { case EM_ARM: - result->ops.get_type_desc = (get_elf_prgm_type_desc_cb)get_elf_program_arm_type_desc; - result->ops.fix_virt = (fix_elf_virt_addr_cb)fix_elf_arm_virtual_address; - result->ops.get_linkage_offset = (get_elf_linkage_offset_cb)retrieve_arm_linkage_offset; + format->ops.get_type_desc = (get_elf_prgm_type_desc_cb)get_elf_program_arm_type_desc; + format->ops.fix_virt = (fix_elf_virt_addr_cb)fix_elf_arm_virtual_address; + format->ops.get_linkage_offset = (get_elf_linkage_offset_cb)retrieve_arm_linkage_offset; break; default: log_variadic_message(LMT_ERROR, "Architecture not supported for ELF binaries"); - goto gefn_error; + goto gefa_error; break; } @@ -323,23 +377,20 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent, GtkStatus preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status); + if (!load_elf_symbols(format, status)) + goto gefa_error; - if (!load_elf_symbols(result, status)) - goto gefn_error; + if (!find_all_elf_strings(format)) + goto gefa_error; - if (!find_all_elf_strings(result)) - goto gefn_error; + if (!g_executable_format_complete_loading(exe, status)) + goto gefa_error; - if (!g_executable_format_complete_loading(exe_format, status)) - goto gefn_error; + result = true; - return base; + gefa_error: - gefn_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; + return result; } diff --git a/plugins/elf/format.h b/plugins/elf/format.h index a822105..47b3171 100644 --- a/plugins/elf/format.h +++ b/plugins/elf/format.h @@ -59,7 +59,7 @@ FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **); GType g_elf_format_get_type(void); /* Prend en charge un nouveau format ELF. */ -GBinFormat *g_elf_format_new(GBinContent *, GExeFormat *, GtkStatusStack *); +GExeFormat *g_elf_format_new(GBinContent *); /* Présente l'en-tête ELF du format chargé. */ const elf_header *g_elf_format_get_header(const GElfFormat *); diff --git a/plugins/elf/python/format.c b/plugins/elf/python/format.c index a3d8758..2d5bfd8 100644 --- a/plugins/elf/python/format.c +++ b/plugins/elf/python/format.c @@ -72,67 +72,17 @@ static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject { 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 */ + GExeFormat *format; /* Création GLib à transmettre */ - parent_obj = Py_None; - status_obj = Py_None; - - ret = PyArg_ParseTuple(args, "O|OO", &content_obj, &parent_obj, &status_obj); + ret = PyArg_ParseTuple(args, "O!", get_python_binary_content_type(), &content_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; - } + format = g_elf_format_new(content); + assert(format != NULL); result = pygobject_new(G_OBJECT(format)); |