diff options
Diffstat (limited to 'plugins/pyoida/plugin.c')
-rw-r--r-- | plugins/pyoida/plugin.c | 865 |
1 files changed, 0 insertions, 865 deletions
diff --git a/plugins/pyoida/plugin.c b/plugins/pyoida/plugin.c deleted file mode 100644 index 64cf013..0000000 --- a/plugins/pyoida/plugin.c +++ /dev/null @@ -1,865 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * plugin.c - interactions avec un greffon Python - * - * Copyright (C) 2010-2012 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" -#include "debug/debugger.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é */ - PyObject *instance; /* Instance Python du greffon */ - -}; - - -/* 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 *); - -/* 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); - - -/* Exécute une action relative à un débogueur. */ -static bool g_python_plugin_handle_debugger(const GPythonPlugin *, GBinaryDebugger *, 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 *); - -/* 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 *); - - -/* Exécute une action relative à un débogueur. */ -static PyObject *pyoida_plugin_handle_debugger(PyObject *, 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; - plugin_parent->handle_debugger = (execute_on_debugger_fc)g_python_plugin_handle_debugger; - -} - - - - -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 : modname = nom du module à charger. * -* 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 *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 - if (name == NULL) goto gppn_bad_exit; - - module = PyImport_Import(name); - Py_DECREF(name); - - if (module == NULL) - { - PyErr_Print(); - 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; - - 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)->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; - -} - - -/****************************************************************************** -* * -* 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. * -* * -* 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); - - - - - - -} - - - - - - -/****************************************************************************** -* * -* Paramètres : plugin = greffon à consulter. * -* debugger = débogueur à l'origine de l'opération. * -* action = action attendue. * -* * -* Description : Exécute une action relative à un débogueur. * -* * -* Retour : true si une action a été menée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinaryDebugger *debugger, PluginAction action) -{ - 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, PyInt_FromLong(action)); - - value = run_python_method(plugin->instance, "handle_debugger", args); - - result = (value == Py_True); - - Py_XDECREF(value); - Py_DECREF(args); - - return result; - -} - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* 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_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; - - ret = PyDict_SetItemString(dict, "PGA_DEBUGGER_ATTACH", PyInt_FromLong(PGA_DEBUGGER_ATTACH)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_DEBUGGER_DETACH", PyInt_FromLong(PGA_DEBUGGER_DETACH)); - 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; - -} - - -/****************************************************************************** -* * -* 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 relative à un débogueur. * -* * -* Retour : True en équivalent Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *pyoida_plugin_handle_debugger(PyObject *self, PyObject *args) -{ - Py_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[] = { - { "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." - }, - { "handle_debugger", (PyCFunction)pyoida_plugin_handle_debugger, METH_VARARGS, - "Be notify about debugger attaching or detaching." - }, - { "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 */ - - -} |