summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-12-27 20:44:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-12-27 20:44:31 (GMT)
commit4b1367d2fee7be0789744e1db35d6f9200b29163 (patch)
tree3b22581bf6a6d2da6d73a7fef30540282808ecb7 /plugins
parentf6490769c12dbb3b7766c7e6861284b8fee9f9e6 (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.c180
-rw-r--r--plugins/pychrysalide/pychrysa.c42
-rw-r--r--plugins/pychrysalide/pychrysa.h3
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);