diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-09-19 22:28:42 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-09-19 22:28:42 (GMT) |
commit | 0e3059731d9687027c913135b3b856596c49a689 (patch) | |
tree | d3c3754f95c90ae50168817e6248afee6873fbf3 /plugins | |
parent | 18648e4e8763a3bc005d6fae51eae3d1528d7d29 (diff) |
Extended the prototype for matching formats in order to get it suitable for plugins.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@577 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/devdbg/speed.c | 3 | ||||
-rw-r--r-- | plugins/mobicore/mclf.c | 14 | ||||
-rw-r--r-- | plugins/mobicore/mclf.h | 3 | ||||
-rw-r--r-- | plugins/mobicore/mobicore.c | 6 | ||||
-rw-r--r-- | plugins/pychrysa/core/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/pychrysa/core/module.c | 2 | ||||
-rw-r--r-- | plugins/pychrysa/plugin.c | 340 | ||||
-rw-r--r-- | plugins/python/apkfiles/__init__.py | 4 | ||||
-rw-r--r-- | plugins/python/apkfiles/apkfiles.py | 27 | ||||
-rw-r--r-- | plugins/ropgadgets/select.c | 12 |
10 files changed, 170 insertions, 242 deletions
diff --git a/plugins/devdbg/speed.c b/plugins/devdbg/speed.c index e5042ea..538a741 100644 --- a/plugins/devdbg/speed.c +++ b/plugins/devdbg/speed.c @@ -79,7 +79,6 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu } - switch (action) { case PGA_DISASSEMBLY_STARTED: @@ -115,6 +114,4 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *plugin, Plu } - printf("##########\n\nPassage 0x%08x !!!\n\n################\n", action); - } diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c index 99ff7ed..4ff44bb 100644 --- a/plugins/mobicore/mclf.c +++ b/plugins/mobicore/mclf.c @@ -56,6 +56,8 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *, GBinPortion *); * * * 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. * * * @@ -65,9 +67,9 @@ static void g_mclf_format_refine_portions(const GMCLFFormat *, GBinPortion *); * * ******************************************************************************/ -const char *mclf_is_matching(GBinContent *content, GExeFormat *parent) +FormatMatchStatus mclf_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key) { - const char *result; /* Format détecté à renvoyer */ + FormatMatchStatus result; /* Bilan à renvoyer */ vmpa2t addr; /* Tête de lecture initiale */ bool status; /* Bilan des accès mémoire */ char magic[4]; /* Idenfiant standard */ @@ -78,7 +80,13 @@ const char *mclf_is_matching(GBinContent *content, GExeFormat *parent) status &= (memcmp(magic, MC_SERVICE_HEADER_MAGIC_STR, 4) == 0); - result = status ? "mclf" : NULL; + if (status) + { + result = FMS_MATCHED; + *key = strdup("mclf"); + } + else + result = FMS_UNKNOWN; return result; diff --git a/plugins/mobicore/mclf.h b/plugins/mobicore/mclf.h index 5ac0926..78ed57b 100644 --- a/plugins/mobicore/mclf.h +++ b/plugins/mobicore/mclf.h @@ -30,6 +30,7 @@ #include <sys/types.h> +#include <core/formats.h> #include <format/executable.h> #include <format/format.h> @@ -51,7 +52,7 @@ typedef struct _GMCLFFormatClass GMCLFFormatClass; /* Indique si le format peut être pris en charge ici. */ -const char *mclf_is_matching(GBinContent *, GExeFormat *); +FormatMatchStatus mclf_is_matching(GBinContent *, GExeFormat *, void *, char **); /* Indique le type défini pour un format d'exécutable MCLF. */ GType g_mclf_format_get_type(void); diff --git a/plugins/mobicore/mobicore.c b/plugins/mobicore/mobicore.c index 087297b..8a28a76 100644 --- a/plugins/mobicore/mobicore.c +++ b/plugins/mobicore/mobicore.c @@ -54,9 +54,11 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin, GObject *ref) { bool result; /* Bilan à retourner */ - result &= register_format_matcher(mclf_is_matching); + result = true; - result = register_format_loader("mclf", "MobiCore Load Format", g_mclf_format_new); + result &= register_format_matcher(mclf_is_matching, NULL); + + result &= register_format_loader("mclf", "MobiCore Load Format", g_mclf_format_new); return result; diff --git a/plugins/pychrysa/core/Makefile.am b/plugins/pychrysa/core/Makefile.am index 1ffacf4..129b5af 100644 --- a/plugins/pychrysa/core/Makefile.am +++ b/plugins/pychrysa/core/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libpychrysacore.la libpychrysacore_la_SOURCES = \ + formats.h formats.c \ module.h module.c \ params.h params.c diff --git a/plugins/pychrysa/core/module.c b/plugins/pychrysa/core/module.c index a866c05..9fcede9 100644 --- a/plugins/pychrysa/core/module.c +++ b/plugins/pychrysa/core/module.c @@ -28,6 +28,7 @@ #include <assert.h> +#include "formats.h" #include "params.h" @@ -78,6 +79,7 @@ bool add_core_module_to_python_module(PyObject *super) result = true; + result &= register_python_formats(module); result &= register_python_params(module); loading_failed: diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c index 44cb0d8..5e968e2 100644 --- a/plugins/pychrysa/plugin.c +++ b/plugins/pychrysa/plugin.c @@ -30,6 +30,8 @@ #include <common/extstr.h> +#include "../../src/core/formats.h" +//#include <core/formats.h> #include <plugins/plugin-int.h> @@ -74,23 +76,11 @@ static bool g_python_plugin_do_init(GPythonPlugin *, GObject *); /* Procède à l'extinction du greffon. */ static bool g_python_plugin_do_exit(GPythonPlugin *, GObject *); +/* Indique si le format peut être pris en charge ici. */ +FormatMatchStatus python_plugin_is_matching(GBinContent *, GExeFormat *, GPythonPlugin *, char **); - - - - -/* Indique l'utilité pratique du greffon. */ -static PluginAction g_python_plugin_get_action(const GPythonPlugin *); - -/* Indentifie un format à associer à un contenu binaire. */ -static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *, char **, bin_t **, off_t *); - -/* Exécute une action définie sur un binaire chargé. */ -static bool g_python_plugin_execute_on_binary(GPythonPlugin *, GLoadedBinary *, PluginAction); - - -/* Exécute une action relative à un débogueur. */ -//static bool g_python_plugin_handle_debugger(const GPythonPlugin *, GBinaryDebugger *, PluginAction); +/* Exécute une action pendant un désassemblage de binaire. */ +static void g_python_plugin_process_disass(const GPythonPlugin *, PluginAction, GLoadedBinary *); @@ -143,19 +133,10 @@ static void g_python_plugin_class_init(GPythonPluginClass *klass) static void g_python_plugin_init(GPythonPlugin *plugin) { - GPluginModule *plugin_parent; /* Instance parente */ - - plugin_parent = G_PLUGIN_MODULE(plugin); - - plugin_parent->exec_on_bin = (execute_action_on_binary_fc)g_python_plugin_execute_on_binary; - //plugin_parent->handle_debugger = (execute_on_debugger_fc)g_python_plugin_handle_debugger; } - - - /****************************************************************************** * * * Paramètres : modname = nom du module à charger. * @@ -184,6 +165,7 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO PyObject *class; /* Classe à instancier */ PyObject *instance; /* Instance Python du greffon */ size_t i; /* Boucle de parcours */ + uint32_t action; /* Identifiant d'une action */ uint32_t category; /* Catégorie principale */ uint32_t sub; /* Sous-catégorie visée */ @@ -246,17 +228,6 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO goto gppn_interface_error; } - - //G_PLUGIN_MODULE(result)->get_action = (get_plugin_action_fc)g_python_plugin_get_action; - - //G_PLUGIN_MODULE(result)->is_matching = (is_matching_fc)g_python_plugin_is_matching; - - - - - - - /* Localisation des différents points d'entrée déclarés */ #define register_python_binding(inst, sym, binding) \ @@ -279,8 +250,9 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO for (i = 0; i < G_PLUGIN_MODULE(result)->interface->actions_count; i++) { - category = MASK_PLUGIN_CATEGORY(G_PLUGIN_MODULE(result)->interface->actions[i]); - sub = MASK_PLUGIN_SUB_CATEGORY(G_PLUGIN_MODULE(result)->interface->actions[i]); + action = G_PLUGIN_MODULE(result)->interface->actions[i]; + category = MASK_PLUGIN_CATEGORY(action); + sub = MASK_PLUGIN_SUB_CATEGORY(action); switch (category) { @@ -309,26 +281,39 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO } break; -#if 0 + case DPC_BINARY_PROCESSING: switch (sub) { case DPS_FORMAT: - switch (result->interface->actions[i]) + switch (action) { + case PGA_FORMAT_MATCHER: + + if (!has_python_method(instance, "is_format_matching")) + { + log_variadic_message(LMT_ERROR, + _("No '%s' entry in plugin candidate '%s'"), + "is_format_matching", + G_PLUGIN_MODULE(result)->filename); + goto gppn_bad_plugin; + } + + if (!register_format_matcher((format_match_fc)python_plugin_is_matching, result)) + goto gppn_bad_plugin; + + break; case PGA_FORMAT_LOADER_LAST: - if (!load_plugin_symbol(result->module, - "handle_binary_format", &result->handle_format)) - goto bad_plugin; + /* TODO */ break; default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), - result->interface->actions[i], filename); + action, filename); break; } @@ -336,9 +321,9 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO break; case DPS_DISASSEMBLY: - if (!load_plugin_symbol(result->module, - "process_binary_disassembly", &result->proc_disass)) - goto bad_plugin; + if (!register_python_binding(instance, process_disass, + (pg_process_disassembly_fc)g_python_plugin_process_disass)) + goto gppn_bad_plugin; break; default: @@ -349,7 +334,7 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GO } break; -#endif + default: log_variadic_message(LMT_WARNING, _("Unknown category '0x%02x' in plugin '%s'..."), category, filename); @@ -555,234 +540,152 @@ static bool g_python_plugin_do_exit(GPythonPlugin *plugin, GObject *ref) } - - - - - - /****************************************************************************** * * -* Paramètres : plugin = greffon de prise en charge à utiliser. * +* Paramètres : content = contenu binaire à parcourir. * +* parent = éventuel format exécutable déjà chargé. * +* plugin = grefon C interne représentant le grefon Python. * +* key = identifiant de format trouvé ou NULL. [OUT] * * * -* Description : Indique l'utilité pratique du greffon. * +* Description : Indique si le format peut être pris en charge ici. * * * -* Retour : Action(s) codifiée(s), PGA_NONE par défaut. * +* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. * * * * Remarques : - * * * ******************************************************************************/ -static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin) +FormatMatchStatus python_plugin_is_matching(GBinContent *content, GExeFormat *parent, GPythonPlugin *plugin, char **key) { - PluginAction result; /* Valeur à retourner */ - PyObject *value; /* Valeur obtenue */ - - value = run_python_method(plugin->instance, "get_action", NULL); - - if (value != NULL) - { - result = PyLong_AsLong(value); - Py_DECREF(value); - } - else - result = 0;//PGA_NONE; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : plugin = greffon de prise en charge à utiliser. * -* filename = éventuel nom de fichier associé ou NULL. [OUT] * -* data = données chargées. [OUT] * -* length = quantité de ces données. [OUT] * -* * -* Description : Indentifie un format à associer à un contenu binaire. * -* * -* Retour : Bilan de la recherche de correspondances. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *plugin, char **filename, bin_t **data, off_t *length) -{ - return MFA_NONE; - -#if 0 - MatchingFormatAction result; /* Valeur à retourner */ + FormatMatchStatus result; /* Bilan à renvoyer */ PyObject *args; /* Arguments pour l'appel */ - PyObject *value; /* Valeurs obtenues */ - PyObject *action; /* Action à faire suivre */ - PyObject *new_filename; /* Nouveau fichier */ - PyObject *new_data; /* Nouvelles données */ - char *tmp; /* Stockage avant recopie */ + PyObject *value; /* Valeur obtenue */ + PyObject *arg; /* Argument en élément de tuple*/ - if (*filename == NULL) - return MFA_NONE; + result = FMS_UNKNOWN; args = PyTuple_New(2); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(content))); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(parent))); - PyTuple_SetItem(args, 0, PyString_FromString(*filename)); - PyTuple_SetItem(args, 1, PyByteArray_FromStringAndSize((char *)*data, *length)); - - value = run_python_method(plugin->instance, "is_matching", args); + value = run_python_method(plugin->instance, "is_format_matching", args); - if (value != NULL && PyTuple_Check(value) && PyTuple_Size(value) == 3) + if (PyTuple_Check(value)) { - action = PyTuple_GetItem(value, 0); - new_filename = PyTuple_GetItem(value, 1); - new_data = PyTuple_GetItem(value, 2); - - if (action == NULL || new_filename == NULL || new_data == NULL) - goto is_matching_bad; - - if (!PyInt_Check(action) - || (new_filename != Py_None && !PyString_Check(new_filename)) - || (new_data != Py_None && !PyByteArray_Check(new_data))) - goto is_matching_bad; - - result = PyInt_AsLong(action); - if (result >= MFA_COUNT) goto is_matching_bad; - - if (result != MFA_NONE && new_data == Py_None) goto is_matching_bad; - - if (new_filename != Py_None) - { - free(*filename); - *filename = strdup(PyString_AsString(new_filename)); - } - - /** - * La suppression de la part du greffon n'est permise que - * si une prise en charge est assurée. - */ - else if (result != MFA_NONE) - { - free(*filename); - *filename = NULL; - } - - /** - * Pareil que précédemment. - */ - if (new_data != Py_None) + if (PyTuple_Size(value) > 0) { - tmp = PyByteArray_AsString(new_data); - *length = PyByteArray_Size(new_data); - - free(*data); - - *data = (bin_t *)calloc(*length, sizeof(bin_t)); - memcpy(*data, tmp, *length * sizeof(bin_t)); - - } + arg = PyTuple_GetItem(value, 0); - goto is_matching_ok; + if (PyLong_Check(arg)) + { + result = PyLong_AsLong(arg); - } - - is_matching_bad: - - printf("<LOG>Bad result from is_matching() plugin function.\n"); + switch (result) + { + case FMS_MATCHED: - result = MFA_NONE; + if (PyTuple_Size(value) != 2) + { + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR, + _("Expecting only a tuple [ status, key ] " \ + "as result for format matching.")); + result = FMS_UNKNOWN; + break; + } - is_matching_ok: + arg = PyTuple_GetItem(value, 1); - Py_XDECREF(value); - Py_DECREF(args); + if (PyUnicode_Check(arg)) + *key = strdup(PyUnicode_AsUTF8(arg)); - return result; -#endif -} + else + { + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR, + _("Expecting a key string for format matching.")); + result = FMS_UNKNOWN; + } + break; + case FMS_FORWARDED: + case FMS_UNKNOWN: + if (PyTuple_Size(value) != 1) + { + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_WARNING, + _("Unused second item for format matching.")); + } + break; -/****************************************************************************** -* * -* Paramètres : plugin = greffon de prise en charge à utiliser. * -* binary = représentation binaire à traiter. * -* action = action attendue. * -* * -* Description : Exécute une action définie sur un binaire chargé. * -* * -* Retour : true si une action a été menée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ + default: + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR, + _("Unexpected result for format matching.")); + result = FMS_UNKNOWN; + break; -static bool g_python_plugin_execute_on_binary(GPythonPlugin *plugin, GLoadedBinary *binary, PluginAction action) -{ - bool result; /* Bilan à remonter */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *value; /* Valeurs obtenues */ + } - args = PyTuple_New(2); + } - PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary))); - PyTuple_SetItem(args, 1, Py_None);//PyInt_FromLong(action)); + else + { + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR, + _("Unexpected result status for format matching.")); + result = FMS_UNKNOWN; + } - value = run_python_method(plugin->instance, "execute_on_binary", args); + } + else + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_WARNING, + _("Interpreting a empty tuple as FMS_UNKNOWN " \ + "for format matching.")); - result = (value == Py_True); + } + else + g_plugin_module_log_variadic_message(G_PLUGIN_MODULE(plugin), LMT_ERROR, + _("Expected a tuple containing [ status, key ] as result " \ + "for format matching.")); Py_XDECREF(value); Py_DECREF(args); return result; -} +} -#if 0 /****************************************************************************** * * -* Paramètres : plugin = greffon à consulter. * -* debugger = débogueur à l'origine de l'opération. * -* action = action attendue. * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* binary = binaire dont le contenu est en cours de traitement. * * * -* Description : Exécute une action relative à un débogueur. * +* Description : Exécute une action pendant un désassemblage de binaire. * * * -* Retour : true si une action a été menée, false sinon. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinaryDebugger *debugger, PluginAction action) +static void g_python_plugin_process_disass(const GPythonPlugin *plugin, PluginAction action, GLoadedBinary *binary) { - bool result; /* Bilan à remonter */ PyObject *args; /* Arguments pour l'appel */ PyObject *value; /* Valeurs obtenues */ args = PyTuple_New(2); - PyTuple_SetItem(args, 0, py_binary_debugger_from_c(debugger)); - PyTuple_SetItem(args, 1, Py_None);//PyInt_FromLong(action)); + PyTuple_SetItem(args, 0, PyLong_FromLong(action)); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(binary))); - value = run_python_method(plugin->instance, "handle_debugger", args); - - result = (value == Py_True); + value = run_python_method(plugin->instance, "process_binary_disassembly", args); Py_XDECREF(value); Py_DECREF(args); - return result; - } -#endif - - - - @@ -791,19 +694,6 @@ static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinary /* ---------------------------------------------------------------------------------- */ - - - - - - - - - - - - - /****************************************************************************** * * * Paramètres : obj_type = type dont le dictionnaire est à compléter. * diff --git a/plugins/python/apkfiles/__init__.py b/plugins/python/apkfiles/__init__.py index 2ebf824..7da894e 100644 --- a/plugins/python/apkfiles/__init__.py +++ b/plugins/python/apkfiles/__init__.py @@ -1,2 +1,4 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- -from apkfiles import ApkFiles as apkfiles +from apkfiles.apkfiles import ApkFiles as AutoLoad diff --git a/plugins/python/apkfiles/apkfiles.py b/plugins/python/apkfiles/apkfiles.py index 7c05ca9..b85b0c8 100644 --- a/plugins/python/apkfiles/apkfiles.py +++ b/plugins/python/apkfiles/apkfiles.py @@ -1,15 +1,36 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -from pychrysalide import Plugin - +from pychrysalide import PluginModule import zipfile -class ApkFiles(Plugin): +class ApkFiles(PluginModule): """Open and process APK files.""" + def get_interface(self): + """Provide the full plugin description.""" + + desc = { + + 'name' : 'Welcome', + 'desc' : 'Add suppport for the APK file format', + 'version' : '0.1', + + 'actions' : [ PluginModule.PGA_PLUGIN_INIT ] + + } + + return desc + + + def init(self, ref): + """Initialise l'extension.""" + + return True + + def get_action(self): """Register the plugin for given actions.""" diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c index 53995e5..2497dd1 100644 --- a/plugins/ropgadgets/select.c +++ b/plugins/ropgadgets/select.c @@ -1316,7 +1316,8 @@ static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref) GtkEntry *entry; /* Zone de saisie de texte */ const gchar *filename; /* Nom du fichier à charger */ GBinContent *content; /* Contenu binaire chargé */ - const char *target; /* Sous-traitance requise */ + FormatMatchStatus status; /* Statut d'une reconnaissance */ + char *target; /* Sous-traitance requise */ const char *desc; /* Description humaine associée*/ /* Récupération du nom de fichier */ @@ -1338,18 +1339,21 @@ static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref) /* Récupération du format de fichier associé */ - target = find_matching_format(content, NULL); - desc = get_binary_format_name(target); + status = find_matching_format(content, NULL, &target); - if (desc == NULL) + if (status != FMS_MATCHED) { g_object_unref(G_OBJECT(content)); push_status_printing_of_rop_search_step(ref, "format", _("unknown binary format"), false); goto leffrg_error; } + desc = get_binary_format_name(target); + result = load_new_named_format(target, content, NULL); + free(target); + if (result == NULL) { push_status_printing_of_rop_search_step(ref, "format", _("error while loading the binary"), false); |