diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-01-16 19:02:56 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-01-16 19:02:56 (GMT) |
commit | 9da8f8b37e3edebc917b4e223dd2447cd7cbc818 (patch) | |
tree | 3f330b13e7ca2a0a163882be3043ca9571f25211 /plugins/pychrysa/pychrysa.c | |
parent | eb9b7fd76451db5c9f07a800c0394480e4b88c9c (diff) |
Changed the Python bindings source directory and updated code.
Diffstat (limited to 'plugins/pychrysa/pychrysa.c')
-rw-r--r-- | plugins/pychrysa/pychrysa.c | 616 |
1 files changed, 0 insertions, 616 deletions
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c deleted file mode 100644 index 35d14f4..0000000 --- a/plugins/pychrysa/pychrysa.c +++ /dev/null @@ -1,616 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * pychrysa.c - plugin permettant des extensions en Python - * - * Copyright (C) 2012-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "pychrysa.h" - - -#include <assert.h> -#include <errno.h> -#include <pygobject.h> -#include <stdio.h> -#include <stdbool.h> -#include <string.h> -#include <unistd.h> - - -#include <config.h> -#include <common/cpp.h> -#include <common/environment.h> -#include <common/extstr.h> -#include <core/core.h> -#include <plugins/pglist.h> -#include <plugins/plugin-def.h> -#include <plugins/plugin-int.h> - - -#include "helpers.h" -#include "plugin.h" -#include "struct.h" -#include "analysis/module.h" -#include "arch/module.h" -#include "common/module.h" -#include "core/module.h" -#include "debug/module.h" -#include "format/module.h" -#include "glibext/module.h" -#include "gtkext/module.h" -#include "gui/module.h" - - - -DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("PyChrysalide", "Provides bindings to Python", "0.1.0", PGA_PLUGIN_INIT); - - -/* Note la nature du chargement */ -static bool _standalone = true; - -/* Réceptacle pour le chargement forcé */ -static PyObject *_chrysalide_module = NULL; - - -/* Fournit la révision du programme global. */ -static PyObject *py_chrysalide_revision(PyObject *, PyObject *); - -/* Fournit la version du programme global. */ -static PyObject *py_chrysalide_version(PyObject *, PyObject *); - -/* Fournit la version du greffon pour Python. */ -static PyObject *py_chrysalide_mod_version(PyObject *, PyObject *); - -/* Détermine si l'interpréteur lancé est celui pris en compte. */ -static bool is_current_abi_suitable(void); - -/* Définit la version attendue de GTK à charger dans Python. */ -static bool set_version_for_gtk_namespace(const char *); - -/* Charge autant de greffons composés en Python que possible. */ -static bool load_python_plugins(GPluginModule *); - - - -/****************************************************************************** -* * -* Paramètres : self = NULL car méthode statique. * -* args = non utilisé ici. * -* * -* Description : Fournit la révision du programme global. * -* * -* Retour : Numéro de révision. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_chrysalide_revision(PyObject *self, PyObject *args) -{ - return PyUnicode_FromString("r" XSTR(REVISION)); - -} - - -/****************************************************************************** -* * -* Paramètres : self = NULL car méthode statique. * -* args = non utilisé ici. * -* * -* Description : Fournit la version du programme global. * -* * -* Retour : Numéro de version. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_chrysalide_version(PyObject *self, PyObject *args) -{ - char version[16]; - int major; - int minor; - int revision; - - major = REVISION / 1000; - minor = (REVISION - (major * 1000)) / 100; - revision = REVISION % 100; - - snprintf(version, sizeof(version), "%d.%d.%d", major, minor, revision); - - return PyUnicode_FromString(version); - -} - - -/****************************************************************************** -* * -* Paramètres : self = NULL car méthode statique. * -* args = non utilisé ici. * -* * -* Description : Fournit la version du greffon pour Python. * -* * -* Retour : Numéro de version. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_chrysalide_mod_version(PyObject *self, PyObject *args) -{ - char version[16]; - - snprintf(version, sizeof(version), "%s", _chrysalide_plugin.version); - - return PyUnicode_FromString(version); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Détermine si l'interpréteur lancé est celui pris en compte. * -* * -* Retour : true si l'exécution peut se poursuivre, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool is_current_abi_suitable(void) -{ - bool result; - int fds[2]; - int ret; - char cmds[128]; - char content[64]; - ssize_t got; - -#define GRAB_ABI_FLAGS_IN_PYTHON \ - "import sys" "\n" \ - "import os" "\n" \ - "os.write(%d, bytes(sys.abiflags, 'UTF-8'))" "\n" - - result = false; - - ret = pipe(fds); - if (ret == -1) - { - perror("pipe()"); - return false; - } - - snprintf(cmds, sizeof(cmds), GRAB_ABI_FLAGS_IN_PYTHON, fds[1]); - - ret = PyRun_SimpleString(cmds); - if (ret != 0) goto icas_exit; - - got = read(fds[0], content, sizeof(content)); - if (got < 0) - { - perror("read()"); - goto icas_exit; - } - - content[got] = '\0'; - - result = (strcmp(content, LIBPYTHON_ABI_FLAGS) == 0); - - icas_exit: - - if (!result) - PyErr_SetString(PyExc_SystemError, "the ABI flags of the current interpreter do not match " \ - "the ones of the Python library used during the module compilation."); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : version = idenfiant de la version de GTK à stipuler. * -* * -* Description : Définit la version attendue de GTK à charger dans Python. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool set_version_for_gtk_namespace(const char *version) -{ - bool result; /* Bilan à retourner */ - PyObject *gi_mod; /* Module Python-GObject */ - PyObject *args; /* Arguments à fournir */ - - result = false; - - /** - * On cherche ici à éviter le message suivant si on charge 'gi.repository.Gtk' directement : - * - * - * PyGIWarning: Gtk was imported without specifying a version first. \ - * Use gi.require_version('Gtk', '3.0') before import to ensure that the right version gets loaded. - * - */ - - gi_mod = PyImport_ImportModule("gi"); - - if (gi_mod != NULL) - { - args = Py_BuildValue("ss", "Gtk", "3.0"); - - run_python_method(gi_mod, "require_version", args); - - result = (PyErr_Occurred() == NULL); - - Py_DECREF(args); - Py_DECREF(gi_mod); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Point d'entrée pour l'initialisation de Python. * -* * -* Retour : ? * -* * -* Remarques : - * -* * -******************************************************************************/ -#include <gtkext/support.h> // REMME -#include <glibext/delayed.h> - -#define PYCHRYSALIDE_DOC \ - "PyChrysalide is a module containing Chrysalide's features and designed for Python users.\n" \ - "\n" \ - "The whole API is defined in a single library named 'pychrysalide.so' and can be used in two ways:\n" \ - "* either from the Chrysalide's GUI, by registering hooks or GLib signals.\n" \ - "* or from a shell command line, by setting PYTHONPATH to point to the directory containing the library.\n" \ - "\n" \ - "In both cases, it is a good start point to have a look at already existing plugins to quickly learn " \ - "how the API works.\n" \ - "\n" \ - "These plugins are located in the 'plugins/python' directory." - -PyMODINIT_FUNC PyInit_pychrysalide(void) -{ - PyObject *result; /* Module Python à retourner */ - bool status; /* Bilan des inclusions */ - GPluginModule *self; /* Représentation interne */ - PluginStatusFlags self_flags; /* Fanions à mettre à jour */ - - static PyMethodDef py_chrysalide_methods[] = { - - { "revision", py_chrysalide_revision, - METH_NOARGS, - "revision(/)\n--\n\nProvide the revision number of Chrysalide." - }, - { "version", py_chrysalide_version, - METH_NOARGS, - "version(/)\n--\n\nProvide the version number of Chrysalide." - }, - { "mod_version", py_chrysalide_mod_version, - METH_NOARGS, - "mod_version(/)\n--\n\nProvide the version number of Chrysalide module for Python." - }, - { NULL } - - }; - - static PyModuleDef py_chrysalide_module = { - - .m_base = PyModuleDef_HEAD_INIT, - - .m_name = "pychrysalide", - .m_doc = PYCHRYSALIDE_DOC, - - .m_size = -1, - - .m_methods = py_chrysalide_methods - - }; - -#if 0 - do - { - int argc = 0; - //char *argv[] = { NULL }; - - /* Initialisation de GTK */ - g_set_prgname("Chrysalide"); - setlocale (LC_ALL, ""); - gtk_init(&argc, NULL/*&argv-*/); - - } while (0); - - add_pixmap_directory(PACKAGE_DATA_DIR); - add_pixmap_directory(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "pixmaps"); - - /** - * On évite d'initialiser deux fois... - */ - if (get_work_queue() != NULL) - init_work_queue(NULL/* !! */); -#endif - - - - - - if (!is_current_abi_suitable()) - return NULL; - - if (pygobject_init(-1, -1, -1) == NULL) - { - PyErr_SetString(PyExc_SystemError, "unable to init GObject in Python."); - return NULL; - } - - if (!set_version_for_gtk_namespace("3.0")) - return NULL; - - if (!load_all_basic_components()) - { - PyErr_SetString(PyExc_SystemError, "unable to load all basic components."); - return NULL; - } - - /* Mise en place des fonctionnalités offertes */ - - result = PyModule_Create(&py_chrysalide_module); - - status = register_python_py_struct(result); - - /* Interface 'LineGenerator' en premier... */ - if (status) status = add_glibext_module_to_python_module(result); - - /* BinRoutine hérite de BinSymbol... */ - if (status) status = add_format_module_to_python_module(result); - - if (status) status = register_python_plugin_module(result); - if (status) status = add_analysis_module_to_python_module(result); - if (status) status = add_arch_module_to_python_module(result); - if (status) status = add_common_module_to_python_module(result); - if (status) status = add_core_module_to_python_module(result); - if (status) status = add_debug_module_to_python_module(result); - if (status) status = add_gtkext_module_to_python_module(result); - if (status) status = add_gui_module_to_python_module(result); - - if (!status) - { - PyErr_SetString(PyExc_SystemError, "fail to load all PyChrysalide components."); - return NULL; - } - - if (_standalone) - { - init_all_plugins(false); - - lock_plugin_list_for_reading(); - - self = get_plugin_by_name("PyChrysalide", NULL); - assert(self != NULL); - - self_flags = g_plugin_module_get_flags(self); - self_flags &= ~(PSF_FAILURE | PSF_LOADED); - self_flags |= (status ? PSF_LOADED : PSF_FAILURE); - - g_plugin_module_override_flags(self, self_flags); - - unlock_plugin_list_for_reading(); - - load_remaning_plugins(); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : plugin = instance représentant le greffon Python d'origine. * -* * -* Description : Charge autant de greffons composés en Python que possible. * -* * -* Retour : true. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool load_python_plugins(GPluginModule *plugin) -{ - char *paths; /* Emplacements de greffons */ - char *save; /* Sauvegarde pour ré-entrance */ - char *path; /* Chemin à fouiller */ - DIR *dir; /* Répertoire à parcourir */ - struct dirent *entry; /* Elément trouvé */ - char *modname; /* Nom du module pour Python */ - char *filename; /* Chemin d'accès reconstruit */ - GPluginModule *pyplugin; /* Lien vers un grffon Python */ - - paths = get_env_var("PYTHONPATH"); - - save = NULL; /* gcc... */ - - for (path = strtok_r(paths, ":", &save); - path != NULL; - path = strtok_r(NULL, ":", &save)) - { - dir = opendir(path); - if (dir == NULL) - { - perror("opendir"); - continue; - } - - g_plugin_module_log_variadic_message(plugin, LMT_INFO, - _("Looking for Python plugins in '%s'..."), - path); - - while (1) - { - errno = 0; - - entry = readdir(dir); - - if (entry == NULL) - { - if (errno != 0) - perror("readdir"); - - break; - - } - - if (entry->d_type != DT_DIR) continue; - if (entry->d_name[0] == '.') continue; - - modname = strdup(entry->d_name); - modname = stradd(modname, "."); - modname = stradd(modname, "__init__"); - - filename = strdup(path); - filename = stradd(filename, G_DIR_SEPARATOR_S); - filename = stradd(filename, entry->d_name); - - pyplugin = g_python_plugin_new(modname, filename); - - if (pyplugin == NULL) - g_plugin_module_log_variadic_message(plugin, LMT_ERROR, - _("No suitable Python plugin found in '%s'"), - filename); - else - { - g_plugin_module_log_variadic_message(plugin, LMT_PROCESS, - _("Loaded the Python plugin found in the '<b>%s</b>' directory"), - filename); - _register_plugin(pyplugin); - } - - free(filename); - free(modname); - - } - - closedir(dir); - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : plugin = greffon à manipuler. * -* * -* Description : Prend acte du chargement du greffon. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) -{ - bool result; /* Bilan à retourner */ - DIR *dir; /* Répertoire à parcourir */ - int ret; /* Bilan de préparatifs */ - - /* Définition des zones d'influence */ - - dir = opendir(PLUGINS_DIR G_DIR_SEPARATOR_S "python"); - - if (dir != NULL) - { - closedir(dir); - add_to_env_var("PYTHONPATH", PLUGINS_DIR G_DIR_SEPARATOR_S "python", ":"); - } - else - add_to_env_var("PYTHONPATH", PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "plugins" \ - G_DIR_SEPARATOR_S "python", ":"); - - g_plugin_module_log_variadic_message(plugin, LMT_INFO, - _("PYTHONPATH environment variable set to '%s'"), - getenv("PYTHONPATH")); - - /* Chargement du module pour Python */ - - _standalone = false; - - ret = PyImport_AppendInittab("pychrysalide", &PyInit_pychrysalide); - - if (ret == -1) - { - g_plugin_module_log_variadic_message(plugin, LMT_ERROR, - _("Can not extend the existing table of Python built-in modules.")); - result = false; - goto cpi_done; - } - - Py_Initialize(); - - PySys_SetArgv(0, (wchar_t *[]) { NULL }); - - _chrysalide_module = PyImport_ImportModule("pychrysalide"); - - result = load_python_plugins(plugin); - - cpi_done: - - return result; - -} - - - -/****************************************************************************** -* * -* Paramètres : plugin = greffon à manipuler. * -* * -* Description : Prend acte du déchargement du greffon. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin) -{ - Py_XDECREF(_chrysalide_module); - -} |