From 83da8ea946dc50941838ec8b3951108f5e16642e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 7 May 2018 17:00:14 +0200 Subject: Described binary formats and improved their loading. --- plugins/dex/core.c | 14 +------ plugins/dex/format.c | 63 ++++++++++++++++++++++++++++++ plugins/dex/format.h | 3 ++ plugins/dex/python/format.c | 15 ++++++-- plugins/elf/core.c | 17 +-------- plugins/elf/format.c | 60 ++++++++++++++++++----------- plugins/elf/format.h | 4 +- plugins/elf/python/format.c | 15 ++++++-- plugins/pychrysalide/format/format.c | 74 ++++++++++++++++++++++++++++++++++++ src/format/format-int.h | 4 ++ src/format/format.c | 23 +++++++++++ src/format/format.h | 3 ++ 12 files changed, 236 insertions(+), 59 deletions(-) diff --git a/plugins/dex/core.c b/plugins/dex/core.c index 869ef4b..da0a540 100644 --- a/plugins/dex/core.c +++ b/plugins/dex/core.c @@ -54,10 +54,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) { bool result; /* Bilan à retourner */ - result = register_format_loader("dex", "Dalvik Executable format", g_dex_format_new); - - if (result) - result = add_format_dex_module_to_python_module(); + result = add_format_dex_module_to_python_module(); return result; @@ -82,19 +79,12 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) 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[DEX_FILE_MAGIC_LEN]; /* Idenfiant standard */ GExeFormat *format; /* Format DEX 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, DEX_FILE_MAGIC_LEN, (bin_t *)magic); - - if (test) - test = (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); + test = check_dex_format(content); if (test) { diff --git a/plugins/dex/format.c b/plugins/dex/format.c index 1fa5a7d..b9b6ca9 100755 --- a/plugins/dex/format.c +++ b/plugins/dex/format.c @@ -55,6 +55,9 @@ static void g_dex_format_finalize(GDexFormat *); /* Indique la désignation interne du format. */ static const char *g_dex_format_get_name(const GDexFormat *); +/* Fournit une description humaine du format. */ +static const char *g_dex_format_get_description(const GDexFormat *); + /* Assure l'interprétation d'un format en différé. */ static bool g_dex_format_analyze(GDexFormat *, wgroup_id_t, GtkStatusStack *); @@ -90,6 +93,39 @@ static void g_dex_format_decompile(const GDexFormat *, void/*GCodeBuffer*/ *, co + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à traiter. * +* * +* Description : Valide un contenu comme étant un format Dex. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool check_dex_format(const GBinContent *content) +{ + bool result; /* Bilan à faire remonter */ + vmpa2t addr; /* Tête de lecture initiale */ + char magic[DEX_FILE_MAGIC_LEN]; /* Idenfiant standard */ + + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + + result = g_binary_content_read_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic); + + if (result) + result = (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); + + return result; + +} + + /* Indique le type défini pour un format d'exécutable DEX. */ G_DEFINE_TYPE(GDexFormat, g_dex_format, G_TYPE_EXE_FORMAT); @@ -120,6 +156,7 @@ static void g_dex_format_class_init(GDexFormatClass *klass) fmt = G_BIN_FORMAT_CLASS(klass); fmt->get_name = (format_get_name_fc)g_dex_format_get_name; + fmt->get_desc = (format_get_desc_fc)g_dex_format_get_description; fmt->analyze = (format_analyze_fc)g_dex_format_analyze; fmt->get_endian = (format_get_endian_fc)g_dex_format_get_endianness; @@ -216,6 +253,9 @@ GExeFormat *g_dex_format_new(GBinContent *content) { GDexFormat *result; /* Structure à retourner */ + if (!check_dex_format(content)) + return NULL; + result = g_object_new(G_TYPE_DEX_FORMAT, NULL); g_binary_format_set_content(G_BIN_FORMAT(result), content); @@ -250,6 +290,29 @@ static const char *g_dex_format_get_name(const GDexFormat *format) /****************************************************************************** * * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Fournit une description humaine du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_dex_format_get_description(const GDexFormat *format) +{ + const char *result; /* Désignation à retourner */ + + result = "Dalvik Executable format (version '035')"; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = format chargé dont l'analyse est lancée. * * gid = groupe de travail dédié. * * status = barre de statut à tenir informée. * diff --git a/plugins/dex/format.h b/plugins/dex/format.h index 6850ed1..1879da3 100755 --- a/plugins/dex/format.h +++ b/plugins/dex/format.h @@ -52,6 +52,9 @@ typedef struct _GDexFormat GDexFormat; typedef struct _GDexFormatClass GDexFormatClass; +/* Valide un contenu comme étant un format Dex. */ +bool check_dex_format(const GBinContent *); + /* Indique le type défini pour un format d'exécutable DEX. */ GType g_dex_format_get_type(void); diff --git a/plugins/dex/python/format.c b/plugins/dex/python/format.c index 81db02f..8bcd2fa 100644 --- a/plugins/dex/python/format.c +++ b/plugins/dex/python/format.c @@ -100,13 +100,20 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject content = G_BIN_CONTENT(pygobject_get(content_obj)); format = g_dex_format_new(content); - assert(format != NULL); - result = pygobject_new(G_OBJECT(format)); + if (format == NULL) + { + result = Py_None; + Py_INCREF(result); + } - g_object_unref(format); + else + { + result = pygobject_new(G_OBJECT(format)); + g_object_unref(format); + } - return (PyObject *)result; + return result; } diff --git a/plugins/elf/core.c b/plugins/elf/core.c index 7486242..03d5964 100644 --- a/plugins/elf/core.c +++ b/plugins/elf/core.c @@ -54,13 +54,7 @@ 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(); + result = add_format_elf_module_to_python_module(); return result; @@ -85,19 +79,12 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) 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); + test = check_elf_format(content); if (test) { diff --git a/plugins/elf/format.c b/plugins/elf/format.c index 86682a2..9e29a11 100644 --- a/plugins/elf/format.c +++ b/plugins/elf/format.c @@ -63,6 +63,9 @@ static void g_elf_format_finalize(GElfFormat *); /* Indique la désignation interne du format. */ static const char *g_elf_format_get_name(const GElfFormat *); +/* Fournit une description humaine du format. */ +static const char *g_elf_format_get_description(const GElfFormat *); + /* Assure l'interprétation d'un format en différé. */ static bool g_elf_format_analyze(GElfFormat *, wgroup_id_t, GtkStatusStack *); @@ -94,42 +97,28 @@ static bool g_elf_format_get_section_range_by_name(const GElfFormat *, const cha /****************************************************************************** * * -* 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] * +* Paramètres : content = contenu binaire à traiter. * * * -* Description : Indique si le format peut être pris en charge ici. * +* Description : Valide un contenu comme étant un format Elf. * * * -* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -FormatMatchStatus elf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key) +bool check_elf_format(const GBinContent *content) { - FormatMatchStatus result; /* Bilan à renvoyer */ + bool result; /* Bilan à faire remonter */ 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); + result = 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; + if (result) + result = (memcmp(magic, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); return result; @@ -166,6 +155,7 @@ 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->get_desc = (format_get_desc_fc)g_elf_format_get_description; fmt->analyze = (format_analyze_fc)g_elf_format_analyze; fmt->get_endian = (format_get_endian_fc)g_elf_format_get_endianness; @@ -257,6 +247,9 @@ GExeFormat *g_elf_format_new(GBinContent *content) { GElfFormat *result; /* Structure à retourner */ + if (!check_elf_format(content)) + return NULL; + result = g_object_new(G_TYPE_ELF_FORMAT, NULL); g_binary_format_set_content(G_BIN_FORMAT(result), content); @@ -291,6 +284,29 @@ static const char *g_elf_format_get_name(const GElfFormat *format) /****************************************************************************** * * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Fournit une description humaine du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_elf_format_get_description(const GElfFormat *format) +{ + const char *result; /* Désignation à retourner */ + + result = "Executable and Linkable Format"; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = format chargé dont l'analyse est lancée. * * gid = groupe de travail dédié. * * status = barre de statut à tenir informée. * diff --git a/plugins/elf/format.h b/plugins/elf/format.h index 47b3171..c97ed67 100644 --- a/plugins/elf/format.h +++ b/plugins/elf/format.h @@ -52,8 +52,8 @@ typedef struct _GElfFormat GElfFormat; typedef struct _GElfFormatClass GElfFormatClass; -/* Indique si le format peut être pris en charge ici. */ -FormatMatchStatus elf_is_matching(GBinContent *, GExeFormat *, void *, char **); +/* Valide un contenu comme étant un format Elf. */ +bool check_elf_format(const GBinContent *); /* Indique le type défini pour un format d'exécutable ELF. */ GType g_elf_format_get_type(void); diff --git a/plugins/elf/python/format.c b/plugins/elf/python/format.c index 0319ba9..87b590b 100644 --- a/plugins/elf/python/format.c +++ b/plugins/elf/python/format.c @@ -82,13 +82,20 @@ static PyObject *py_elf_format_new(PyTypeObject *type, PyObject *args, PyObject content = G_BIN_CONTENT(pygobject_get(content_obj)); format = g_elf_format_new(content); - assert(format != NULL); - result = pygobject_new(G_OBJECT(format)); + if (format == NULL) + { + result = Py_None; + Py_INCREF(result); + } - g_object_unref(format); + else + { + result = pygobject_new(G_OBJECT(format)); + g_object_unref(format); + } - return (PyObject *)result; + return result; } diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c index 15abcf7..561c0c2 100644 --- a/plugins/pychrysalide/format/format.c +++ b/plugins/pychrysalide/format/format.c @@ -60,6 +60,12 @@ static PyObject *py_binary_format_find_next_symbol_at(PyObject *, PyObject *); /* Recherche le symbole correspondant à une adresse. */ static PyObject *py_binary_format_resolve_symbol(PyObject *, PyObject *); +/* Indique la désignation interne du format. */ +static PyObject *py_binary_format_get_name(PyObject *, void *); + +/* Indique la désignation humaine du format. */ +static PyObject *py_binary_format_get_description(PyObject *, void *); + /* Fournit une référence vers le contenu binaire analysé. */ static PyObject *py_binary_format_get_content(PyObject *, void *); @@ -370,6 +376,66 @@ static PyObject *py_binary_format_resolve_symbol(PyObject *self, PyObject *args) * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * +* Description : Indique la désignation interne du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_format_get_name(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GBinFormat *format; /* Format de binaire manipulé */ + const char *name; /* Description interne */ + + format = G_BIN_FORMAT(pygobject_get(self)); + + name = g_binary_format_get_name(format); + + result = PyUnicode_FromString(name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique la désignation humaine du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_format_get_description(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GBinFormat *format; /* Format de binaire manipulé */ + const char *desc; /* Description humaine */ + + format = G_BIN_FORMAT(pygobject_get(self)); + + desc = g_binary_format_get_description(format); + + result = PyUnicode_FromString(desc); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * * Description : Fournit une référence vers le contenu binaire analysé. * * * * Retour : Gestionnaire de contenu binaire en place. * @@ -611,6 +677,14 @@ PyTypeObject *get_python_binary_format_type(void) static PyGetSetDef py_bin_format_getseters[] = { { + "name", py_binary_format_get_name, NULL, + "Internal name of the binary format.", NULL + }, + { + "description", py_binary_format_get_description, NULL, + "Human description of the binary format.", NULL + }, + { "content", py_binary_format_get_content, NULL, "Content of the binary format.", NULL }, diff --git a/src/format/format-int.h b/src/format/format-int.h index 09586b9..354e616 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -40,6 +40,9 @@ /* Indique la désignation interne du format. */ typedef const char * (* format_get_name_fc) (const GBinFormat *); +/* Fournit une description humaine du format. */ +typedef const char * (* format_get_desc_fc) (const GBinFormat *); + /*Assure l'interprétation d'un format en différé. */ typedef bool (* format_analyze_fc) (GBinFormat *, wgroup_id_t, GtkStatusStack *); @@ -116,6 +119,7 @@ struct _GBinFormatClass GObjectClass parent; /* A laisser en premier */ format_get_name_fc get_name; /* Désignation interne */ + format_get_desc_fc get_desc; /* Désignation humaine */ format_analyze_fc analyze; /* Interprétation du format */ diff --git a/src/format/format.c b/src/format/format.c index b28f4a7..e6cefc8 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -283,6 +283,29 @@ const char *g_binary_format_get_name(const GBinFormat *format) /****************************************************************************** * * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Fournit une description humaine du format. * +* * +* Retour : Description du format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_format_get_description(const GBinFormat *format) +{ + const char *result; /* Désignation à retourner */ + + result = G_BIN_FORMAT_GET_CLASS(format)->get_desc(format); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = format chargé dont l'analyse est lancée. * * gid = groupe de travail dédié. * * status = barre de statut à tenir informée. * diff --git a/src/format/format.h b/src/format/format.h index 44d005c..e552f0c 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -61,6 +61,9 @@ GBinContent *g_binary_format_get_content(const GBinFormat *); /* Indique la désignation interne du format. */ const char *g_binary_format_get_name(const GBinFormat *); +/* Fournit une description humaine du format. */ +const char *g_binary_format_get_description(const GBinFormat *); + /* Assure l'interprétation d'un format en différé. */ bool g_binary_format_analyze(GBinFormat *, wgroup_id_t, GtkStatusStack *); -- cgit v0.11.2-87-g4458