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/pychrysa | |
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/pychrysa')
-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 |
3 files changed, 118 insertions, 225 deletions
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. * |