summaryrefslogtreecommitdiff
path: root/src/plugins/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/plugin.c')
-rw-r--r--src/plugins/plugin.c396
1 files changed, 328 insertions, 68 deletions
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index a9bd9da..ff3db31 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -35,6 +35,7 @@
#include <string.h>
+#include "dt.h"
#include "pglist.h"
#include "plugin-int.h"
@@ -52,6 +53,10 @@ static void g_plugin_module_dispose(GPluginModule *);
/* Procède à la libération totale de la mémoire. */
static void g_plugin_module_finalize(GPluginModule *);
+/* Initialise la classe des greffons d'extension. */
+static void g_plugin_module_init_gclass(GPluginModuleClass *, GModule *);
+
+
/* Indique le type défini pour un greffon. */
G_DEFINE_TYPE(GPluginModule, g_plugin_module, G_TYPE_OBJECT);
@@ -117,6 +122,7 @@ static void g_plugin_module_dispose(GPluginModule *plugin)
const plugin_interface *pg_iface; /* Définition du greffon */
size_t i; /* Boucle de parcours */
GPluginModule *dependency; /* Module nécessaire */
+ GPluginModuleClass *class; /* Classe de l'instance active */
pg_iface = g_plugin_module_get_interface(plugin);
@@ -145,11 +151,16 @@ static void g_plugin_module_dispose(GPluginModule *plugin)
}
- if (plugin->exit != NULL)
- plugin->exit(plugin);
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ if (class->exit != NULL)
+ class->exit(plugin);
if (plugin->module != NULL)
+ {
g_module_close(plugin->module);
+ plugin->module = NULL;
+ }
G_OBJECT_CLASS(g_plugin_module_parent_class)->dispose(G_OBJECT(plugin));
@@ -195,25 +206,26 @@ static void g_plugin_module_finalize(GPluginModule *plugin)
GPluginModule *g_plugin_module_new(const gchar *filename)
{
GPluginModule *result; /* Structure à retourner */
+ GModule *module; /* Abstration de manipulation */
+ const plugin_interface *interface; /* Déclaration d'interfaçage */
plugin_abi_version_t current; /* Version de l'ABI actuelle */
+ bool valid; /* Statut de validité */
size_t i; /* Boucle de parcours */
uint32_t action; /* Identifiant d'une action */
uint32_t category; /* Catégorie principale */
uint32_t sub; /* Sous-catégorie visée */
+ GType gtype; /* Nouveau type de greffon */
- result = g_object_new(G_TYPE_PLUGIN_MODULE, NULL);
-
- result->filename = strdup(filename);
-
- result->module = g_module_open(filename, G_MODULE_BIND_LAZY);
- if (result->module == NULL)
+ module = g_module_open(filename, G_MODULE_BIND_LAZY);
+ if (module == NULL)
{
log_variadic_message(LMT_ERROR,
_("Error while loading the plugin candidate '%s' : %s"),
filename, g_module_error());
- goto bad_plugin;
+ goto bad_module;
}
+
#define load_plugin_symbol(mod, sym, dest) \
({ \
bool __result; \
@@ -221,7 +233,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
{ \
log_variadic_message(LMT_ERROR, \
_("No '%s' entry in plugin candidate '%s'"), \
- sym, result->filename); \
+ sym, filename); \
__result = false; \
} \
else __result = true; \
@@ -231,12 +243,12 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
/* Récupération de la version d'ABI */
- if (!load_plugin_symbol(result->module, "_chrysalide_plugin", &result->interface))
+ if (!load_plugin_symbol(module, "_chrysalide_plugin", &interface))
goto bad_plugin;
current = CURRENT_ABI_VERSION;
- if (current != result->interface->abi_version)
+ if (current != interface->abi_version)
{
log_variadic_message(LMT_ERROR,
_("ABI mismatch detected! Plugin '%s' rejected"),
@@ -247,9 +259,20 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
/* Localisation des différents points d'entrée déclarés */
- for (i = 0; i < result->interface->actions_count; i++)
+
+#define check_plugin_symbol(mod, sym) \
+ ({ \
+ bool __result; \
+ __result = g_module_symbol(mod, sym, (gpointer []) { 0 }); \
+ __result; \
+ })
+
+
+ valid = true;
+
+ for (i = 0; i < interface->actions_count && valid; i++)
{
- action = result->interface->actions[i];
+ action = interface->actions[i];
category = MASK_PLUGIN_CATEGORY(action);
sub = MASK_PLUGIN_SUB_CATEGORY(action);
@@ -267,21 +290,17 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
switch (action)
{
case PGA_PLUGIN_INIT:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_init", &result->init))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_init");
break;
case PGA_PLUGIN_EXIT:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_exit", &result->exit))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_exit");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- result->interface->actions[i], filename);
+ interface->actions[i], filename);
break;
}
@@ -293,16 +312,13 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
switch (action)
{
case PGA_NATIVE_LOADED:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_on_native_loaded",
- &result->native_loaded))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_on_native_loaded");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- result->interface->actions[i], filename);
+ interface->actions[i], filename);
break;
}
@@ -327,15 +343,13 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
switch (action)
{
case PGA_GUI_THEME:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_include_theme", &result->include_theme))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_include_theme");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- result->interface->actions[i], filename);
+ interface->actions[i], filename);
break;
}
@@ -361,23 +375,17 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
{
case PGA_CONTENT_EXPLORER:
case PGA_CONTENT_RESOLVER:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_handle_binary_content",
- &result->handle_content))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_handle_binary_content");
break;
case PGA_CONTENT_ANALYZED:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_handle_loaded_content",
- &result->handle_loaded))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_handle_loaded_content");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- result->interface->actions[i], filename);
+ interface->actions[i], filename);
break;
}
@@ -392,28 +400,21 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
case PGA_FORMAT_ANALYSIS_ENDED:
case PGA_FORMAT_POST_ANALYSIS_STARTED:
case PGA_FORMAT_POST_ANALYSIS_ENDED:
- if (!load_plugin_symbol(result->module,
- "handle_binary_format_analysis",
- &result->handle_fmt_analysis))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "handle_binary_format_analysis");
break;
case PGA_FORMAT_PRELOAD:
- if (!load_plugin_symbol(result->module,
- "preload_binary_format", &result->preload_format))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "preload_binary_format");
break;
case PGA_FORMAT_ATTACH_DEBUG:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_attach_debug", &result->attach_debug))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_attach_debug");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- result->interface->actions[i], filename);
+ interface->actions[i], filename);
break;
}
@@ -421,15 +422,11 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
break;
case DPS_DISASSEMBLY:
- if (!load_plugin_symbol(result->module,
- "process_binary_disassembly", &result->process_disass))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "process_binary_disassembly");
break;
case DPS_DETECTION:
- if (!load_plugin_symbol(result->module,
- "chrysalide_plugin_detect_external_tools", &result->detect))
- goto bad_plugin;
+ valid = check_plugin_symbol(module, "chrysalide_plugin_detect_external_tools");
break;
default:
@@ -450,11 +447,29 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
}
+ if (!valid)
+ goto bad_plugin;
+
+ gtype = built_dynamic_type(G_TYPE_PLUGIN_MODULE, interface->gtp_name,
+ (GClassInitFunc)g_plugin_module_init_gclass, module);
+
+ if (gtype == G_TYPE_INVALID)
+ goto bad_plugin;
+
+ result = g_object_new(gtype, NULL);
+
+ result->filename = strdup(filename);
+ result->module = module;
+
+ result->interface = interface;
+
return result;
bad_plugin:
- g_object_unref(G_OBJECT(result));
+ g_module_close(module);
+
+ bad_module:
return NULL;
@@ -463,6 +478,212 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
/******************************************************************************
* *
+* Paramètres : class = classe à initialiser. *
+* module = module représentant le greffon chargé en mémoire. *
+* *
+* Description : Initialise la classe des greffons d'extension. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_plugin_module_init_gclass(GPluginModuleClass *class, GModule *module)
+{
+ const plugin_interface *interface; /* Déclaration d'interfaçage */
+ size_t i; /* Boucle de parcours */
+ uint32_t action; /* Identifiant d'une action */
+ uint32_t category; /* Catégorie principale */
+ uint32_t sub; /* Sous-catégorie visée */
+
+
+#undef load_plugin_symbol
+
+#define load_plugin_symbol(mod, sym, dest) \
+ ({ \
+ bool __result; \
+ __result = g_module_symbol(mod, sym, (gpointer *)dest); \
+ assert(__result); \
+ __result; \
+ })
+
+
+ load_plugin_symbol(module, "_chrysalide_plugin", &interface);
+
+ for (i = 0; i < interface->actions_count; i++)
+ {
+ action = interface->actions[i];
+ category = MASK_PLUGIN_CATEGORY(action);
+ sub = MASK_PLUGIN_SUB_CATEGORY(action);
+
+ switch (category)
+ {
+ case DPC_BASIC:
+
+ switch (sub)
+ {
+ case DPS_NONE:
+ break;
+
+ case DPS_PG_MANAGEMENT:
+
+ switch (action)
+ {
+ case PGA_PLUGIN_INIT:
+ load_plugin_symbol(module, "chrysalide_plugin_init", &class->init);
+ break;
+
+ case PGA_PLUGIN_EXIT:
+ load_plugin_symbol(module, "chrysalide_plugin_exit", &class->exit);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ case DPS_CORE_MANAGEMENT:
+
+ switch (action)
+ {
+ case PGA_NATIVE_LOADED:
+ load_plugin_symbol(module, "chrysalide_plugin_on_native_loaded",
+ &class->native_loaded);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ case DPC_GUI:
+
+ switch (sub)
+ {
+ case DPS_SETUP:
+
+ switch (action)
+ {
+ case PGA_GUI_THEME:
+ load_plugin_symbol(module, "chrysalide_plugin_include_theme",
+ &class->include_theme);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ case DPC_BINARY_PROCESSING:
+
+ switch (sub)
+ {
+ case DPS_CONTENT:
+
+ switch (action)
+ {
+ case PGA_CONTENT_EXPLORER:
+ case PGA_CONTENT_RESOLVER:
+ load_plugin_symbol(module, "chrysalide_plugin_handle_binary_content",
+ &class->handle_content);
+ break;
+
+ case PGA_CONTENT_ANALYZED:
+ load_plugin_symbol(module, "chrysalide_plugin_handle_loaded_content",
+ &class->handle_loaded);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ case DPS_FORMAT:
+
+ switch (action)
+ {
+ case PGA_FORMAT_ANALYSIS_STARTED:
+ case PGA_FORMAT_ANALYSIS_ENDED:
+ case PGA_FORMAT_POST_ANALYSIS_STARTED:
+ case PGA_FORMAT_POST_ANALYSIS_ENDED:
+ load_plugin_symbol(module, "handle_binary_format_analysis",
+ &class->handle_fmt_analysis);
+ break;
+
+ case PGA_FORMAT_PRELOAD:
+ load_plugin_symbol(module, "preload_binary_format", &class->preload_format);
+ break;
+
+ case PGA_FORMAT_ATTACH_DEBUG:
+ load_plugin_symbol(module, "chrysalide_plugin_attach_debug", &class->attach_debug);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ case DPS_DISASSEMBLY:
+ load_plugin_symbol(module, "process_binary_disassembly", &class->process_disass);
+ break;
+
+ case DPS_DETECTION:
+ load_plugin_symbol(module, "chrysalide_plugin_detect_external_tools", &class->detect);
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : plugin = greffon à consulter. *
* *
* Description : Indique le fichier contenant le greffon manipulé. *
@@ -654,6 +875,7 @@ bool g_plugin_module_load(GPluginModule *plugin, GPluginModule **list, size_t co
const plugin_interface *pg_iface; /* Définition du greffon */
size_t i; /* Boucle de parcours */
GPluginModule *dependency; /* Module nécessaire */
+ GPluginModuleClass *class; /* Classe de l'instance active */
char *dir; /* Répertoire modifiable */
/* Si un essai précédent a déjà échoué ou réussi... */
@@ -689,9 +911,11 @@ bool g_plugin_module_load(GPluginModule *plugin, GPluginModule **list, size_t co
if (result)
{
- if (plugin->init != NULL)
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ if (class->init != NULL)
{
- result = plugin->init(plugin);
+ result = class->init(plugin);
if (!result)
{
@@ -810,7 +1034,11 @@ void g_plugin_module_log_variadic_message(const GPluginModule *plugin, LogMessag
void g_plugin_module_notify_native_loaded(GPluginModule *plugin, PluginAction action, void *unused)
{
- plugin->native_loaded(plugin, action);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->native_loaded(plugin, action);
}
@@ -832,7 +1060,11 @@ void g_plugin_module_notify_native_loaded(GPluginModule *plugin, PluginAction ac
void g_plugin_module_include_theme(const GPluginModule *plugin, PluginAction action, char ***resources, size_t *count)
{
- plugin->include_theme(plugin, action, resources, count);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->include_theme(plugin, action, resources, count);
}
@@ -855,7 +1087,11 @@ void g_plugin_module_include_theme(const GPluginModule *plugin, PluginAction act
void g_plugin_module_handle_binary_content(const GPluginModule *plugin, PluginAction action, GBinContent *content, wgroup_id_t wid, GtkStatusStack *status)
{
- return plugin->handle_content(plugin, action, content, wid, status);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->handle_content(plugin, action, content, wid, status);
}
@@ -878,7 +1114,11 @@ void g_plugin_module_handle_binary_content(const GPluginModule *plugin, PluginAc
void g_plugin_module_handle_loaded_content(const GPluginModule *plugin, PluginAction action, GLoadedContent *content, wgroup_id_t wid, GtkStatusStack *status)
{
- return plugin->handle_loaded(plugin, action, content, wid, status);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ return class->handle_loaded(plugin, action, content, wid, status);
}
@@ -901,7 +1141,11 @@ void g_plugin_module_handle_loaded_content(const GPluginModule *plugin, PluginAc
bool g_plugin_module_handle_binary_format_analysis(const GPluginModule *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status)
{
- return plugin->handle_fmt_analysis(plugin, action, format, gid, status);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ return class->handle_fmt_analysis(plugin, action, format, gid, status);
}
@@ -924,7 +1168,11 @@ bool g_plugin_module_handle_binary_format_analysis(const GPluginModule *plugin,
bool g_plugin_module_preload_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
- return plugin->preload_format(plugin, action, format, info, status);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ return class->preload_format(plugin, action, format, info, status);
}
@@ -945,7 +1193,11 @@ bool g_plugin_module_preload_binary_format(const GPluginModule *plugin, PluginAc
void g_plugin_module_attach_debug_format(const GPluginModule *plugin, PluginAction action, GExeFormat *format)
{
- plugin->attach_debug(plugin, action, format);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->attach_debug(plugin, action, format);
}
@@ -968,7 +1220,11 @@ void g_plugin_module_attach_debug_format(const GPluginModule *plugin, PluginActi
void g_plugin_module_process_disassembly_event(const GPluginModule *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context)
{
- plugin->process_disass(plugin, action, binary, status, context);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->process_disass(plugin, action, binary, status, context);
}
@@ -992,6 +1248,10 @@ void g_plugin_module_process_disassembly_event(const GPluginModule *plugin, Plug
void g_plugin_module_detect_external_tools(const GPluginModule *plugin, PluginAction action, const GLoadedContent *content, bool version, char ***names, size_t *count)
{
- plugin->detect(plugin, action, content, version, names, count);
+ GPluginModuleClass *class; /* Classe de l'instance active */
+
+ class = G_PLUGIN_MODULE_GET_CLASS(plugin);
+
+ class->detect(plugin, action, content, version, names, count);
}