summaryrefslogtreecommitdiff
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
parentf6490769c12dbb3b7766c7e6861284b8fee9f9e6 (diff)
Updated the API in order to allow Python plugins to rely on native plugins.
-rw-r--r--plugins/pychrysalide/plugin.c180
-rw-r--r--plugins/pychrysalide/pychrysa.c42
-rw-r--r--plugins/pychrysalide/pychrysa.h3
-rw-r--r--src/plugins/pglist.c2
-rw-r--r--src/plugins/pglist.h8
-rw-r--r--src/plugins/plugin-def.h12
-rw-r--r--src/plugins/plugin-int.h5
-rw-r--r--src/plugins/plugin.c42
-rw-r--r--src/plugins/plugin.h3
9 files changed, 272 insertions, 25 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);
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 57f7538..b7c8d1d 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -459,6 +459,8 @@ void load_remaning_plugins(void)
g_rw_lock_reader_unlock(&_pg_lock);
+ notify_native_loaded;
+
}
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index 0c8f6af..1306571 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -85,6 +85,11 @@ GPluginModule **get_all_plugins_for_action(PluginAction, size_t *);
while (0)
+/* DPS_PG_MANAGEMENT */
+
+#define notify_native_loaded \
+ process_all_plugins_for(PGA_NATIVE_LOADED, g_plugin_module_notify_native_loaded, NULL)
+
/* DPS_SETUP */
#define include_plugin_theme(r, c) \
@@ -103,9 +108,6 @@ GPluginModule **get_all_plugins_for_action(PluginAction, size_t *);
#define handle_binary_format_analysis(a, f, g, s) \
process_all_plugins_for(a, g_plugin_module_handle_binary_format_analysis, f, g, s)
-#define handle_binary_format(a, f, s) \
- process_all_plugins_for(a, g_plugin_module_handle_binary_format, f, s)
-
#define preload_binary_format(a, f, i, s) \
process_all_plugins_for(a, g_plugin_module_preload_binary_format, f, i, s)
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index 96b04b1..4c59606 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -76,6 +76,7 @@ typedef uint32_t plugin_action_t;
#define DPS_NONE DEFINE_PLUGIN_SUB_CATEGORY(0)
#define DPS_PG_MANAGEMENT DEFINE_PLUGIN_SUB_CATEGORY(1)
+#define DPS_CORE_MANAGEMENT DEFINE_PLUGIN_SUB_CATEGORY(2)
/* DPC_GUI */
@@ -111,10 +112,17 @@ typedef enum _PluginAction
*/
/* Chargement */
- PGA_PLUGIN_INIT = DPC_BASIC | DPS_PG_MANAGEMENT | DEFINE_PLUGIN_ACTION(0),
+ PGA_PLUGIN_INIT = DPC_BASIC | DPS_PG_MANAGEMENT | DEFINE_PLUGIN_ACTION(0),
/* Déchargement */
- PGA_PLUGIN_EXIT = DPC_BASIC | DPS_PG_MANAGEMENT | DEFINE_PLUGIN_ACTION(1),
+ PGA_PLUGIN_EXIT = DPC_BASIC | DPS_PG_MANAGEMENT | DEFINE_PLUGIN_ACTION(1),
+
+ /**
+ * DPC_BASIC | DPS_CORE_MANAGEMENT
+ */
+
+ /* Fin du chargement des greffons natifs */
+ PGA_NATIVE_LOADED = DPC_BASIC | DPS_CORE_MANAGEMENT | DEFINE_PLUGIN_ACTION(0),
/**
* DPC_GUI | DPS_SETUP
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 8df3527..2d98217 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -41,6 +41,9 @@
/* Prend acte du [dé]chargement du greffon. */
typedef bool (* pg_management_fc) (GPluginModule *);
+/* Accompagne la fin du chargement des modules natifs. */
+typedef void (* pg_native_loaded_fc) (GPluginModule *, PluginAction);
+
/* Procède à une opération liée à un contenu binaire. */
typedef void (* pg_handle_content_fc) (const GPluginModule *, PluginAction, GBinContent *, wgroup_id_t, GtkStatusStack *);
@@ -83,6 +86,8 @@ struct _GPluginModule
pg_management_fc init; /* Procédure d'initialisation */
pg_management_fc exit; /* Procédure d'extinction */
+ pg_native_loaded_fc native_loaded; /* Fin des chargements natifs */
+
pg_include_theme_fc include_theme; /* Extension d'un thème */
pg_handle_content_fc handle_content; /* Explorations ou résolutions */
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index 1608032..a9bd9da 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -288,6 +288,27 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
break;
+ case DPS_CORE_MANAGEMENT:
+
+ switch (action)
+ {
+ case PGA_NATIVE_LOADED:
+ if (!load_plugin_symbol(result->module,
+ "chrysalide_plugin_on_native_loaded",
+ &result->native_loaded))
+ goto bad_plugin;
+ break;
+
+ default:
+ log_variadic_message(LMT_WARNING,
+ _("Unknown action '0x%02x' in plugin '%s'..."),
+ result->interface->actions[i], filename);
+ break;
+
+ }
+
+ break;
+
default:
log_variadic_message(LMT_WARNING,
_("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename);
@@ -775,6 +796,27 @@ void g_plugin_module_log_variadic_message(const GPluginModule *plugin, LogMessag
/******************************************************************************
* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* unused = variable non utilisé pour l'usage de __VA_ARGS__. *
+* *
+* Description : Accompagne la fin du chargement des modules natifs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_plugin_module_notify_native_loaded(GPluginModule *plugin, PluginAction action, void *unused)
+{
+ plugin->native_loaded(plugin, action);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
* resources = liste de ressources à constituer. [OUT] *
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index 86dba25..4b3b306 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -91,6 +91,9 @@ bool g_plugin_module_resolve_dependencies(GPluginModule *, GPluginModule **, siz
/* Termine le chargement du greffon préparé. */
bool g_plugin_module_load(GPluginModule *, GPluginModule **, size_t);
+/* Accompagne la fin du chargement des modules natifs. */
+void g_plugin_module_notify_native_loaded(GPluginModule *, PluginAction, void *);
+
/* Complète une liste de resources pour thème. */
void g_plugin_module_include_theme(const GPluginModule *, PluginAction, char ***, size_t *);