diff options
| -rw-r--r-- | ChangeLog | 36 | ||||
| -rw-r--r-- | plugins/pyoida/plugin.c | 250 | ||||
| -rw-r--r-- | plugins/pyoida/plugin.h | 2 | ||||
| -rw-r--r-- | plugins/pyoida/pyoida.c | 118 | ||||
| -rw-r--r-- | plugins/python/apkfiles/__init__.py | 2 | ||||
| -rw-r--r-- | plugins/python/apkfiles/apkfiles.py | 34 | ||||
| -rw-r--r-- | src/analysis/binary.c | 41 | ||||
| -rw-r--r-- | src/common/environment.c | 2 | ||||
| -rwxr-xr-x | src/format/dex/dex.c | 2 | ||||
| -rw-r--r-- | src/format/format.c | 54 | ||||
| -rw-r--r-- | src/format/format.h | 2 | ||||
| -rw-r--r-- | src/gtkext/gtksourceview.c | 3 | ||||
| -rw-r--r-- | src/plugins/plugin-def.h | 27 | ||||
| -rw-r--r-- | src/plugins/plugin-int.h | 12 | ||||
| -rw-r--r-- | src/plugins/plugin.c | 81 | ||||
| -rw-r--r-- | src/plugins/plugin.h | 6 | 
16 files changed, 622 insertions, 50 deletions
@@ -1,3 +1,39 @@ +11-10-01  Cyrille Bagard <nocbos@gmail.com> + +	* plugins/pyoida/plugin.c: +	* plugins/pyoida/plugin.h: +	Properly load a Python plugin and define some needed functions +	for format recognition. + +	* plugins/pyoida/pyoida.c: +	Browse directories for finding Python plugins. + +	* plugins/python/apkfiles/apkfiles.py: +	* plugins/python/apkfiles/__init__.py: +	New entries: define the first real [python] plugin. + +	* src/analysis/binary.c: +	Start to update call to load_new_format(). + +	* src/common/environment.c: +	Fix a bug when getting an environment variable. + +	* src/format/dex/dex.c: +	Dummy fix. + +	* src/format/format.c: +	* src/format/format.h: +	Load formats usings plugins too. + +	* src/gtkext/gtksourceview.c: +	Dummy fix. + +	* src/plugins/plugin.c: +	* src/plugins/plugin-def.h: +	* src/plugins/plugin.h: +	* src/plugins/plugin-int.h: +	Update interfaces for plugins (mainly those which are looking for formats). +  11-07-11  Cyrille Bagard <nocbos@gmail.com>  	* configure.ac: diff --git a/plugins/pyoida/plugin.c b/plugins/pyoida/plugin.c index 23934a9..e652949 100644 --- a/plugins/pyoida/plugin.c +++ b/plugins/pyoida/plugin.c @@ -46,6 +46,7 @@ struct _GPythonPlugin      GPluginModule parent;                   /* Instance parente            */      PyObject *module;                       /* Script Python chargé        */ +    PyObject *instance;                     /* Instance Python du greffon  */  }; @@ -64,6 +65,12 @@ static void g_python_plugin_class_init(GPythonPluginClass *);  /* Initialise l'instance d'un greffon Python. */  static void g_python_plugin_init(GPythonPlugin *); +/* 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(GPythonPlugin *, GOpenidaBinary *, PluginAction); @@ -94,7 +101,11 @@ static PyObject *pyoida_plugin_run(PyObject *, PyObject *);  /* Définit les constantes pour les greffons en Python. */  static bool pyoida_plugin_define_constants(PyObject *); +/* Définit le comportement par défaut d'un greffon Python. */ +static PyObject *pyoida_plugin_get_action(PyObject *, PyObject *); +/* Définit l'issue de la recherche d'un format par défaut. */ +static PyObject *pyoida_plugin_is_matching(PyObject *, PyObject *); @@ -260,7 +271,8 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args  /******************************************************************************  *                                                                             * -*  Paramètres  : filename = chemin d'accès au code Python à charger.          * +*  Paramètres  : modname  = nom du module à charger.                          * +*                filename = chemin d'accès au code Python à charger.          *  *                                                                             *  *  Description : Crée un greffon à partir de code Python.                     *  *                                                                             * @@ -270,18 +282,20 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args  *                                                                             *  ******************************************************************************/ -GPluginModule *g_python_plugin_new(const char *filename) +GPluginModule *g_python_plugin_new(const char *modname, const char *filename)  {      GPythonPlugin *result;                  /* Structure à retourner       */      PyObject *name;                         /* Chemin d'accès pour Python  */      PyObject *module;                       /* Script Python chargé        */ +    PyObject *dict;                         /* Dictionnaire associé        */ +    PyObject *class;                        /* Classe à instancier         */ +    PyObject *instance;                     /* Instance Python du greffon  */  #if PY_VERSION_HEX >= 0x03000000      name = PyUnicode_FromString(filename);  #else      name = PyString_FromString(filename);  #endif -    name = PyString_FromString/*PyUnicode_FromString*/(filename);      if (name == NULL) goto gppn_bad_exit;      module = PyImport_Import(name); @@ -293,20 +307,37 @@ GPluginModule *g_python_plugin_new(const char *filename)          goto gppn_bad_exit;      } +    dict = PyModule_GetDict(module); +    class = PyDict_GetItemString(dict, modname); +    Py_DECREF(dict); +    if (class == NULL) goto gppn_no_class; +    if (!PyType_Check(class->ob_type)) goto gppn_no_class; -    //Py_DECREF(module); - +    instance = PyObject_CallFunction(class, NULL); +    if (instance == NULL) goto gppn_no_instance; +    Py_DECREF(class);      result = g_object_new(G_TYPE_PYTHON_PLUGIN, NULL); -    G_PLUGIN_MODULE(result)->action = PGA_CODE_PROCESS; +    G_PLUGIN_MODULE(result)->get_action = g_python_plugin_get_action; + +    G_PLUGIN_MODULE(result)->is_matching = g_python_plugin_is_matching;      result->module = module; +    result->instance = instance;      return G_PLUGIN_MODULE(result); + gppn_no_instance: + +    Py_DECREF(class); + + gppn_no_class: + +    Py_DECREF(module); +   gppn_bad_exit:      return NULL; @@ -317,6 +348,138 @@ GPluginModule *g_python_plugin_new(const char *filename)  /******************************************************************************  *                                                                             *  *  Paramètres  : plugin = greffon de prise en charge à utiliser.              * +*                                                                             * +*  Description : Indique l'utilité pratique du greffon.                       * +*                                                                             * +*  Retour      : Action(s) codifiée(s), PGA_NONE par défaut.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin) +{ +    PluginAction result;                    /* Valeur à retourner          */ +    PyObject *value;                        /* Valeur obtenue              */ + +    value = run_python_method(plugin->instance, "get_action", NULL); + +    result = PyLong_AsLong(value); +    Py_DECREF(value); + +    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) +{ +    MatchingFormatAction result;            /* Valeur à retourner          */ +    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      */ + +    if (*filename == NULL) +        return MFA_NONE; + +    args = PyTuple_New(2); + +    PyTuple_SetItem(args, 0, PyString_FromString(*filename)); +    PyTuple_SetItem(args, 1, PyByteArray_FromStringAndSize(*data, *length)); + +    value = run_python_method(plugin->instance, "is_matching", args); + +    if (value != NULL && PyTuple_Check(value) && PyTuple_Size(value) == 3) +    { +        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) +            *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) +            *filename = NULL; + +        /** +         * Pareil que précédemment. +         */ +        if (new_data != Py_None) +        { +            tmp = PyByteArray_AsString(new_data); +            *length = PyByteArray_Size(new_data); + +            *data = (bin_t *)calloc(*length, sizeof(bin_t)); +            memcpy(*data, tmp, *length * sizeof(bin_t)); + +        } + +        goto is_matching_ok; + +    } + + is_matching_bad: + +    printf("<LOG>Bad result from is_matching() plugin function.\n"); + +    result = MFA_NONE; + + is_matching_ok: + +    Py_XDECREF(value); +    Py_DECREF(args); + +    return result; + +} + + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon de prise en charge à utiliser.              *  *                binary = représentation binaire à traiter.                   *  *                action = action attendue.                                    *  *                                                                             * @@ -421,12 +584,29 @@ static bool pyoida_plugin_define_constants(PyObject *dict)  {      int ret;                                /* Bilan d'un ajout            */ +    ret = PyDict_SetItemString(dict, "PGA_NONE", PyInt_FromLong(PGA_NONE)); +    if (ret == -1) return false; + +    ret = PyDict_SetItemString(dict, "PGA_FORMAT_MATCHER", PyInt_FromLong(PGA_FORMAT_MATCHER)); +    if (ret == -1) return false; +      ret = PyDict_SetItemString(dict, "PGA_DISASSEMBLE", PyInt_FromLong(PGA_DISASSEMBLE));      if (ret == -1) return false;      ret = PyDict_SetItemString(dict, "PGA_CODE_PROCESS", PyInt_FromLong(PGA_CODE_PROCESS));      if (ret == -1) return false; +    /* PGA_FORMAT_MATCHER */ + +    ret = PyDict_SetItemString(dict, "MFA_NONE", PyInt_FromLong(MFA_NONE)); +    if (ret == -1) return false; + +    ret = PyDict_SetItemString(dict, "MFA_MATCHED", PyInt_FromLong(MFA_MATCHED)); +    if (ret == -1) return false; + +    ret = PyDict_SetItemString(dict, "MFA_RELOAD", PyInt_FromLong(MFA_RELOAD)); +    if (ret == -1) return false; +      return true;  } @@ -437,6 +617,58 @@ static bool pyoida_plugin_define_constants(PyObject *dict)  *  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   *  *                args = arguments fournis à l'appel.                          *  *                                                                             * +*  Description : Définit le comportement par défaut d'un greffon Python.      * +*                                                                             * +*  Retour      : Rien en équivalent Python.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *pyoida_plugin_get_action(PyObject *self, PyObject *args) +{ +    return PyInt_FromLong(PGA_NONE); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   * +*                args = arguments fournis à l'appel.                          * +*                                                                             * +*  Description : Définit l'issue de la recherche d'un format par défaut.      * +*                                                                             * +*  Retour      : Rien en équivalent Python.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *pyoida_plugin_is_matching(PyObject *self, PyObject *args) +{ +    PyObject *result;                       /* Liste à retourner           */ + +    result = PyTuple_New(3); + +    PyTuple_SetItem(result, 0, PyInt_FromLong(MFA_NONE)); +    PyTuple_SetItem(result, 1, Py_None); +    PyTuple_SetItem(result, 2, Py_None); + +    return result; + +} + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = classe assurant le lien avec l'éditeur de messages.   * +*                args = arguments fournis à l'appel.                          * +*                                                                             *  *  Description : Exécute une action valide pour le greffon Python.            *  *                                                                             *  *  Retour      : Rien en équivalent Python.                                   * @@ -474,6 +706,12 @@ bool add_plugin_to_python_module(PyObject *module)  static PyMethodDef pyoida_plugin_methods[] = { +    { "get_action", (PyCFunction)pyoida_plugin_get_action, METH_NOARGS, +     "Register the plugin for given actions." +    }, +    { "is_matching", (PyCFunction)pyoida_plugin_is_matching, METH_VARARGS, +     "Define if the given file can be handled." +    },      { "run", (PyCFunction)pyoida_plugin_run, METH_VARARGS,       "Run the plugin for a specific action."      }, diff --git a/plugins/pyoida/plugin.h b/plugins/pyoida/plugin.h index f5d4ab4..b8b76d9 100644 --- a/plugins/pyoida/plugin.h +++ b/plugins/pyoida/plugin.h @@ -60,7 +60,7 @@ typedef struct _GPythonPluginClass GPythonPluginClass;  GType g_python_plugin_get_type(void);  /* Crée un greffon à partir de code Python. */ -GPluginModule *g_python_plugin_new(const char *); +GPluginModule *g_python_plugin_new(const char *, const char *); diff --git a/plugins/pyoida/pyoida.c b/plugins/pyoida/pyoida.c index 4a79bfd..be75b7c 100644 --- a/plugins/pyoida/pyoida.c +++ b/plugins/pyoida/pyoida.c @@ -24,6 +24,10 @@  #include "pyoida.h" +#include <config.h> +#include <dirent.h> + +  #include <Python.h> @@ -69,6 +73,7 @@ static PyMethodDef SpamMethods[] = { +static PyObject *__mod;  /****************************************************************************** @@ -85,17 +90,37 @@ static PyMethodDef SpamMethods[] = {  bool init_plugin(GObject *ref)  { +    char *paths;                            /* Emplacements de greffons    */ +    char *path;                             /* Chemin à fouiller           */ +    char *save;                             /* Sauvegarde pour ré-entrance */ +    DIR *dir;                               /* Répertoire à parcourir      */ +    struct dirent entry;                    /* Elément trouvé              */ +    struct dirent *next;                    /* Prochain élément fourni     */ +    int ret;                                /* Bilan d'un appel système    */ +    char *filename;                         /* Chemin d'accès reconstruit  */ + + + +      GPluginModule *plugin; -    int ret; + +      printf("Init pyoida\n");      _ref = ref; -    add_to_env_var("PYTHONPATH", "/home/ocb/prog/openida/plugins/python", ";"); + +    /* Définition des zones d'influence */ + +    add_to_env_var("PYTHONPATH", PLUGINS_DIR G_DIR_SEPARATOR_S "python", ";"); + +    paths = get_env_var("PYTHONPATH"); + +    /* Intialisations Python */ -    return false; +    //return false;      Py_Initialize(); @@ -104,33 +129,92 @@ bool init_plugin(GObject *ref) +    /* Chargement des greffons */ -    plugin = g_python_plugin_new("lnxsyscalls/lnxsyscalls"); -    add_plugin_to_main_list(plugin); +    printf("Paths :: '%s'\n", paths); +    for (path = strtok_r(paths, ";", &save); +         path != NULL;  +         path = strtok_r(NULL, ";", &save)) +    { +        dir = opendir(path); +        if (dir == NULL) +        { +            perror("opendir"); +            continue; +        } +        printf("CHEMIN :: '%s'\n", path); -#if 0 +        for (ret = readdir_r(dir, &entry, &next); +             ret == 0 && next != NULL; +             ret = readdir_r(dir, &entry, &next)) +        { +            if (entry.d_name[0] == '.') continue; -#if 0 -    //main2("/home/ocb/prog/openida/plugins/pyoida/lnxsyscalls/lnxsyscalls.py", "get_instance"); -    main2("lnxsyscalls", "get_instance"); -#else -    //main2("/home/ocb/prog/openida/plugins/pyoida/lnxsyscalls/lnxsyscalls.py", "get_instance"); -    main2("lnxsyscalls/lnxsyscalls", "get_instance"); -#endif +            filename = strdup(entry.d_name); +            filename = stradd(filename, "."); +            filename = stradd(filename, "__init__"); -#endif +            printf(" - entry :: '%s'\n", filename); -    //Py_Finalize(); -    //exit(-1); +            plugin = g_python_plugin_new(entry.d_name, filename); + +            if (plugin == NULL) +                 printf("No suitable Python plugin found in '%s'\n", filename);  /* FIXME : LOG(...) */ +            else +            { +                printf("ok pour %s\n", filename); +                add_plugin_to_main_list(plugin); +            } + +            free(filename); + +        } + +         closedir(dir); + +         break; /* FIXME */ + +    } + +    //Py_Finalize();      return true;  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à consulter.                                * +*                                                                             * +*  Description : Indique les opérations offertes par un greffon donné.        * +*                                                                             * +*  Retour      : Action(s) offerte(s) par le greffon.                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PluginAction get_plugin_action(const GPluginModule *plugin) +{ +    PluginAction result;                    /* Combinaison à retourner     */ + +    result = PGA_NONE; + + + + +    return result; + +} + + + + +  #if PY_VERSION_HEX >= 0x03000000  /* Python 3.x code */ @@ -169,6 +253,8 @@ initpyoida(void)      printf("Passage 2\n");      module = Py_InitModule("pyoida", SpamMethods); +    __mod = module; +      //add_analysis_roptions_to_python_module(module);      add_analysis_module_to_python_module(module);      add_arch_module_to_python_module(module); diff --git a/plugins/python/apkfiles/__init__.py b/plugins/python/apkfiles/__init__.py new file mode 100644 index 0000000..2ebf824 --- /dev/null +++ b/plugins/python/apkfiles/__init__.py @@ -0,0 +1,2 @@ + +from apkfiles import ApkFiles as apkfiles diff --git a/plugins/python/apkfiles/apkfiles.py b/plugins/python/apkfiles/apkfiles.py new file mode 100644 index 0000000..fe7deb8 --- /dev/null +++ b/plugins/python/apkfiles/apkfiles.py @@ -0,0 +1,34 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from pyoida import Plugin + +import zipfile + + +class ApkFiles(Plugin): +    """Open and process APK files.""" + +    def get_action(self): +        """Register the plugin for given actions.""" + +        return Plugin.PGA_FORMAT_MATCHER + +    def is_matching(self, filename, data): +        """Define if the given file can be handled.""" + +        if not zipfile.is_zipfile(filename): +            return Plugin.MFA_NONE, None, None + +        zf = zipfile.ZipFile(filename) + +        if zf.namelist().count('classes.dex') > 0: + +            f = zf.open('classes.dex', 'r') +            data = f.read() +            f.closed + +            return Plugin.MFA_RELOAD, None, bytearray(data) + +        else: +            return Plugin.MFA_NONE, None, None diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 15be43e..f5ff3fb 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -365,17 +365,56 @@ static void g_openida_binary_init(GOpenidaBinary *binary)  GOpenidaBinary *g_openida_binary_new_from_file(const char *filename)  {      GOpenidaBinary *result;                 /* Adresse à retourner         */ +    GPluginModule **pglist;                 /* Liste de greffons           */ +    size_t pgcount;                         /* Taille de cette liste       */ +    size_t i;                               /* Boucle de parcours          */ + + +    char *file = strdup(filename);      result = g_object_new(G_TYPE_OPENIDA_BINARY, NULL); + + + +    printf("%s\n", filename); + + + +    pglist = get_all_plugins_for_action(PGA_FORMAT_MATCHER, &pgcount); + +    if (pgcount > 0) +    { +        printf("===>>>> FOUND :: %d\n", pgcount); + + +        /* +        for (i = 0; i < pgcount; i++) +            g_plugin_module_execute_action_on_binary(pglist[i], binary, PGA_CODE_PROCESS); +        */ +        free(pglist); + +    } + + + + + + + + +      log_variadic_message(LMT_PROCESS, _("Opening '%s' file..."), filename);      result->filename = strdup(filename); +    /*      result->bin_data = map_binary_file(filename, &result->bin_length);      if (result->bin_data == NULL) goto lbf_error; +    */ -    result->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, result->bin_data, result->bin_length)); +    result->format = G_EXE_FORMAT(load_new_format(FMT_EXEC, file, +                                                  &result->bin_data, &result->bin_length));      if (result->format == NULL)      {          log_simple_message(LMT_INFO, _("Unknown binary format")); diff --git a/src/common/environment.c b/src/common/environment.c index a0fa568..633d3e2 100644 --- a/src/common/environment.c +++ b/src/common/environment.c @@ -52,7 +52,7 @@ char *get_env_var(const char *name)      result = getenv(name);      if (result == NULL) result = strdup(""); -    else result = strdup(name); +    else result = strdup(result);      return result; diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index 174bd2b..287c9ea 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -224,6 +224,8 @@ static void g_dex_format_find_all_sources(GDexFormat *format)      bf = G_BIN_FORMAT(format); +    return; /* FIXME */ +      for (i = 0; i < format->classes_count; i++)      {          source = g_dex_class_get_source_file(format->classes[i], format); diff --git a/src/format/format.c b/src/format/format.c index 053a7aa..8e1d864 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -35,6 +35,7 @@  #include "pe/pe.h"  #include "../decomp/expr/block.h"  #include "../panels/log.h" +#include "../plugins/pglist.h" @@ -497,9 +498,10 @@ bool init_all_formats(void)  /******************************************************************************  *                                                                             * -*  Paramètres  : type    = type de format recherché.                          * -*                content = contenu binaire à parcourir.                       * -*                length  = taille du contenu en question.                     * +*  Paramètres  : type     = type de format recherché.                         * +*                filename = fichier d'origine des données initiales.          * +*                content  = contenu binaire à parcourir. [OUT]                * +*                length   = taille du contenu en question. [OUT]              *  *                                                                             *  *  Description : Charge si possible un nouveau format binaire.                *  *                                                                             * @@ -509,22 +511,62 @@ bool init_all_formats(void)  *                                                                             *  ******************************************************************************/ -GBinFormat *load_new_format(FormatType type, const uint8_t *content, off_t length) +GBinFormat *load_new_format(FormatType type, char *filename, bin_t **content, off_t *length)  {      GBinFormat *result;                     /* Adresse à retourner         */ +    GPluginModule **pglist;                 /* Liste de greffons           */ +    size_t pgcount;                         /* Taille de cette liste       */      size_t i;                               /* Boucle de parcours          */      result = NULL; +    printf("analysing... %s\n", filename); + + + +    pglist = get_all_plugins_for_action(PGA_FORMAT_MATCHER, &pgcount); + +    if (pgcount > 0) +    { + lnf_rescan: + +        for (i = 0; i < pgcount; i++) +            switch (g_plugin_module_is_matching(pglist[i], &filename, content, length)) +            { +                case MFA_MATCHED: +                    /* FIXME */ +                    break; + +                case MFA_RELOAD: +                    //goto lnf_rescan; +                    break; + +                default: +                    break; + +            } + +        free(pglist); + +    } + + +      for (i = 0; i < FID_COUNT && result == NULL; i++) -        if (_formats[i].type == type && _formats[i].match(type, content, length)) +        if (_formats[i].type == type && _formats[i].match(type, *content, *length))          {              log_variadic_message(LMT_INFO, _("%s is matching..."), _formats[i].name); -            result = _formats[i].load(content, length); +            result = _formats[i].load(*content, *length);          } + + +    printf("FINAL FORMAT :: %p\n", result); + +    //exit(0); +      return result;  } diff --git a/src/format/format.h b/src/format/format.h index dd05dd2..7f0b649 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -121,7 +121,7 @@ typedef GBinFormat * (* format_load_fc) (const bin_t *, off_t);  bool init_all_formats(void);  /* Charge si possible un nouveau format binaire. */ -GBinFormat *load_new_format(FormatType, const uint8_t *, off_t); +GBinFormat *load_new_format(FormatType, char *filename, bin_t **, off_t *); diff --git a/src/gtkext/gtksourceview.c b/src/gtkext/gtksourceview.c index 33b61c5..5dea05f 100644 --- a/src/gtkext/gtksourceview.c +++ b/src/gtkext/gtksourceview.c @@ -149,6 +149,9 @@ static void gtk_source_view_attach_binary(GtkSourceView *view, GOpenidaBinary *b      buffer = g_openida_binary_get_decompiled_buffer(binary, -1); +    /* FIXME */ +    if (buffer != NULL) +      gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), buffer);  } diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h index 50b8df2..43ec28e 100644 --- a/src/plugins/plugin-def.h +++ b/src/plugins/plugin-def.h @@ -42,9 +42,13 @@ typedef enum _PluginType  /* Action(s) menée(s) par le greffon */  typedef enum _PluginAction  { -    PGA_DISASSEMBLE     = (1 << 0),         /* Désassemblage (non trivial) */ +    PGA_NONE            = (0 << 0),         /* Aucun intérêt               */ -    PGA_CODE_PROCESS    = (1 << 1)          /* Traitement du code existant */ +    PGA_FORMAT_MATCHER  = (1 << 0),         /* Détection et chargement     */ + +    PGA_DISASSEMBLE     = (1 << 1),         /* Désassemblage (non trivial) */ + +    PGA_CODE_PROCESS    = (1 << 2)          /* Traitement du code existant */  } PluginAction; @@ -54,11 +58,28 @@ typedef enum _PluginAction  typedef PluginType (* get_plugin_type_fc) (void);  /* Fournit une indication sur le type d'opération(s) menée(s). */ -typedef PluginAction (* get_plugin_action_fc) (void); +//typedef PluginAction (* get_plugin_action_fc) (void);  /* Exécute une action définie sur un binaire chargé. */  typedef bool (* execute_action_on_binary_fc) (GOpenidaBinary *, PluginAction); +/* PGA_FORMAT_MATCHER */ + +/* Bilans d'une reconnaissance */ +typedef enum _MatchingFormatAction +{ +    MFA_NONE,                               /* Aucune détection            */ +    MFA_MATCHED,                            /* Format reconnu              */ +    MFA_RELOAD,                             /* Rechargemet opéré           */ + +    MFA_COUNT + +} MatchingFormatAction; + + + + +  #endif  /* _PLUGINS_PLUGIN_DEF_H */ diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h index 929dbf9..a0b5758 100644 --- a/src/plugins/plugin-int.h +++ b/src/plugins/plugin-int.h @@ -36,6 +36,11 @@  /* Procède à l'initialisation du greffon */  typedef bool (* init_plugin_fc) (GObject *); +/* Fournit une indication sur le type d'opération(s) menée(s). */ +typedef PluginAction (* get_plugin_action_fc) (const GPluginModule *); + +/* Identifie un format à associer à un contenu binaire. */ +typedef MatchingFormatAction (* is_matching_fc) (const GPluginModule *, char **, bin_t **, off_t *);  /* Greffon pour OpenIDA (instance) */ @@ -46,9 +51,11 @@ struct _GPluginModule      GModule *module;                        /* Abstration de manipulation  */      PluginType type;                        /* Type(s) du greffon          */ -    PluginAction action;                    /* Opération(s) menée(s)       */      init_plugin_fc init;                    /* Procédure d'initialisation  */ +    get_plugin_action_fc get_action;        /* Opération(s) menée(s)       */ + +    is_matching_fc is_matching;             /* Recherche de correspondance */      execute_action_on_binary_fc exec_on_bin;/* Action sur un binaire       */ @@ -66,6 +73,9 @@ struct _GPluginModuleClass + + +  /* Ajoute un greffon à la liste principale de greffons. */  void add_plugin_to_main_list(GPluginModule *); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 2443768..ce8ef37 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -99,7 +99,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)  {      GPluginModule *result;                  /* Structure à retourner       */      get_plugin_action_fc __get_type;        /* Type(s) de greffon          */ -    get_plugin_action_fc __get_action;      /* Actions du greffon          */ +    get_plugin_action_fc get_action;        /* Actions du greffon          */      result = g_object_new(G_TYPE_PLUGIN_MODULE, NULL); @@ -107,6 +107,21 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)      result->module = g_module_open(filename, G_MODULE_BIND_LAZY); +    if (!result->module) +    { +        printf("err null mod\n"); +        return NULL; + +    } + + +    if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init)) +    { +        printf("Err plugin init sym\n"); +        /* TODO */ +    } + +    /*      if (!g_module_symbol(result->module, "get_plugin_type", (gpointer *)&__get_type)) @@ -119,20 +134,20 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)      printf("Plugin type :: 0x%08x\n", result->type); +    */ - -#if 1 -    if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&__get_action)) +    if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&get_action))      {          printf("Err plugin get_action sym\n");          //g_object_destroy(result);          return NULL;      } -    result->action = __get_action(); +    result->get_action = get_action; +    /*      if (result->action & (PGA_DISASSEMBLE | PGA_CODE_PROCESS))      {          if (!g_module_symbol(result->module, "execute_action_on_binary", (gpointer *)&result->exec_on_bin)) @@ -144,14 +159,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)      } -#endif  - - -    if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init)) -    { -        printf("Err plugin init sym\n"); -        /* TODO */ -    } +    */ @@ -188,11 +196,56 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)  PluginAction g_plugin_module_get_action(const GPluginModule *plugin)  { -    return plugin->action; +    return plugin->get_action(plugin); + +} + + +/****************************************************************************** +*                                                                             * +*  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 : Identifie un format à associer à un contenu binaire.         * +*                                                                             * +*  Retour      : Bilan de la recherche de correspondances.                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +MatchingFormatAction g_plugin_module_is_matching(const GPluginModule *plugin, char **filename, bin_t **data, off_t *length) +{ +    MatchingFormatAction result;            /* Valeur à retourner          */ +    char *old_filename;                     /* Ancien nom de fichier       */ +    bin_t *old_data;                        /* Ancien contenu binaire      */ + +    if (plugin->is_matching == NULL) +        return MFA_NONE; + +    old_filename = *filename; +    old_data = *data; + +    result = plugin->is_matching(plugin, filename, data, length); + +    if (result == MFA_RELOAD) +    { +        if (old_filename != NULL) +            free(old_filename); +        free(old_data); +    } + +    return result;  } + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : plugin = greffon à consulter.                                * diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h index d17cee5..8df0e0e 100644 --- a/src/plugins/plugin.h +++ b/src/plugins/plugin.h @@ -57,9 +57,15 @@ GPluginModule *g_plugin_module_new(const gchar *, GObject *);  /* Indique les opérations offertes par un greffon donné. */  PluginAction g_plugin_module_get_action(const GPluginModule *); +/* Identifie un format à associer à un contenu binaire. */ +MatchingFormatAction g_plugin_module_is_matching(const GPluginModule *, char **, bin_t **, off_t *); +  /* Exécute une action définie sur un binaire chargé. */  bool g_plugin_module_execute_action_on_binary(const GPluginModule *, GOpenidaBinary *, PluginAction); + + +  #endif  /* _PLUGINS_PLUGIN_H */  | 
