summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-03 23:36:47 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-03 23:36:47 (GMT)
commit55ccf25e0c6666436f0ecd222e60208ebf6ab30e (patch)
tree21c1ecc9e6d6ae50d0cfb0ffa4eaf61bf78a45a2 /plugins
parent28bfc34862513acb8fe9fcd02afca493c2411c02 (diff)
Defined a dynamic type for each plugin.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/arm/core.c2
-rw-r--r--plugins/dalvik/core.c2
-rw-r--r--plugins/devdbg/speed.c2
-rw-r--r--plugins/dex/core.c2
-rw-r--r--plugins/dexbnf/core.c2
-rw-r--r--plugins/dwarf/core.c2
-rw-r--r--plugins/elf/core.c2
-rw-r--r--plugins/itanium/core.c2
-rw-r--r--plugins/javadesc/core.c2
-rw-r--r--plugins/libcsem/semantic.c2
-rw-r--r--plugins/lnxsyscalls/core.c2
-rw-r--r--plugins/mobicore/core.c2
-rw-r--r--plugins/pychrysalide/Makefile.am1
-rw-r--r--plugins/pychrysalide/arch/processor.c39
-rw-r--r--plugins/pychrysalide/dt.c469
-rw-r--r--plugins/pychrysalide/dt.h47
-rw-r--r--plugins/pychrysalide/gui/editem.c3
-rw-r--r--plugins/pychrysalide/gui/panels/panel.c39
-rw-r--r--plugins/pychrysalide/helpers.c74
-rw-r--r--plugins/pychrysalide/helpers.h12
-rw-r--r--plugins/pychrysalide/plugin.c929
-rw-r--r--plugins/pychrysalide/pychrysa.c5
-rw-r--r--plugins/readdex/reader.c2
-rw-r--r--plugins/readelf/reader.c2
-rw-r--r--plugins/readmc/reader.c2
-rw-r--r--plugins/ropgadgets/plugin.c2
26 files changed, 668 insertions, 982 deletions
diff --git a/plugins/arm/core.c b/plugins/arm/core.c
index d2dd805..07b9b24 100644
--- a/plugins/arm/core.c
+++ b/plugins/arm/core.c
@@ -32,7 +32,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("arm", "Add support for the ARM architecture", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GArmPlugin", "arm", "Add support for the ARM architecture", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT));
diff --git a/plugins/dalvik/core.c b/plugins/dalvik/core.c
index 2e936b9..d7e5a04 100644
--- a/plugins/dalvik/core.c
+++ b/plugins/dalvik/core.c
@@ -35,7 +35,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("dalvik", "Add support for the Dalvik architecture", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GDalvikPlugin", "dalvik", "Add support for the Dalvik architecture", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT));
diff --git a/plugins/devdbg/speed.c b/plugins/devdbg/speed.c
index 935fbd9..77c407a 100644
--- a/plugins/devdbg/speed.c
+++ b/plugins/devdbg/speed.c
@@ -38,7 +38,7 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("Speed Measure", "Tracks to time spent for disassembling code", "0.1.0",
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("GSpeedPlugin", "Speed Measure", "Tracks to time spent for disassembling code", "0.1.0",
PGA_FORMAT_ANALYSIS_STARTED,PGA_FORMAT_ANALYSIS_ENDED,
PGA_FORMAT_POST_ANALYSIS_STARTED, PGA_FORMAT_POST_ANALYSIS_ENDED,
PGA_DISASSEMBLY_STARTED, PGA_DISASSEMBLY_ENDED);
diff --git a/plugins/dex/core.c b/plugins/dex/core.c
index 6bdb9d5..3e5b835 100644
--- a/plugins/dex/core.c
+++ b/plugins/dex/core.c
@@ -33,7 +33,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("dex", "Add support for the DEX format", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GDexPlugin", "dex", "Add support for the DEX format", "0.1.0",
RL("PyChrysalide", "dexbnf"), AL(PGA_PLUGIN_INIT, PGA_CONTENT_RESOLVER));
diff --git a/plugins/dexbnf/core.c b/plugins/dexbnf/core.c
index 774e88e..736fa5f 100644
--- a/plugins/dexbnf/core.c
+++ b/plugins/dexbnf/core.c
@@ -33,7 +33,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("dexbnf", "Symbol demangler for Dex", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GDexBnfPlugin", "dexbnf", "Symbol demangler for Dex", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT));
diff --git a/plugins/dwarf/core.c b/plugins/dwarf/core.c
index fa7e0ec..1e2d900 100644
--- a/plugins/dwarf/core.c
+++ b/plugins/dwarf/core.c
@@ -31,7 +31,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("dwarf", "Add support for the DWARF format", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GDwarfPlugin", "dwarf", "Add support for the DWARF format", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT, PGA_FORMAT_ATTACH_DEBUG));
diff --git a/plugins/elf/core.c b/plugins/elf/core.c
index 6b7810e..d3d226e 100644
--- a/plugins/elf/core.c
+++ b/plugins/elf/core.c
@@ -33,7 +33,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("elf", "Add support for the ELF format", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GElfPlugin", "elf", "Add support for the ELF format", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT, PGA_CONTENT_RESOLVER));
diff --git a/plugins/itanium/core.c b/plugins/itanium/core.c
index ecfd7f0..71816f7 100644
--- a/plugins/itanium/core.c
+++ b/plugins/itanium/core.c
@@ -33,7 +33,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("itanium", "Symbol demangler for Itanium", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GItaniumPlugin", "itanium", "Symbol demangler for Itanium", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT));
diff --git a/plugins/javadesc/core.c b/plugins/javadesc/core.c
index e374749..41c4789 100644
--- a/plugins/javadesc/core.c
+++ b/plugins/javadesc/core.c
@@ -33,7 +33,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("javadesc", "Symbol demangler for Java", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GJavaDescPlugin", "javadesc", "Symbol demangler for Java", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT));
diff --git a/plugins/libcsem/semantic.c b/plugins/libcsem/semantic.c
index 0dc330e..de87012 100644
--- a/plugins/libcsem/semantic.c
+++ b/plugins/libcsem/semantic.c
@@ -32,7 +32,7 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("LibC semantics", "Register semantic information relative to the libc", "0.1.0",
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("GCSemPlugin", "LibC semantics", "Register semantic information relative to the libc", "0.1.0",
PGA_DISASSEMBLY_HOOKED_POST);
diff --git a/plugins/lnxsyscalls/core.c b/plugins/lnxsyscalls/core.c
index f28e776..cd9fa0e 100644
--- a/plugins/lnxsyscalls/core.c
+++ b/plugins/lnxsyscalls/core.c
@@ -37,7 +37,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("Linux System Calls", "Describes each Linux system call with its arguments", \
+DEFINE_CHRYSALIDE_PLUGIN("GLnxSyscallsPlugin", "Linux System Calls", "Describes each Linux system call with its arguments", \
"0.1.0", EMPTY_PG_LIST(.required), AL(PGA_PLUGIN_INIT, PGA_DISASSEMBLY_ENDED));
diff --git a/plugins/mobicore/core.c b/plugins/mobicore/core.c
index bc7298f..9de116d 100644
--- a/plugins/mobicore/core.c
+++ b/plugins/mobicore/core.c
@@ -32,7 +32,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("mobicore", "Support MobiCore file format for Trusted Applications", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GMobicorePlugin", "mobicore", "Support MobiCore file format for Trusted Applications", "0.1.0",
EMPTY_PG_LIST(.required), AL(PGA_CONTENT_RESOLVER));
diff --git a/plugins/pychrysalide/Makefile.am b/plugins/pychrysalide/Makefile.am
index 3fe13af..d9194b9 100644
--- a/plugins/pychrysalide/Makefile.am
+++ b/plugins/pychrysalide/Makefile.am
@@ -7,7 +7,6 @@ libdir = $(pluginslibdir)
pychrysalide_la_SOURCES = \
access.h access.c \
constval.h constval.c \
- dt.h dt.c \
helpers.h helpers.c \
plugin.h plugin.c \
pychrysa.h pychrysa.c \
diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c
index 115f980..4feaa8b 100644
--- a/plugins/pychrysalide/arch/processor.c
+++ b/plugins/pychrysalide/arch/processor.c
@@ -31,6 +31,7 @@
#include <i18n.h>
#include <arch/processor-int.h>
+#include <plugins/dt.h>
#include "context.h"
@@ -38,7 +39,6 @@
#include "instruction.h"
#include "vmpa.h"
#include "../access.h"
-#include "../dt.h"
#include "../helpers.h"
#include "../analysis/content.h"
#include "../format/executable.h"
@@ -140,18 +140,16 @@ static bool define_python_arch_processor_constants(PyTypeObject *);
static PyObject *py_arch_processor_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *result; /* Objet à retourner */
- bool abstract; /* Validation du type parent */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
GType gtype; /* Nouveau type de processeur */
- PyObject *sys_mod_dict; /* Dictionnaire des modules */
- PyObject *modname; /* Nom du module du type */
- PyObject *module; /* Module à recompléter */
- PyObject *dict; /* Dictionnaire dudit module */
+ bool status; /* Bilan d'un enregistrement */
/* Validations diverses */
- abstract = (type == get_python_arch_processor_type());
+ base = get_python_arch_processor_type();
- if (abstract)
+ if (type == base)
{
result = NULL;
PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
@@ -160,30 +158,23 @@ static PyObject *py_arch_processor_new(PyTypeObject *type, PyObject *args, PyObj
/* Mise en place d'un type dédié */
- gtype = built_dynamic_type(G_TYPE_ARCH_PROCESSOR, type->tp_name,
- (GClassInitFunc)py_arch_processor_init_gclass);
-
- /* Enregistrement du nouveau GType dans Python */
-
- sys_mod_dict = PyImport_GetModuleDict();
+ first_time = (g_type_from_name(type->tp_name) == 0);
- modname = PyDict_GetItemString(type->tp_dict, "__module__");
-
- module = PyObject_GetItem(sys_mod_dict, modname);
+ gtype = built_dynamic_type(G_TYPE_ARCH_PROCESSOR, type->tp_name,
+ (GClassInitFunc)py_arch_processor_init_gclass, NULL);
- dict = PyModule_GetDict(module);
+ if (first_time)
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+ else
+ status = true;
- if (!_register_class_for_pygobject(dict, gtype, type,
- &PyGObject_Type, get_python_arch_processor_type(), NULL))
+ if (!status)
{
result = NULL;
goto exit;
}
- Py_DECREF(module);
- Py_DECREF(modname);
-
- /* On créé, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
result = PyType_GenericNew(type, args, kwds);
diff --git a/plugins/pychrysalide/dt.c b/plugins/pychrysalide/dt.c
deleted file mode 100644
index 0b46b45..0000000
--- a/plugins/pychrysalide/dt.c
+++ /dev/null
@@ -1,469 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * dt.c - possibilité de créer de nouveaux types de façon dynamique
- *
- * Copyright (C) 2018 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "dt.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-
-
-
-/* ------------------------- MODULE DE GESTION DES NOUVEAUX ------------------------- */
-
-
-#define G_TYPE_DYNAMIC_TYPES g_dynamic_types_get_type()
-#define G_DYNAMIC_TYPES(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DYNAMIC_TYPES, GDynamicTypes))
-#define G_IS_DYNAMIC_TYPES(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DYNAMIC_TYPES))
-#define G_DYNAMIC_TYPES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DYNAMIC_TYPES, GDynamicTypesClass))
-#define G_IS_DYNAMIC_TYPES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DYNAMIC_TYPES))
-#define G_DYNAMIC_TYPES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DYNAMIC_TYPES, GDynamicTypesClass))
-
-
-/* Mémorisation des caractéristiques de type */
-typedef struct _type_dyn_info_t
-{
- GType type; /* Identifiant unique obtenu */
- GClassInitFunc init; /* Définition des méthodes */
-
-} type_dyn_info_t;
-
-/* Description de fichier binaire (instance) */
-typedef struct _GDynamicTypes
-{
- GObject parent; /* A laisser en premier */
-
- type_dyn_info_t **info; /* Liste d'informations utiles */
- size_t count; /* Taille de cette liste */
-
-} GDynamicTypes;
-
-/* Description de fichier binaire (classe) */
-typedef struct _GDynamicTypesClass
-{
- GObjectClass parent; /* A laisser en premier */
-
-} GDynamicTypesClass;
-
-
-/* Indique le type défini pour une gestion de types dynamique. */
-static GType g_dynamic_types_get_type(void);
-
-/* Initialise la classe de gestion de types dynamique. */
-static void g_dynamic_types_class_init(GDynamicTypesClass *);
-
-/* Initialise une gestion de types dynamique. */
-static void g_dynamic_types_init(GDynamicTypes *);
-
-/* Procède à l'initialisation de l'interface de typage nouveau. */
-static void g_dynamic_types_interface_init(GTypePluginClass *);
-
-/* Supprime toutes les références externes. */
-static void g_dynamic_types_dispose(GDynamicTypes *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_dynamic_types_finalize(GDynamicTypes *);
-
-/* Crée un nouveau gestionnaire de nouveaux types. */
-static GDynamicTypes *g_dynamic_types_new(void);
-
-/* Marque une augmentation des utilisations. */
-static void g_dynamic_types_use(GDynamicTypes *);
-
-/* Marque une diminution des utilisations. */
-static void g_dynamic_types_unuse(GDynamicTypes *);
-
-/* Complète la définition d'un type dynamiquement. */
-static void g_dynamic_types_complete_type(GDynamicTypes *, GType, GTypeInfo *, GTypeValueTable *);
-
-/* Retrouve les informations concernant un type dynamique. */
-static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *, GType);
-
-/* Fournit un identifiant GLib pour un nouveau type Python. */
-static GType g_dynamic_types_register_type(GDynamicTypes *, GType, const char *, GClassInitFunc);
-
-
-
-/* ----------------------- ACCOMPAGNEMENTS DES NOUVEAUX TYPES ----------------------- */
-
-
-/* Encadrement des nouveaux types Python dérivés */
-static GDynamicTypes *_python_dtypes = NULL;
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* MODULE DE GESTION DES NOUVEAUX */
-/* ---------------------------------------------------------------------------------- */
-
-/* Indique le type défini pour une gestion de types dynamique. */
-G_DEFINE_TYPE_WITH_CODE(GDynamicTypes, g_dynamic_types, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(G_TYPE_TYPE_PLUGIN, g_dynamic_types_interface_init));
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe de gestion de types dynamique. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_class_init(GDynamicTypesClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_dynamic_types_dispose;
- object->finalize = (GObjectFinalizeFunc)g_dynamic_types_finalize;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : types = instance à initialiser. *
-* *
-* Description : Initialise une gestion de types dynamique. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_init(GDynamicTypes *types)
-{
-
-}
-
-/******************************************************************************
-* *
-* Paramètres : iface = interface GLib à initialiser. *
-* *
-* Description : Procède à l'initialisation de l'interface de typage nouveau. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_interface_init(GTypePluginClass *iface)
-{
- iface->use_plugin = (GTypePluginUse)g_dynamic_types_use;
- iface->unuse_plugin = (GTypePluginUnuse)g_dynamic_types_unuse;
- iface->complete_type_info = (GTypePluginCompleteTypeInfo)g_dynamic_types_complete_type;
-
-}
-
-/******************************************************************************
-* *
-* Paramètres : types = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_dispose(GDynamicTypes *types)
-{
- G_OBJECT_CLASS(g_dynamic_types_parent_class)->dispose(G_OBJECT(types));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : types = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_finalize(GDynamicTypes *types)
-{
- G_OBJECT_CLASS(g_dynamic_types_parent_class)->finalize(G_OBJECT(types));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : - *
-* *
-* Description : Crée un nouveau gestionnaire de nouveaux types. *
-* *
-* Retour : Instance mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static GDynamicTypes *g_dynamic_types_new(void)
-{
- GDynamicTypes *result; /* Adresse à retourner */
-
- result = g_object_new(G_TYPE_DYNAMIC_TYPES, NULL);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : types = gestionnaire de types courant. *
-* *
-* Description : Marque une augmentation des utilisations. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_use(GDynamicTypes *types)
-{
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : types = gestionnaire de types courant. *
-* *
-* Description : Marque une diminution des utilisations. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_unuse(GDynamicTypes *types)
-{
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : types = gestionnaire de types courant. *
-* type = nouveau type GLib à traiter. *
-* info = information concernant ce type à constituer. [OUT] *
-* table = table de valeur à éventuellement initialiser. [OUT] *
-* *
-* Description : Complète la définition d'un type dynamiquement. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dynamic_types_complete_type(GDynamicTypes *types, GType type, GTypeInfo *info, GTypeValueTable *table)
-{
- const type_dyn_info_t *nfo; /* Source d'inspiration */
- GType parent; /* Type parent du type */
- GTypeQuery query; /* Informations complémentaires*/
-
- /* Consultation */
-
- nfo = g_dynamic_types_find(types, type);
- assert(nfo != NULL);
-
- parent = g_type_parent(type);
- g_type_query(parent, &query);
-
- /* Définition */
-
- info->class_size = query.class_size;
- info->class_init = nfo->init;
-
- info->instance_size = query.instance_size;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : parent = type GLib parent. *
-* type = identifiant du type GLib à considérer. *
-* *
-* Description : Retrouve les informations concernant un type dynamique. *
-* *
-* Retour : Structure contenant les informations associées au type. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *types, GType target)
-{
- type_dyn_info_t *result; /* Informations à retourner */
- size_t i; /* Boucle de parcours */
-
- result = NULL;
-
- for (i = 0; i < types->count && result == NULL; i++)
- if (types->info[i]->type == target)
- result = types->info[i];
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : parent = type GLib parent. *
-* name = désignation du nouveau type. *
-* init = procédure d'initialisation de la classe associée. *
-* *
-* Description : Fournit un identifiant GLib pour un nouveau type Python. *
-* *
-* Retour : identifiant d'un nouveau type valide, ou 0. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static GType g_dynamic_types_register_type(GDynamicTypes *types, GType parent, const char *name, GClassInitFunc init)
-{
- GType result; /* Identifiant à retourner */
- type_dyn_info_t *new; /* Mémorisation de paramètres */
-
- /* Création d'un nouveau type adapté */
-
- result = g_type_register_dynamic(parent, name, G_TYPE_PLUGIN(types), 0);
-
- if (result == 0)
- goto exit;
-
- new = malloc(sizeof(type_dyn_info_t));
-
- new->type = result;
- new->init = init;
-
- /* Inscription définitive */
-
- types->info = realloc(types->info, ++types->count * sizeof(type_dyn_info_t *));
-
- types->info[types->count - 1] = new;
-
- exit:
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* ACCOMPAGNEMENTS DES NOUVEAUX TYPES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : - *
-* *
-* Description : Lance le support de dérivations de types dans Python. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool init_dynamic_python_types(void)
-{
- bool result; /* Bilan à retourner */
-
- _python_dtypes = g_dynamic_types_new();
-
- result = (_python_dtypes != NULL);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : - *
-* *
-* Description : Arrête le support de dérivations de types dans Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void exit_dynamic_python_types(void)
-{
- g_object_unref(G_OBJECT(_python_dtypes));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : parent = type GLib parent. *
-* name = désignation du nouveau type. *
-* init = procédure d'initialisation de la classe associée. *
-* *
-* Retour : Identifiant d'un nouveau type valide, ou 0. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GType built_dynamic_type(GType parent, const char *name, GClassInitFunc init)
-{
- GType result; /* Identifiant à retourner */
-
- result = g_type_from_name(name);
-
- if (result == 0)
- result = g_dynamic_types_register_type(_python_dtypes, parent, name, init);
-
- return result;
-
-}
diff --git a/plugins/pychrysalide/dt.h b/plugins/pychrysalide/dt.h
deleted file mode 100644
index b0f16db..0000000
--- a/plugins/pychrysalide/dt.h
+++ /dev/null
@@ -1,47 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * dt.h - prototypes pour la possibilité de créer de nouveaux types de façon dynamique
- *
- * Copyright (C) 2018 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _PLUGINS_PYCHRYSALIDE_DT_H
-#define _PLUGINS_PYCHRYSALIDE_DT_H
-
-
-#include <glib-object.h>
-#include <stdbool.h>
-
-
-
-/* ----------------------- ACCOMPAGNEMENTS DES NOUVEAUX TYPES ----------------------- */
-
-
-/* Lance le support de dérivations de types dans Python. */
-bool init_dynamic_python_types(void);
-
-/* Arrête le support de dérivations de types dans Python. */
-void exit_dynamic_python_types(void);
-
-/* Fournit un identifiant GLib pour un nouveau type Python. */
-GType built_dynamic_type(GType, const char *, GClassInitFunc);
-
-
-
-#endif /* _PLUGINS_PYCHRYSALIDE_DT_H */
diff --git a/plugins/pychrysalide/gui/editem.c b/plugins/pychrysalide/gui/editem.c
index 986d1cb..68962ae 100644
--- a/plugins/pychrysalide/gui/editem.c
+++ b/plugins/pychrysalide/gui/editem.c
@@ -45,9 +45,6 @@
/* Réagit à un changement de contenu chargé en cours d'analyse. */
static void py_editor_item_change_content_wrapper(GEditorItem *, GLoadedContent *, GLoadedContent *);
-/* Réagit à un changement de contenu chargé en cours d'analyse. */
-static void py_editor_item_change_content_wrapper(GEditorItem *, GLoadedContent *, GLoadedContent *);
-
/* Réagit à un changement de vue du contenu en cours d'analyse. */
static void py_editor_item_change_view_wrapper(GEditorItem *, GLoadedPanel *, GLoadedPanel *);
diff --git a/plugins/pychrysalide/gui/panels/panel.c b/plugins/pychrysalide/gui/panels/panel.c
index 1df0670..d4062d3 100644
--- a/plugins/pychrysalide/gui/panels/panel.c
+++ b/plugins/pychrysalide/gui/panels/panel.c
@@ -32,11 +32,11 @@
#include <core/params.h>
#include <gui/core/panels.h>
#include <gui/panels/panel-int.h>
+#include <plugins/dt.h>
#include "../editem.h"
#include "../../access.h"
-#include "../../dt.h"
#include "../../helpers.h"
#include "../../gtkext/dockable.h"
@@ -89,18 +89,16 @@ static bool py_panel_item_define_constants(PyTypeObject *);
static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *result; /* Objet à retourner */
- bool abstract; /* Validation du type parent */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
GType gtype; /* Nouveau type de processeur */
- PyObject *sys_mod_dict; /* Dictionnaire des modules */
- PyObject *modname; /* Nom du module du type */
- PyObject *module; /* Module à recompléter */
- PyObject *dict; /* Dictionnaire dudit module */
+ bool status; /* Bilan d'un enregistrement */
/* Validations diverses */
- abstract = (type == get_python_panel_item_type());
+ base = get_python_panel_item_type();
- if (abstract)
+ if (type == base)
{
result = NULL;
PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
@@ -109,30 +107,23 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject
/* Mise en place d'un type dédié */
- gtype = built_dynamic_type(G_TYPE_PANEL_ITEM, type->tp_name,
- (GClassInitFunc)py_panel_item_init_gclass);
-
- /* Enregistrement du nouveau GType dans Python */
-
- sys_mod_dict = PyImport_GetModuleDict();
+ first_time = (g_type_from_name(type->tp_name) == 0);
- modname = PyDict_GetItemString(type->tp_dict, "__module__");
-
- module = PyObject_GetItem(sys_mod_dict, modname);
+ gtype = built_dynamic_type(G_TYPE_PANEL_ITEM, type->tp_name,
+ (GClassInitFunc)py_panel_item_init_gclass, NULL);
- dict = PyModule_GetDict(module);
+ if (first_time)
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+ else
+ status = true;
- if (!_register_class_for_pygobject(dict, gtype, type,
- &PyGObject_Type, get_python_panel_item_type(), NULL))
+ if (!status)
{
result = NULL;
goto exit;
}
- Py_DECREF(module);
- Py_DECREF(modname);
-
- /* On créé, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
result = PyType_GenericNew(type, args, kwds);
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index ad62de4..a930097 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -701,3 +701,77 @@ bool _register_class_for_pygobject(PyObject *dict, GType gtype, PyTypeObject *ty
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : dict = dictionnaire où conserver une référence au type créé.*
+* gtype = type dans sa version GLib. *
+* type = type dans sa version Python. *
+* base = type de base de l'objet. *
+* *
+* Description : Enregistre un type Python dérivant d'un type GLib dynamique. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_class_for_dynamic_pygobject(GType gtype, PyTypeObject *type, PyTypeObject *base)
+{
+ bool result; /* Bilan à retourner */
+ PyTypeObject *legacy_parent; /* Type parent d'origine */
+ PyObject *sys_mod_dict; /* Dictionnaire des modules */
+ PyObject *modname; /* Nom du module du type */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire dudit module */
+
+ /**
+ * Lors de l'appel à pygobject_register_class(), PyGObject remplace systématiquement
+ * le type Python fourni par :
+ *
+ * Py_TYPE(type) = PyGObject_MetaType;
+ *
+ * Ce nouveau type est le suivant (cf. gi/types.py) :
+ *
+ * class _GObjectMetaBase(type):
+ * """Metaclass for automatically registering GObject classes."""
+ *
+ * D'une part, comme les enregistrements sont gérés manuellement dans le cas de
+ * types dérivés dynamiquement d'objets natifs, ce changement est inutile.
+ *
+ * D'autre part, il semble avoir un soucis de références (cf. testGarbageCollecting()
+ * du fichier de test plugins/plugin.py) :
+ *
+ * python3dm: ../Modules/gcmodule.c:379: visit_decref: Assertion `_PyGCHead_REFS(gc) != 0' failed.
+ *
+ * #3 __GI___assert_fail ()
+ * #4 visit_decref ()
+ * #5 subtype_traverse ()
+ * #6 subtract_refs ()
+ * #7 collect ()
+ * #8 collect_with_callback ()
+ * #9 gc_collect ()
+ *
+ * On restaure donc le type d'origine de l'objet Python créé dynamquement pour éviter
+ * ce genre de soucis.
+ */
+
+ legacy_parent = Py_TYPE(type);
+
+ sys_mod_dict = PyImport_GetModuleDict();
+
+ modname = PyDict_GetItemString(type->tp_dict, "__module__");
+
+ module = PyObject_GetItem(sys_mod_dict, modname);
+
+ dict = PyModule_GetDict(module);
+
+ result = _register_class_for_pygobject(dict, gtype, type, &PyGObject_Type, base, NULL);
+
+ Py_TYPE(type) = legacy_parent;
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index e080ca4..bf95e61 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -25,8 +25,9 @@
#define _PLUGINS_PYCHRYSALIDE_HELPERS_H
-#include <glib-object.h>
#include <Python.h>
+#include <assert.h>
+#include <glib-object.h>
#include <stdbool.h>
@@ -97,13 +98,8 @@ bool _register_class_for_pygobject(PyObject *, GType, PyTypeObject *, PyTypeObje
#define register_class_for_pygobject(dict, gtype, type, base) \
_register_class_for_pygobject(dict, gtype, type, base, NULL)
-
-/**
- * Quand on remplace un objet GLib dans le dos de Python, il faut
- * le remplacer de la même manière qu'on l'a obtenu !
- */
-
-#define pygobject_set(p, v) ((PyGObject *)(p))->obj = (GObject *)v
+/* Enregistre un type Python dérivant d'un type GLib dynamique. */
+bool register_class_for_dynamic_pygobject(GType, PyTypeObject *, PyTypeObject *);
diff --git a/plugins/pychrysalide/plugin.c b/plugins/pychrysalide/plugin.c
index a693d7b..22bfabb 100644
--- a/plugins/pychrysalide/plugin.c
+++ b/plugins/pychrysalide/plugin.c
@@ -32,6 +32,7 @@
#include <common/extstr.h>
+#include <plugins/dt.h>
#include <plugins/plugin-int.h>
@@ -41,6 +42,50 @@
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_plugin_module_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise la classe des greffons d'extension. */
+static void py_plugin_module_init_gclass(GPluginModuleClass *, gpointer);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds);
+
+/* Valide les fonctionnalités déclarées en actions. */
+static bool py_plugin_module_check_interface(PyObject *);
+
+/* Accompagne la fin du chargement des modules natifs. */
+static void py_plugin_module_notify_native_loaded_wrapper(GPluginModule *, PluginAction);
+
+/* Complète une liste de resources pour thème. */
+static void py_plugin_module_include_theme_wrapper(const GPluginModule *, PluginAction, char ***, size_t *);
+
+/* Procède à une opération liée à un contenu binaire. */
+static void py_plugin_module_handle_binary_content_wrapper(const GPluginModule *, PluginAction, GBinContent *, wgroup_id_t, GtkStatusStack *);
+
+/* Procède à une opération liée à un contenu chargé. */
+static void py_plugin_module_handle_loaded_content_wrapper(const GPluginModule *, PluginAction, GLoadedContent *, wgroup_id_t, GtkStatusStack *);
+
+/* Procède à une opération liée à l'analyse d'un format. */
+static bool py_plugin_module_handle_binary_format_analysis_wrapper(const GPluginModule *, PluginAction, GBinFormat *, wgroup_id_t, GtkStatusStack *);
+
+/* Procède à un préchargement de format de fichier. */
+static bool py_plugin_module_preload_binary_format_wrapper(const GPluginModule *, PluginAction, GBinFormat *, GPreloadInfo *, GtkStatusStack *);
+
+/* Procède au rattachement d'éventuelles infos de débogage. */
+static void py_plugin_module_attach_debug_format_wrapper(const GPluginModule *, PluginAction, GExeFormat *);
+
+/* Exécute une action pendant un désassemblage de binaire. */
+static void py_plugin_module_process_disassembly_event_wrapper(const GPluginModule *, PluginAction, GLoadedBinary *, GtkStatusStack *, GProcContext *);
+
+/* Effectue la détection d'effets d'outils externes. */
+static void py_plugin_module_detect_external_tools_wrapper(const GPluginModule *, PluginAction, const GLoadedContent *, bool, char ***, size_t *);
+
+
+
/* --------------------- INTERFACE INTERNE POUR GREFFONS PYTHON --------------------- */
@@ -75,30 +120,6 @@ static void g_python_plugin_dispose(GPythonPlugin *);
/* Description : Procède à la libération totale de la mémoire. */
static void g_python_plugin_finalize(GPythonPlugin *);
-/* Reconstruit la déclaration d'interface à partir de lectures. */
-static bool g_python_plugin_read_interface(GPythonPlugin *);
-
-/* Procède à l'initialisation du greffon. */
-static bool g_python_plugin_do_init(GPythonPlugin *);
-
-/* Procède à l'extinction du greffon. */
-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 *);
-
/* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */
@@ -113,61 +134,78 @@ static bool py_plugin_module_define_constants(PyTypeObject *);
/* ---------------------------------------------------------------------------------- */
-/* INTERFACE INTERNE POUR GREFFONS PYTHON */
+/* GLUE POUR CREATION DEPUIS PYTHON */
/* ---------------------------------------------------------------------------------- */
-/* Indique le type défini par la GLib pour le greffon Python. */
-G_DEFINE_TYPE(GPythonPlugin, g_python_plugin, G_TYPE_PLUGIN_MODULE);
-
-
/******************************************************************************
* *
-* Paramètres : klass = classe à initialiser. *
+* Paramètres : type = type du nouvel objet à mettre en place. *
+* args = éventuelle liste d'arguments. *
+* kwds = éventuel dictionnaire de valeurs mises à disposition. *
* *
-* Description : Initialise la classe des greffons Python. *
+* Description : Accompagne la création d'une instance dérivée en Python. *
* *
-* Retour : - *
+* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_python_plugin_class_init(GPythonPluginClass *klass)
+static PyObject *py_plugin_module_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- GObjectClass *object; /* Autre version de la classe */
+ PyObject *result; /* Objet à retourner */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
+ GType gtype; /* Nouveau type de processeur */
+ bool status; /* Bilan d'un enregistrement */
- object = G_OBJECT_CLASS(klass);
+ /* Validations diverses */
- object->dispose = (GObjectFinalizeFunc/* ! */)g_python_plugin_dispose;
- object->finalize = (GObjectFinalizeFunc)g_python_plugin_finalize;
+ base = get_python_plugin_module_type();
-}
+ if (type == base)
+ {
+ result = NULL;
+ PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
+ goto exit;
+ }
+ /* Mise en place d'un type dédié */
-/******************************************************************************
-* *
-* Paramètres : plugin = instance à initialiser. *
-* *
-* Description : Initialise l'instance d'un greffon Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ first_time = (g_type_from_name(type->tp_name) == 0);
-static void g_python_plugin_init(GPythonPlugin *plugin)
-{
+ gtype = built_dynamic_type(G_TYPE_PYTHON_PLUGIN, type->tp_name,
+ (GClassInitFunc)py_plugin_module_init_gclass, NULL);
+
+ if (first_time)
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+ else
+ status = true;
+
+ if (!status)
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : class = classe à initialiser. *
+* unused = données non utilisées ici. *
* *
-* Description : Supprime toutes les références externes. *
+* Description : Initialise la classe des greffons d'extension. *
* *
* Retour : - *
* *
@@ -175,191 +213,147 @@ static void g_python_plugin_init(GPythonPlugin *plugin)
* *
******************************************************************************/
-static void g_python_plugin_dispose(GPythonPlugin *plugin)
+static void py_plugin_module_init_gclass(GPluginModuleClass *class, gpointer unused)
{
- PyThreadState *tstate; /* Contexte d'environnement */
+ class->init = NULL;
+ class->exit = NULL;
- /**
- * Cf. https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
- *
- * Cependant, comme on se trouve à priori dans le thread principal de l'interpréteur,
- * PyGILState_Ensure() ne pose aucun verrou. Ce qui aboutit à la situation suivante :
- *
- * Fatal Python error: drop_gil: GIL is not locked
- *
- * On peut forcer les choses avec PyEval_AcquireLock(), mais cette fonction est marquée
- * comme dépréciée depuis Python 3.2.
- *
- * Donc on choisit les alternatives officielles.
- *
- * Cependant, PyThreadState_Get() renvoit l'erreur suivante :
- *
- * Fatal Python error: PyThreadState_Get: no current thread
- *
- * Donc on se rabat sur une sauvegarde, qui n'est initialisée que lorsque l'interpréteur
- * est intégré dans l'éditeur.
- */
+ class->native_loaded = py_plugin_module_notify_native_loaded_wrapper;
- tstate = get_pychrysalide_main_tstate();
+ class->include_theme = py_plugin_module_include_theme_wrapper;
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
+ class->handle_content = py_plugin_module_handle_binary_content_wrapper;
+ class->handle_loaded = py_plugin_module_handle_loaded_content_wrapper;
- Py_XDECREF(plugin->instance);
- plugin->instance = NULL;
+ class->handle_fmt_analysis = py_plugin_module_handle_binary_format_analysis_wrapper;
+ class->preload_format = py_plugin_module_preload_binary_format_wrapper;
+ class->attach_debug = py_plugin_module_attach_debug_format_wrapper;
- if (tstate != NULL)
- PyEval_SaveThread();
+ class->process_disass = py_plugin_module_process_disassembly_event_wrapper;
- G_OBJECT_CLASS(g_python_plugin_parent_class)->dispose(G_OBJECT(plugin));
+ class->detect = py_plugin_module_detect_external_tools_wrapper;
}
/******************************************************************************
* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Procède à la libération totale de la mémoire. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : - *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_python_plugin_finalize(GPythonPlugin *plugin)
+static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- plugin_interface *final; /* Interface finale conservée */
+ const char *name; /* Désignation humaine courte */
+ const char *desc; /* Description plus loquace */
+ const char *version; /* Version du greffon */
+ PyObject *actions_obj; /* Liste des actions offertes */
+ int ret; /* Bilan de lecture des args. */
+ PyObject *new_kwds; /* Nouveau dictionnaire épuré */
+ GPluginModule *plugin; /* Greffon à manipuler */
+ plugin_interface *iface; /* Interface à constituer */
+ size_t i; /* Boucle de parcours */
+ PyObject *action; /* Identifiant d'une action */
- Py_DECREF(plugin->module);
+ static char *kwlist[] = { "name", "desc", "version", "actions", NULL };
- final = (plugin_interface *)G_PLUGIN_MODULE(plugin)->interface;
+ /* Récupération des paramètres */
- if (final != NULL)
- {
- assert(final->required_count == 1);
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "sssO!", kwlist,
+ &name, &desc, &version, &PyTuple_Type, &actions_obj);
+ if (!ret) return -1;
- free(final->required);
- free(final);
+ /* Initialisation d'un objet GLib */
- }
+ new_kwds = PyDict_New();
- G_OBJECT_CLASS(g_python_plugin_parent_class)->finalize(G_OBJECT(plugin));
+ ret = PyGObject_Type.tp_init(self, args, new_kwds);
-}
+ Py_DECREF(new_kwds);
+ if (ret == -1) return -1;
-/******************************************************************************
-* *
-* Paramètres : modname = nom du module à charger. *
-* filename = chemin d'accès au code Python à charger. *
-* *
-* Description : Crée un greffon à partir de code Python. *
-* *
-* Retour : Adresse de la structure mise en place ou NULL si erreur. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ /* Eléments de base */
-GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
-{
- GPythonPlugin *result; /* Structure à retourner */
- PyObject *name; /* Chemin d'accès pour Python */
- PyObject *module; /* Script Python chargé */
- PyObject *err_type; /* Type d'erreur Python */
- PyObject *err_value; /* Instance Python d'erreur */
- PyObject *err_traceback; /* Trace Python associée */
- PyObject *err_string; /* Description Python d'erreur */
- const char *err_msg; /* Représentation humaine */
- PyObject *dict; /* Dictionnaire associé */
- PyObject *class; /* Classe à instancier */
- PyObject *instance; /* Instance Python du greffon */
- 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 */
+ plugin = G_PLUGIN_MODULE(pygobject_get(self));
- name = PyUnicode_FromString(modname);
- if (name == NULL) goto gppn_bad_exit;
+ iface = malloc(sizeof(plugin_interface));
+ plugin->interface = iface;
- module = PyImport_Import(name);
- Py_DECREF(name);
+ iface->name = strdup(name);
+ iface->desc = strdup(desc);
+ iface->version = strdup(version);
- if (PyErr_Occurred())
- {
- PyErr_Fetch(&err_type, &err_value, &err_traceback);
+ iface->container = false;
- if (err_value == NULL)
- log_variadic_message(LMT_ERROR,
- _("An unknown error occured when importing '%s'..."), modname);
- else
- {
- err_string = PyObject_Str(err_value);
- err_msg = PyUnicode_AsUTF8(err_string);
+ iface->required = malloc(sizeof(char *));
+ iface->required[0] = "PyChrysalide";
+ iface->required_count = 1;
- log_variadic_message(LMT_ERROR,
- _("An error occured when importing '%s': \"%s\""), modname, err_msg);
+ iface->actions_count = PyTuple_Size(actions_obj);
+ iface->actions = malloc(iface->actions_count * sizeof(plugin_action_t));
- Py_DECREF(err_string);
- Py_DECREF(err_value);
+ for (i = 0; i < iface->actions_count; i++)
+ {
+ action = PyTuple_GetItem(actions_obj, i);
+ if (!PyLong_Check(action))
+ {
+ PyErr_SetString(PyExc_TypeError, _("invalid type for plugin action."));
+ return -1;
}
- Py_XDECREF(err_traceback);
- Py_XDECREF(err_type);
-
- Py_XDECREF(module);
+ iface->actions[i] = PyLong_AsUnsignedLong(action);
- module = NULL;
+ }
+ if (!py_plugin_module_check_interface(self))
+ {
+ PyErr_SetString(PyExc_TypeError, _("missing features for the declared actions."));
+ return -1;
}
- if (module == NULL) goto gppn_bad_exit;
+ return 0;
- dict = PyModule_GetDict(module);
- class = PyDict_GetItemString(dict, "AutoLoad");
+}
- if (class == NULL) goto gppn_no_class;
- if (!PyType_Check(class->ob_type)) goto gppn_no_class;
- instance = PyObject_CallFunction(class, NULL);
- if (instance == NULL) goto gppn_no_instance;
+/******************************************************************************
+* *
+* Paramètres : self = greffon Python en cours d'initialisation. *
+* *
+* Description : Valide les fonctionnalités déclarées en actions. *
+* *
+* Retour : true si le greffon Python est à priori utilisable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- result = g_object_new(G_TYPE_PYTHON_PLUGIN, NULL);
+static bool py_plugin_module_check_interface(PyObject *self)
+{
+ bool result; /* Bilan à retourner */
+ GPluginModule *plugin; /* Greffon à manipuler */
+ 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 */
- G_PLUGIN_MODULE(result)->filename = strdup(filename);
+ result = true;
- result->module = module;
- result->instance = instance;
+ plugin = G_PLUGIN_MODULE(pygobject_get(self));
- if (!g_python_plugin_read_interface(result))
- goto gppn_interface_error;
-
- /* Localisation des différents points d'entrée déclarés */
-
-#define register_python_binding(inst, pysym, sym, binding) \
- ({ \
- bool __result; \
- if (!has_python_method(inst, #pysym)) \
- { \
- log_variadic_message(LMT_ERROR, \
- _("No '%s' entry in plugin candidate '%s'"), \
- #pysym, G_PLUGIN_MODULE(result)->filename); \
- __result = false; \
- } \
- else \
- { \
- G_PLUGIN_MODULE(result)->sym = binding; \
- __result = true; \
- } \
- __result; \
- })
-
- for (i = 0; i < G_PLUGIN_MODULE(result)->interface->actions_count; i++)
+ for (i = 0; i < plugin->interface->actions_count && result; i++)
{
- action = G_PLUGIN_MODULE(result)->interface->actions[i];
+ action = plugin->interface->actions[i];
category = MASK_PLUGIN_CATEGORY(action);
sub = MASK_PLUGIN_SUB_CATEGORY(action);
@@ -373,20 +367,17 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
break;
case PGA_PLUGIN_INIT:
- if (!register_python_binding(instance, init, init,
- (pg_management_fc)g_python_plugin_do_init))
- goto gppn_bad_plugin;
+ result = has_python_method(self, "init");
break;
case PGA_PLUGIN_EXIT:
- if (!register_python_binding(instance, exit, exit,
- (pg_management_fc)g_python_plugin_do_exit))
- goto gppn_bad_plugin;
+ result = has_python_method(self, "exit");
break;
default:
log_variadic_message(LMT_WARNING,
- _("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename);
+ _("Unknown sub-category '0x%02x' in plugin '%s'..."),
+ sub, self->ob_type->tp_name);
break;
}
@@ -402,16 +393,17 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
switch (action)
{
case PGA_CONTENT_EXPLORER:
+ result = has_python_method(self, "handle_binary_content");
+ break;
+
case PGA_CONTENT_RESOLVER:
- if (!register_python_binding(instance, handle_content, handle_content,
- (pg_handle_content_fc)g_python_plugin_handle_binary_content))
- goto gppn_bad_plugin;
+ result = has_python_method(self, "handle_loaded_content");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- action, filename);
+ action, self->ob_type->tp_name);
break;
}
@@ -426,27 +418,21 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
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;
+ result = has_python_method(self, "handle_format_analysis");
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;
+ result = has_python_method(self, "preload_format");
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;
+ result = has_python_method(self, "attach_debug_format");
break;
default:
log_variadic_message(LMT_WARNING,
_("Unknown action '0x%02x' in plugin '%s'..."),
- action, filename);
+ action, self->ob_type->tp_name);
break;
}
@@ -454,14 +440,13 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
break;
case DPS_DISASSEMBLY:
- if (!register_python_binding(instance, process_disassembly, process_disass,
- (pg_process_disassembly_fc)g_python_plugin_process_disass))
- goto gppn_bad_plugin;
+ result = has_python_method(self, "process_disassembly");
break;
default:
log_variadic_message(LMT_WARNING,
- _("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename);
+ _("Unknown sub-category '0x%02x' in plugin '%s'..."),
+ sub, self->ob_type->tp_name);
break;
}
@@ -470,217 +455,102 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
default:
log_variadic_message(LMT_WARNING,
- _("Unknown category '0x%02x' in plugin '%s'..."), category, filename);
+ _("Unknown category '0x%02x' in plugin '%s'..."),
+ category, self->ob_type->tp_name);
break;
}
}
- /* Conclusion */
-
- return G_PLUGIN_MODULE(result);
-
- gppn_bad_plugin:
-
- gppn_interface_error:
-
- g_object_unref(G_OBJECT(result));
-
- return NULL;
-
- gppn_no_instance:
-
- gppn_no_class:
-
- Py_DECREF(module);
-
- gppn_bad_exit:
-
- return NULL;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : plugin = greffon à initialiser. *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* unused = variable non utilisé pour l'usage de __VA_ARGS__. *
* *
-* Description : Reconstruit la déclaration d'interface à partir de lectures. *
+* Description : Accompagne la fin du chargement des modules natifs. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_python_plugin_read_interface(GPythonPlugin *plugin)
+static void py_plugin_module_notify_native_loaded_wrapper(GPluginModule *plugin, PluginAction action)
{
- bool result; /* Bilan à renvoyer */
- plugin_interface interface; /* Recueil des éléments */
- PyObject *desc; /* Tableau de description */
- PyObject *str; /* Chaîne de caractères */
- PyObject *tuple; /* Liste d'éléments à traiter */
- Py_ssize_t count; /* Nombre d'éléments présents */
- Py_ssize_t i; /* Boucle de parcours */
- PyObject *action; /* Identifiant d'une action */
- plugin_interface *final; /* Interface finale conservée */
-
- result = true;
-
- desc = run_python_method(plugin->instance, "get_interface", NULL);
- if (!PyDict_Check(desc))
- {
- result = false;
- goto pgpri_end;
- }
-
- memset(&interface, 0, sizeof(interface));
-
- /* Chargements des premières chaînes */
-
-#define READ_STR_FIELD(name) \
- str = PyDict_GetItemString(desc, #name); \
- if ((result = PyUnicode_Check(str))) \
- interface.name = strdup(PyUnicode_DATA(str)); \
-
- READ_STR_FIELD(name);
- READ_STR_FIELD(desc);
- READ_STR_FIELD(version);
-
- /* Chargement des actions supportées */
-
- tuple = PyDict_GetItemString(desc, "actions");
-
- if (!PyList_Check(tuple))
- {
- result = false;
- goto pgpri_failed;
- }
-
- count = PyList_GET_SIZE(tuple);
-
- interface.actions = (plugin_action_t *)calloc(count, sizeof(plugin_action_t));
- interface.actions_count = count;
-
- for (i = 0; i < count; i++)
- {
- action = PyList_GET_ITEM(tuple, i);
-
- interface.actions[i] = PyLong_AsUnsignedLong(action);
-
- }
-
- pgpri_failed:
-
- if (result)
- {
- final = (plugin_interface *)calloc(1, sizeof(plugin_interface));
-
- memcpy(final, &interface, sizeof(interface));
-
- final->required = (const char **)malloc(sizeof(char *));
- final->required[0] = "PyChrysalide";
- final->required_count = 1;
-
- G_PLUGIN_MODULE(plugin)->interface = final;
-
- }
- else
- {
- if (interface.name != NULL) free((char *)interface.name);
- if (interface.desc != NULL) free((char *)interface.desc);
- if (interface.version != NULL) free((char *)interface.version);
-
- if (interface.actions != NULL) free(interface.actions);
-
- }
-
- pgpri_end:
-
- Py_XDECREF(desc);
-
- return result;
}
/******************************************************************************
* *
-* Paramètres : plugin = greffon à initialiser. *
-* ref = espace de référencement global. *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* resources = liste de ressources à constituer. [OUT] *
+* count = taille de cette liste. [OUT] *
* *
-* Description : Procède à l'initialisation du greffon. *
+* Description : Complète une liste de resources pour thème. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_python_plugin_do_init(GPythonPlugin *plugin)
+static void py_plugin_module_include_theme_wrapper(const GPluginModule *plugin, PluginAction action, char ***resources, size_t *count)
{
- bool result; /* Bilan à retourner */
- PyThreadState *tstate; /* Contexte d'environnement */
- PyObject *value; /* Valeur obtenue */
-
- tstate = PyThreadState_Get();
-
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
-
- if (!has_python_method(plugin->instance, "init"))
- result = true;
-
- else
- {
- value = run_python_method(plugin->instance, "init", NULL);
-
- result = (value != NULL && PyObject_IsTrue(value));
-
- Py_XDECREF(value);
-
- }
-
- if (tstate != NULL)
- PyEval_SaveThread();
-
- return result;
}
/******************************************************************************
* *
-* Paramètres : plugin = greffon à initialiser. *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* content = contenu binaire à traiter. *
+* wid = identifiant du groupe de traitement. *
+* status = barre de statut à tenir informée. *
* *
-* Description : Procède à l'extinction du greffon. *
+* Description : Procède à une opération liée à un contenu binaire. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_python_plugin_do_exit(GPythonPlugin *plugin)
+static void py_plugin_module_handle_binary_content_wrapper(const GPluginModule *plugin, PluginAction action, GBinContent *content, wgroup_id_t wid, GtkStatusStack *status)
{
- bool result; /* Bilan à retourner */
- PyObject *value; /* Valeur obtenue */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *value; /* Valeurs obtenues */
- if (!has_python_method(plugin->instance, "exit"))
- result = true;
+ gstate = PyGILState_Ensure();
- else
- {
- value = run_python_method(plugin->instance, "exit", NULL);
+ pyobj = pygobject_new(G_OBJECT(plugin));
- result = (value != NULL && PyObject_IsTrue(value));
+ assert(has_python_method(pyobj, "handle_binary_content"));
- Py_XDECREF(value);
+ args = PyTuple_New(4);
- }
+ PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
+ PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(content)));
+ PyTuple_SetItem(args, 2, PyLong_FromUnsignedLong(wid));
+ PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(status)));
- return result;
+ value = run_python_method(pyobj, "handle_binary_content", args);
+
+ Py_XDECREF(value);
+ Py_DECREF(args);
+
+ PyGILState_Release(gstate);
}
@@ -689,11 +559,11 @@ static bool g_python_plugin_do_exit(GPythonPlugin *plugin)
* *
* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
-* content = contenu binaire à traiter. *
+* content = contenu chargé à traiter. *
* wid = identifiant du groupe de traitement. *
* status = barre de statut à tenir informée. *
* *
-* Description : Procède à une opération liée à un contenu binaire. *
+* Description : Procède à une opération liée à un contenu chargé. *
* *
* Retour : - *
* *
@@ -701,14 +571,19 @@ 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)
+static void py_plugin_module_handle_loaded_content_wrapper(const GPluginModule *plugin, PluginAction action, GLoadedContent *content, wgroup_id_t wid, GtkStatusStack *status)
{
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *value; /* Valeurs obtenues */
gstate = PyGILState_Ensure();
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ assert(has_python_method(pyobj, "handle_loaded_content"));
+
args = PyTuple_New(4);
PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
@@ -716,7 +591,7 @@ static void g_python_plugin_handle_binary_content(const GPythonPlugin *plugin, P
PyTuple_SetItem(args, 2, PyLong_FromUnsignedLong(wid));
PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(status)));
- value = run_python_method(plugin->instance, "handle_content", args);
+ value = run_python_method(pyobj, "handle_loaded_content", args);
Py_XDECREF(value);
Py_DECREF(args);
@@ -742,14 +617,19 @@ static void g_python_plugin_handle_binary_content(const GPythonPlugin *plugin, P
* *
******************************************************************************/
-static bool g_python_plugin_handle_binary_format_analysis(const GPythonPlugin *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status)
+static bool py_plugin_module_handle_binary_format_analysis_wrapper(const GPluginModule *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status)
{
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *value; /* Valeurs obtenues */
gstate = PyGILState_Ensure();
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ assert(has_python_method(pyobj, "handle_format_analysis"));
+
args = PyTuple_New(4);
PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
@@ -757,7 +637,7 @@ static bool g_python_plugin_handle_binary_format_analysis(const GPythonPlugin *p
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);
+ value = run_python_method(pyobj, "handle_format_analysis", args);
Py_XDECREF(value);
Py_DECREF(args);
@@ -785,14 +665,19 @@ static bool g_python_plugin_handle_binary_format_analysis(const GPythonPlugin *p
* *
******************************************************************************/
-static bool g_python_plugin_preload_binary_format(const GPythonPlugin *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status)
+static bool py_plugin_module_preload_binary_format_wrapper(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status)
{
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *value; /* Valeurs obtenues */
gstate = PyGILState_Ensure();
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ assert(has_python_method(pyobj, "preload_format"));
+
args = PyTuple_New(4);
PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
@@ -800,7 +685,7 @@ static bool g_python_plugin_preload_binary_format(const GPythonPlugin *plugin, P
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);
+ value = run_python_method(pyobj, "preload_format", args);
Py_XDECREF(value);
Py_DECREF(args);
@@ -826,20 +711,25 @@ static bool g_python_plugin_preload_binary_format(const GPythonPlugin *plugin, P
* *
******************************************************************************/
-static void g_python_plugin_attach_debug_format(const GPythonPlugin *plugin, PluginAction action, GExeFormat *format)
+static void py_plugin_module_attach_debug_format_wrapper(const GPluginModule *plugin, PluginAction action, GExeFormat *format)
{
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *value; /* Valeurs obtenues */
gstate = PyGILState_Ensure();
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ assert(has_python_method(pyobj, "attach_debug_format"));
+
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);
+ value = run_python_method(pyobj, "attach_debug_format", args);
Py_XDECREF(value);
Py_DECREF(args);
@@ -851,9 +741,9 @@ static void g_python_plugin_attach_debug_format(const GPythonPlugin *plugin, Plu
/******************************************************************************
* *
-* Paramètres : plugin = greffon à manipuler. *
-* action = type d'action attendue. *
-* binary = binaire dont le contenu est en cours de traitement.*
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* binary = binaire dont le contenu est en cours de traitement. *
* status = barre de statut à tenir informée. *
* context = contexte de désassemblage. *
* *
@@ -865,14 +755,19 @@ static void g_python_plugin_attach_debug_format(const GPythonPlugin *plugin, Plu
* *
******************************************************************************/
-static void g_python_plugin_process_disass(const GPythonPlugin *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context)
+static void py_plugin_module_process_disassembly_event_wrapper(const GPluginModule *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context)
{
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *value; /* Valeurs obtenues */
gstate = PyGILState_Ensure();
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ assert(has_python_method(pyobj, "process_disassembly"));
+
args = PyTuple_New(4);
PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(action));
@@ -880,7 +775,7 @@ 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_disassembly", args);
+ value = run_python_method(pyobj, "process_disassembly", args);
Py_XDECREF(value);
Py_DECREF(args);
@@ -890,6 +785,265 @@ static void g_python_plugin_process_disass(const GPythonPlugin *plugin, PluginAc
}
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* action = type d'action attendue. *
+* content = élément chargé à consulter. *
+* version = précise si les versions doivent être recherchées. *
+* names = désignations humaines correspondantes, à libérer. *
+* count = nombre de types d'obscurcissement trouvés. [OUT] *
+* *
+* Description : Effectue la détection d'effets d'outils externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_plugin_module_detect_external_tools_wrapper(const GPluginModule *plugin, PluginAction action, const GLoadedContent *content, bool version, char ***names, size_t *count)
+{
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTERFACE INTERNE POUR GREFFONS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour le greffon Python. */
+G_DEFINE_TYPE(GPythonPlugin, g_python_plugin, G_TYPE_PLUGIN_MODULE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des greffons Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_python_plugin_class_init(GPythonPluginClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_python_plugin_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_python_plugin_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un greffon Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_python_plugin_init(GPythonPlugin *plugin)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_python_plugin_dispose(GPythonPlugin *plugin)
+{
+ PyThreadState *tstate; /* Contexte d'environnement */
+
+ /**
+ * Cf. https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
+ *
+ * Cependant, comme on se trouve à priori dans le thread principal de l'interpréteur,
+ * PyGILState_Ensure() ne pose aucun verrou. Ce qui aboutit à la situation suivante :
+ *
+ * Fatal Python error: drop_gil: GIL is not locked
+ *
+ * On peut forcer les choses avec PyEval_AcquireLock(), mais cette fonction est marquée
+ * comme dépréciée depuis Python 3.2.
+ *
+ * Donc on choisit les alternatives officielles.
+ *
+ * Cependant, PyThreadState_Get() renvoit l'erreur suivante :
+ *
+ * Fatal Python error: PyThreadState_Get: no current thread
+ *
+ * Donc on se rabat sur une sauvegarde, qui n'est initialisée que lorsque l'interpréteur
+ * est intégré dans l'éditeur.
+ */
+
+ tstate = get_pychrysalide_main_tstate();
+
+ if (tstate != NULL)
+ PyEval_RestoreThread(tstate);
+
+ Py_XDECREF(plugin->instance);
+ plugin->instance = NULL;
+
+ if (tstate != NULL)
+ PyEval_SaveThread();
+
+ G_OBJECT_CLASS(g_python_plugin_parent_class)->dispose(G_OBJECT(plugin));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_python_plugin_finalize(GPythonPlugin *plugin)
+{
+ plugin_interface *final; /* Interface finale conservée */
+
+ Py_XDECREF(plugin->module);
+
+ final = (plugin_interface *)G_PLUGIN_MODULE(plugin)->interface;
+
+ if (final != NULL)
+ {
+ assert(final->required_count == 1);
+ free(final->required);
+
+ free(final);
+
+ }
+
+ G_OBJECT_CLASS(g_python_plugin_parent_class)->finalize(G_OBJECT(plugin));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : modname = nom du module à charger. *
+* filename = chemin d'accès au code Python à charger. *
+* *
+* Description : Crée un greffon à partir de code Python. *
+* *
+* Retour : Adresse de la structure mise en place ou NULL si erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
+{
+ GPythonPlugin *result; /* Structure à retourner */
+ PyObject *name; /* Chemin d'accès pour Python */
+ PyObject *module; /* Script Python chargé */
+ PyObject *err_type; /* Type d'erreur Python */
+ PyObject *err_value; /* Instance Python d'erreur */
+ PyObject *err_traceback; /* Trace Python associée */
+ PyObject *err_string; /* Description Python d'erreur */
+ const char *err_msg; /* Représentation humaine */
+ PyObject *dict; /* Dictionnaire associé */
+ PyObject *class; /* Classe à instancier */
+ PyObject *instance; /* Instance Python du greffon */
+
+ name = PyUnicode_FromString(modname);
+ if (name == NULL) goto gppn_bad_exit;
+
+ module = PyImport_Import(name);
+ Py_DECREF(name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Fetch(&err_type, &err_value, &err_traceback);
+
+ if (err_value == NULL)
+ log_variadic_message(LMT_ERROR,
+ _("An unknown error occured when importing '%s'..."), modname);
+ else
+ {
+ err_string = PyObject_Str(err_value);
+ err_msg = PyUnicode_AsUTF8(err_string);
+
+ log_variadic_message(LMT_ERROR,
+ _("An error occured when importing '%s': \"%s\""), modname, err_msg);
+
+ Py_DECREF(err_string);
+ Py_DECREF(err_value);
+
+ }
+
+ Py_XDECREF(err_traceback);
+ Py_XDECREF(err_type);
+
+ Py_XDECREF(module);
+
+ module = NULL;
+
+ }
+
+ if (module == NULL) goto gppn_bad_exit;
+
+ dict = PyModule_GetDict(module);
+ class = PyDict_GetItemString(dict, "AutoLoad");
+
+ if (class == NULL) goto gppn_no_class;
+ if (!PyType_Check(class->ob_type)) goto gppn_no_class;
+
+ instance = PyObject_CallFunction(class, NULL);
+ if (instance == NULL) goto gppn_no_instance;
+
+ result = G_PYTHON_PLUGIN(pygobject_get(instance));
+
+ G_PLUGIN_MODULE(result)->filename = strdup(filename);
+
+ result->module = module;
+ result->instance = instance;
+
+ Py_INCREF(instance);
+
+ return G_PLUGIN_MODULE(result);
+
+ gppn_no_instance:
+
+ gppn_no_class:
+
+ Py_DECREF(module);
+
+ gppn_bad_exit:
+
+ return NULL;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* MODULE PYTHON POUR LES SCRIPTS */
@@ -926,7 +1080,7 @@ static PyObject *py_plugin_module_log_message(PyObject *self, PyObject *args)
case LMT_BAD_BINARY:
case LMT_ERROR:
case LMT_EXT_ERROR:
- /*g_plugin_module_*/log_simple_message(/*G_PLUGIN_MODULE(pygobject_get(self)), */type, msg);
+ g_plugin_module_log_simple_message(G_PLUGIN_MODULE(pygobject_get(self)), type, msg);
result = Py_None;
Py_INCREF(result);
break;
@@ -1037,7 +1191,10 @@ PyTypeObject *get_python_plugin_module_type(void)
.tp_doc = "Chrysalide plugin for Python.",
.tp_methods = py_plugin_module_methods,
- .tp_getset = py_plugin_module_getseters
+ .tp_getset = py_plugin_module_getseters,
+
+ .tp_init = py_plugin_module_init,
+ .tp_new = py_plugin_module_new,
};
@@ -1072,7 +1229,7 @@ bool ensure_python_plugin_module_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_PLUGIN_MODULE, type, &PyGObject_Type))
+ if (!register_class_for_pygobject(dict, G_TYPE_PYTHON_PLUGIN, type, &PyGObject_Type))
return false;
if (!py_plugin_module_define_constants(type))
diff --git a/plugins/pychrysalide/pychrysa.c b/plugins/pychrysalide/pychrysa.c
index 8849981..502bf20 100644
--- a/plugins/pychrysalide/pychrysa.c
+++ b/plugins/pychrysalide/pychrysa.c
@@ -45,7 +45,6 @@
#include "access.h"
#include "constval.h"
-#include "dt.h"
#include "helpers.h"
#include "plugin.h"
#include "star.h"
@@ -63,7 +62,7 @@
-DEFINE_CHRYSALIDE_CONTAINER_PLUGIN("PyChrysalide", "Provides bindings to Python", "0.1.0",
+DEFINE_CHRYSALIDE_CONTAINER_PLUGIN("GPyChrysalidePlugin", "PyChrysalide", "Provides bindings to Python", "0.1.0",
EMPTY_PG_LIST(.required), AL(PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT, PGA_NATIVE_LOADED));
@@ -368,8 +367,6 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
/* Mise en place des fonctionnalités offertes */
- init_dynamic_python_types();
-
result = PyModule_Create(&py_chrysalide_module);
register_access_to_python_module(py_chrysalide_module.m_name, result);
diff --git a/plugins/readdex/reader.c b/plugins/readdex/reader.c
index 5b84a0d..2009ad6 100644
--- a/plugins/readdex/reader.c
+++ b/plugins/readdex/reader.c
@@ -34,7 +34,7 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readdex", "Displays information about DEX files", "0.2.0",
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("GDexReaderPlugin", "readdex", "Displays information about DEX files", "0.2.0",
PGA_FORMAT_PRELOAD);
diff --git a/plugins/readelf/reader.c b/plugins/readelf/reader.c
index b137659..ba4d17a 100644
--- a/plugins/readelf/reader.c
+++ b/plugins/readelf/reader.c
@@ -35,7 +35,7 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readelf", "Displays information about ELF files", "0.2.0",
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("GElfReaderPlugin", "readelf", "Displays information about ELF files", "0.2.0",
PGA_FORMAT_PRELOAD);
diff --git a/plugins/readmc/reader.c b/plugins/readmc/reader.c
index e10b927..e492eeb 100644
--- a/plugins/readmc/reader.c
+++ b/plugins/readmc/reader.c
@@ -36,7 +36,7 @@
-DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("readmc", "Displays information about Mobicore files", "0.2.0",
+DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("GMCReaderPlugin", "readmc", "Displays information about Mobicore files", "0.2.0",
PGA_FORMAT_PRELOAD);
diff --git a/plugins/ropgadgets/plugin.c b/plugins/ropgadgets/plugin.c
index 1ecb7d8..d560c88 100644
--- a/plugins/ropgadgets/plugin.c
+++ b/plugins/ropgadgets/plugin.c
@@ -36,7 +36,7 @@
-DEFINE_CHRYSALIDE_PLUGIN("ROP gadgets", "Find available gadgets for a ROP chain", "0.1.0",
+DEFINE_CHRYSALIDE_PLUGIN("GROPPlugin", "ROP gadgets", "Find available gadgets for a ROP chain", "0.1.0",
RL("PyChrysalide"), AL(PGA_PLUGIN_INIT));