diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-12-27 20:44:31 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-12-27 20:44:31 (GMT) |
commit | 4b1367d2fee7be0789744e1db35d6f9200b29163 (patch) | |
tree | 3b22581bf6a6d2da6d73a7fef30540282808ecb7 /plugins | |
parent | f6490769c12dbb3b7766c7e6861284b8fee9f9e6 (diff) |
Updated the API in order to allow Python plugins to rely on native plugins.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/pychrysalide/plugin.c | 180 | ||||
-rw-r--r-- | plugins/pychrysalide/pychrysa.c | 42 | ||||
-rw-r--r-- | plugins/pychrysalide/pychrysa.h | 3 |
3 files changed, 205 insertions, 20 deletions
diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c index 44f518e..f232548 100644 --- a/plugins/pychrysalide/plugin.c +++ b/plugins/pychrysalide/plugin.c @@ -87,6 +87,15 @@ static bool g_python_plugin_do_exit(GPythonPlugin *); /* Procède à une opération liée à un contenu binaire. */ static void g_python_plugin_handle_binary_content(const GPythonPlugin *, PluginAction, GBinContent *, wgroup_id_t, GtkStatusStack *); +/* Procède à une opération liée à l'analyse d'un format. */ +static bool g_python_plugin_handle_binary_format_analysis(const GPythonPlugin *, PluginAction, GBinFormat *, wgroup_id_t, GtkStatusStack *); + +/* Procède à un préchargement de format de fichier. */ +static bool g_python_plugin_preload_binary_format(const GPythonPlugin *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *); + +/* Procède au rattachement d'éventuelles infos de débogage. */ +static void g_python_plugin_attach_debug_format(const GPythonPlugin *, PluginAction, GExeFormat *); + /* Exécute une action pendant un désassemblage de binaire. */ static void g_python_plugin_process_disass(const GPythonPlugin *, PluginAction, GLoadedBinary *, GtkStatusStack *, GProcContext *); @@ -327,14 +336,14 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) /* Localisation des différents points d'entrée déclarés */ -#define register_python_binding(inst, sym, binding) \ +#define register_python_binding(inst, pysym, sym, binding) \ ({ \ bool __result; \ - if (!has_python_method(inst, #sym)) \ + if (!has_python_method(inst, #pysym)) \ { \ log_variadic_message(LMT_ERROR, \ _("No '%s' entry in plugin candidate '%s'"), \ - #sym, G_PLUGIN_MODULE(result)->filename); \ + #pysym, G_PLUGIN_MODULE(result)->filename); \ __result = false; \ } \ else \ @@ -361,12 +370,14 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) break; case PGA_PLUGIN_INIT: - if (!register_python_binding(instance, init, (pg_management_fc)g_python_plugin_do_init)) + if (!register_python_binding(instance, init, init, + (pg_management_fc)g_python_plugin_do_init)) goto gppn_bad_plugin; break; case PGA_PLUGIN_EXIT: - if (!register_python_binding(instance, exit, (pg_management_fc)g_python_plugin_do_exit)) + if (!register_python_binding(instance, exit, exit, + (pg_management_fc)g_python_plugin_do_exit)) goto gppn_bad_plugin; break; @@ -389,7 +400,7 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) { case PGA_CONTENT_EXPLORER: case PGA_CONTENT_RESOLVER: - if (!register_python_binding(instance, handle_content, \ + if (!register_python_binding(instance, handle_content, handle_content, (pg_handle_content_fc)g_python_plugin_handle_binary_content)) goto gppn_bad_plugin; break; @@ -408,6 +419,27 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) switch (action) { + case PGA_FORMAT_ANALYSIS_STARTED: + case PGA_FORMAT_ANALYSIS_ENDED: + case PGA_FORMAT_POST_ANALYSIS_STARTED: + case PGA_FORMAT_POST_ANALYSIS_ENDED: + if (!register_python_binding(instance, handle_format_analysis, handle_fmt_analysis, + (pg_handle_format_analysis_fc)g_python_plugin_handle_binary_format_analysis)) + goto gppn_bad_plugin; + break; + + case PGA_FORMAT_PRELOAD: + if (!register_python_binding(instance, preload_format, preload_format, + (pg_preload_format_fc)g_python_plugin_preload_binary_format)) + goto gppn_bad_plugin; + break; + + case PGA_FORMAT_ATTACH_DEBUG: + if (!register_python_binding(instance, attach_debug_format, attach_debug, + (pg_attach_debug)g_python_plugin_attach_debug_format)) + goto gppn_bad_plugin; + break; + default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), @@ -419,7 +451,7 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) break; case DPS_DISASSEMBLY: - if (!register_python_binding(instance, process_disass, + if (!register_python_binding(instance, process_disassembly, process_disass, (pg_process_disassembly_fc)g_python_plugin_process_disass)) goto gppn_bad_plugin; break; @@ -668,9 +700,9 @@ static bool g_python_plugin_do_exit(GPythonPlugin *plugin) static void g_python_plugin_handle_binary_content(const GPythonPlugin *plugin, PluginAction action, GBinContent *content, wgroup_id_t wid, GtkStatusStack *status) { + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ PyObject *args; /* Arguments pour l'appel */ PyObject *value; /* Valeurs obtenues */ - PyGILState_STATE gstate; /* Sauvegarde d'environnement */ gstate = PyGILState_Ensure(); @@ -693,6 +725,129 @@ static void g_python_plugin_handle_binary_content(const GPythonPlugin *plugin, P /****************************************************************************** * * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* format = format de binaire à manipuler pendant l'opération. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Procède à une opération liée à l'analyse d'un format. * +* * +* Retour : Bilan de l'exécution du traitement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_python_plugin_handle_binary_format_analysis(const GPythonPlugin *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Valeurs obtenues */ + + gstate = PyGILState_Ensure(); + + args = PyTuple_New(4); + + PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action)); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(format))); + PyTuple_SetItem(args, 2, PyLong_FromUnsignedLong(gid)); + PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(status))); + + value = run_python_method(plugin->instance, "handle_format_analysis", args); + + Py_XDECREF(value); + Py_DECREF(args); + + PyGILState_Release(gstate); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* format = format de binaire à manipuler pendant l'opération. * +* info = informations à constituer en avance de phase. * +* status = barre de statut à tenir informée. * +* * +* Description : Procède à un préchargement de format de fichier. * +* * +* Retour : Bilan de l'exécution du traitement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_python_plugin_preload_binary_format(const GPythonPlugin *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status) +{ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Valeurs obtenues */ + + gstate = PyGILState_Ensure(); + + args = PyTuple_New(4); + + PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action)); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(format))); + PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(info))); + PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(status))); + + value = run_python_method(plugin->instance, "preload_format", args); + + Py_XDECREF(value); + Py_DECREF(args); + + PyGILState_Release(gstate); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* format = format de binaire à manipuler pendant l'opération. * +* * +* Description : Procède au rattachement d'éventuelles infos de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_python_plugin_attach_debug_format(const GPythonPlugin *plugin, PluginAction action, GExeFormat *format) +{ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Valeurs obtenues */ + + gstate = PyGILState_Ensure(); + + args = PyTuple_New(2); + + PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action)); + PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(format))); + + value = run_python_method(plugin->instance, "attach_debug_format", args); + + Py_XDECREF(value); + Py_DECREF(args); + + PyGILState_Release(gstate); + +} + + +/****************************************************************************** +* * * Paramètres : plugin = greffon à manipuler. * * action = type d'action attendue. * * binary = binaire dont le contenu est en cours de traitement.* @@ -709,9 +864,12 @@ static void g_python_plugin_handle_binary_content(const GPythonPlugin *plugin, P static void g_python_plugin_process_disass(const GPythonPlugin *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context) { + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ PyObject *args; /* Arguments pour l'appel */ PyObject *value; /* Valeurs obtenues */ + gstate = PyGILState_Ensure(); + args = PyTuple_New(4); PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action)); @@ -719,11 +877,13 @@ static void g_python_plugin_process_disass(const GPythonPlugin *plugin, PluginAc PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(status))); PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(context))); - value = run_python_method(plugin->instance, "process_binary_disassembly", args); + value = run_python_method(plugin->instance, "process_disassembly", args); Py_XDECREF(value); Py_DECREF(args); + PyGILState_Release(gstate); + } @@ -756,6 +916,8 @@ static bool py_plugin_module_define_constants(PyTypeObject *obj_type) result &= PyDict_AddULongMacro(obj_type, PGA_PLUGIN_INIT); result &= PyDict_AddULongMacro(obj_type, PGA_PLUGIN_EXIT); + result &= PyDict_AddULongMacro(obj_type, PGA_NATIVE_LOADED); + result &= PyDict_AddULongMacro(obj_type, PGA_CONTENT_EXPLORER); result &= PyDict_AddULongMacro(obj_type, PGA_CONTENT_RESOLVER); result &= PyDict_AddULongMacro(obj_type, PGA_CONTENT_ANALYZED); diff --git a/plugins/pychrysalide/pychrysa.c b/plugins/pychrysalide/pychrysa.c index 7772592..ff36dab 100644 --- a/plugins/pychrysalide/pychrysa.c +++ b/plugins/pychrysalide/pychrysa.c @@ -64,7 +64,7 @@ DEFINE_CHRYSALIDE_CONTAINER_PLUGIN("PyChrysalide", "Provides bindings to Python", "0.1.0", - EMPTY_PG_LIST(.required), AL(PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT)); + EMPTY_PG_LIST(.required), AL(PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT, PGA_NATIVE_LOADED)); /* Note la nature du chargement */ @@ -93,7 +93,7 @@ static bool is_current_abi_suitable(void); 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 *); +static void load_python_plugins(GPluginModule *); @@ -452,13 +452,13 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) * * * Description : Charge autant de greffons composés en Python que possible. * * * -* Retour : true. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool load_python_plugins(GPluginModule *plugin) +static void load_python_plugins(GPluginModule *plugin) { char *paths; /* Emplacements de greffons */ char *save; /* Sauvegarde pour ré-entrance */ @@ -545,8 +545,6 @@ static bool load_python_plugins(GPluginModule *plugin) } - return true; - } @@ -618,11 +616,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) * En mode autonome, le shell Python remonte bien l'erreur par contre. */ - if (_chrysalide_module == NULL) - result = false; - - else - result = load_python_plugins(plugin); + result = (_chrysalide_module != NULL); _main_tstate = PyThreadState_Get(); @@ -656,6 +650,32 @@ G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin) /****************************************************************************** * * +* Paramètres : plugin = greffon à manipuler. * +* action = type d'action attendue. * +* * +* Description : Accompagne la fin du chargement des modules natifs. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +G_MODULE_EXPORT void chrysalide_plugin_on_native_loaded(GPluginModule *plugin, PluginAction action) +{ + if (!_standalone) + PyEval_AcquireLock(); + + load_python_plugins(plugin); + + if (!_standalone) + PyEval_ReleaseLock(); + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit les informations du thread principal. * diff --git a/plugins/pychrysalide/pychrysa.h b/plugins/pychrysalide/pychrysa.h index da9913b..0f844e6 100644 --- a/plugins/pychrysalide/pychrysa.h +++ b/plugins/pychrysalide/pychrysa.h @@ -48,6 +48,9 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *); /* Prend acte du déchargement du greffon. */ G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *); +/* Accompagne la fin du chargement des modules natifs. */ +G_MODULE_EXPORT void chrysalide_plugin_on_native_loaded(GPluginModule *, PluginAction); + /* Fournit les informations du thread principal. */ PyThreadState *get_pychrysalide_main_tstate(void); |