diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2010-03-31 21:12:35 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2010-03-31 21:12:35 (GMT) | 
| commit | 7cbdd17b441b35d48624956aa438bde69f18bc37 (patch) | |
| tree | 438af8d0a994d6e203cf66ea91cf336bb071ee44 /plugins/pyoida/plugin.c | |
| parent | d5e55f2ad015781bd7bee0e3216e47d6218e0841 (diff) | |
Implemented first steps to a Python plugins support.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@146 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/pyoida/plugin.c')
| -rw-r--r-- | plugins/pyoida/plugin.c | 555 | 
1 files changed, 555 insertions, 0 deletions
| diff --git a/plugins/pyoida/plugin.c b/plugins/pyoida/plugin.c new file mode 100644 index 0000000..23934a9 --- /dev/null +++ b/plugins/pyoida/plugin.c @@ -0,0 +1,555 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * plugin.c - interactions avec un greffon Python + * + * Copyright (C) 2010 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#include "plugin.h" + + +#include "../../src/analysis/binary.h" +#include "../../src/plugins/plugin-int.h" + + +#include "analysis/binary.h" + + + + + + + +/* --------------------- INTERFACE INTERNE POUR GREFFONS PYTHON --------------------- */ + + +/* Ligne de représentation de code binaire (instance) */ +struct _GPythonPlugin +{ +    GPluginModule parent;                   /* Instance parente            */ + +    PyObject *module;                       /* Script Python chargé        */ + +}; + + +/* Ligne de représentation de code binaire (classe) */ +struct _GPythonPluginClass +{ +    GPluginModuleClass parent;              /* Classe parente              */ + +}; + + +/* Initialise la classe des greffons Python. */ +static void g_python_plugin_class_init(GPythonPluginClass *); + +/* Initialise l'instance d'un greffon Python. */ +static void g_python_plugin_init(GPythonPlugin *); + +/* Exécute une action définie sur un binaire chargé. */ +static bool g_python_plugin_execute(GPythonPlugin *, GOpenidaBinary *, PluginAction); + + +/* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */ + + +/* Classe plugin pour Python */ +typedef struct _pyoida_plugin +{ +    PyObject_HEAD + +} pyoida_plugin; + + + + + + +/* Crée un nouveau greffon Python abstrait. */ +static PyObject *pyoida_plugin_new(PyTypeObject *, PyObject *, PyObject *); + +/* Exécute une action valide pour le greffon Python. */ +static PyObject *pyoida_plugin_run(PyObject *, PyObject *); + + + +/* Définit les constantes pour les greffons en Python. */ +static bool pyoida_plugin_define_constants(PyObject *); + + + + + + + + + + + + + +int +main2(const char *filename, const char *method) +{ +    PyObject *pName, *pModule, *pDict, *pFunc; +    PyObject *pArgs, *pValue; +    int i; +    return 0; +    pName = PyString_FromString/*PyUnicode_FromString*/(filename); +    /* Error checking of pName left out */ + +    pModule = PyImport_Import(pName); +    Py_DECREF(pName); + +    if (pModule != NULL) { +        pFunc = PyObject_GetAttrString(pModule, method); +        /* pFunc is a new reference */ + +        if (pFunc && PyCallable_Check(pFunc)) { +            pArgs = PyTuple_New(0/*argc - 3*/); +#if 0 +            for (i = 0; i < argc - 3; ++i) { +                pValue = PyLong_FromLong(atoi(argv[i + 3])); +                if (!pValue) { +                    Py_DECREF(pArgs); +                    Py_DECREF(pModule); +                    fprintf(stderr, "Cannot convert argument\n"); +                    return 1; +                } +                /* pValue reference stolen here: */ +                PyTuple_SetItem(pArgs, i, pValue); +            } +#endif +            pValue = PyObject_CallObject(pFunc, pArgs); +            Py_DECREF(pArgs); +            if (pValue != NULL) { +                printf("Result of call: %ld\n", PyLong_AsLong(pValue)); +                Py_DECREF(pValue); +            } +            else { +                Py_DECREF(pFunc); +                Py_DECREF(pModule); +                PyErr_Print(); +                fprintf(stderr,"Call failed\n"); +                return 1; +            } +        } +        else { +            if (PyErr_Occurred()) +                PyErr_Print(); +            fprintf(stderr, "Cannot find function \"%s\"\n", method); +        } +        Py_XDECREF(pFunc); +        Py_DECREF(pModule); +    } +    else { +        PyErr_Print(); +        fprintf(stderr, "Failed to load \"%s\"\n", filename); +        return 1; +    } +    return 0; +} + + + + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                       INTERFACE INTERNE POUR GREFFONS PYTHON                       */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit par la GLib pour le greffon Python. */ +G_DEFINE_TYPE(GPythonPlugin, g_python_plugin, G_TYPE_PLUGIN_MODULE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des greffons Python.                    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_python_plugin_class_init(GPythonPluginClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise l'instance d'un greffon Python.                   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +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; + +} + + + + +PyObject *run_python_method(PyObject *module, const char *method, PyObject *args) +{ +    PyObject *result;                       /* Bilan à retourner           */ +    PyObject *func;                         /* Fonction visée              */ + +    result = NULL; + +    func = PyObject_GetAttrString(module, method); +    if (func == NULL) return NULL; + +    if (PyCallable_Check(func)) +    { +        result = PyObject_CallObject(func, args); +        if (result == NULL) PyErr_Print(); +    } +    else if (PyErr_Occurred()) PyErr_Print(); + +    Py_DECREF(func); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : filename = chemin d'accès au code Python à charger.          * +*                                                                             * +*  Description : Crée un greffon à partir de code Python.                     * +*                                                                             * +*  Retour      : Adresse de la structure mise en place ou NULL si erreur.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GPluginModule *g_python_plugin_new(const char *filename) +{ +    GPythonPlugin *result;                  /* Structure à retourner       */ +    PyObject *name;                         /* Chemin d'accès pour Python  */ +    PyObject *module;                       /* Script Python chargé        */ + +#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); +    Py_DECREF(name); + +    if (module == NULL) +    { +        PyErr_Print(); +        goto gppn_bad_exit; +    } + + + +    //Py_DECREF(module); + + + +    result = g_object_new(G_TYPE_PYTHON_PLUGIN, NULL); + +    G_PLUGIN_MODULE(result)->action = PGA_CODE_PROCESS; + +    result->module = module; + +    return G_PLUGIN_MODULE(result); + + gppn_bad_exit: + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  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   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_python_plugin_execute(GPythonPlugin *plugin, GOpenidaBinary *binary, PluginAction action) +{ +    PyObject *args;                         /* Arguments pour l'appel      */ +    PyObject *arg;                          /* Un des arguments de l'appel */ +    PyObject *value;                        /* Valeur obtenue              */ + + + +    printf("I am running !!"); + +    args = PyTuple_New(1); + + +    arg = Py_BuildValue("O&", py_binary_new_from_existing, binary); +    PyTuple_SetItem(args, 0, arg); + + +    value = run_python_method(plugin->module, "get_instance", args); + +    if (value != NULL) +    { +        printf("Result of call: %ld\n", PyLong_AsLong(value)); +        Py_DECREF(value); +    } + + +    Py_DECREF(args); + + + + + + +} + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                           MODULE PYTHON POUR LES SCRIPTS                           */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type de l'objet à instancier.                         * +*                args = arguments fournis à l'appel.                          * +*                kwds = arguments de type key=val fournis.                    * +*                                                                             * +*  Description : Crée un nouveau greffon Python abstrait.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *pyoida_plugin_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    pyoida_plugin *result;                  /* Instance à retourner        */ + +    result = (pyoida_plugin *)type->tp_alloc(type, 0); + +    return (PyObject *)result; + +} + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : dict = dictionnaire à compléter.                             * +*                                                                             * +*  Description : Définit les constantes pour les greffons en Python.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool pyoida_plugin_define_constants(PyObject *dict) +{ +    int ret;                                /* Bilan d'un ajout            */ + +    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; + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  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.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *pyoida_plugin_run(PyObject *self, PyObject *args) +{ +    return Py_None; + +} + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Ajoute l'objet 'plugin' au module Python.                    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool add_plugin_to_python_module(PyObject *module) +{ +    int ret;                                /* Bilan d'un appel            */ + + +static PyMethodDef pyoida_plugin_methods[] = { +    { "run", (PyCFunction)pyoida_plugin_run, METH_VARARGS, +     "Run the plugin for a specific action." +    }, +    NULL +}; + + +static PyTypeObject pyoida_plugin_type = { + +    PyObject_HEAD_INIT(NULL) + +#if PY_VERSION_HEX < 0x03000000 +    0,                         /*ob_size*/ +#endif + +    "plugin.Plugin",             /* tp_name */ +    sizeof(pyoida_plugin),             /* tp_basicsize */ +    0,                         /* tp_itemsize */ +    0, /* tp_dealloc */ +    0,                         /* tp_print */ +    0,                         /* tp_getattr */ +    0,                         /* tp_setattr */ +    0,                         /* tp_reserved / tp_compare */ +    0,                         /* tp_repr */ +    0,                         /* tp_as_number */ +    0,                         /* tp_as_sequence */ +    0,                         /* tp_as_mapping */ +    0,                         /* tp_hash  */ +    0,                         /* tp_call */ +    0,                         /* tp_str */ +    0,                         /* tp_getattro */ +    0,                         /* tp_setattro */ +    0,                         /* tp_as_buffer */ +    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ +    "PyOIDA Plugin objects",           /* tp_doc */ +    0,		               /* tp_traverse */ +    0,		               /* tp_clear */ +    0,		               /* tp_richcompare */ +    0,		               /* tp_weaklistoffset */ +    0,		               /* tp_iter */ +    0,		               /* tp_iternext */ +    pyoida_plugin_methods,             /* tp_methods */ +    0,             /* tp_members */ +    0,                         /* tp_getset */ +    0,                         /* tp_base */ +    0,                         /* tp_dict */ +    0,                         /* tp_descr_get */ +    0,                         /* tp_descr_set */ +    0,                         /* tp_dictoffset */ +    0,      /* tp_init */ +    0,                         /* tp_alloc */ +    (newfunc)pyoida_plugin_new,                 /* tp_new */ +}; + + + + +    printf("Adding pyoida pg type...\n"); + +    if (PyType_Ready(&pyoida_plugin_type) < 0) +        return false; + +    printf("Adding pyoida pg type\n"); + + +    if (!pyoida_plugin_define_constants(pyoida_plugin_type.tp_dict)) +        return false; + + + + +    Py_INCREF(&pyoida_plugin_type); +    PyModule_AddObject(module, "Plugin", (PyObject *)&pyoida_plugin_type); + + +    return true;    /* FIXME */ + + +} | 
