diff options
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.        * | 
