summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-04-21 18:44:33 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-04-21 18:44:33 (GMT)
commitcd54168f9877ed4ee16ee1e25c72e8338eed7928 (patch)
tree04dc1a85a28ff8a95eaaa6a0bbd5909ea2dc6397
parent3dada5fbc27777217625603905727364a0cc996d (diff)
Redefined the interface for creating new processors from Python.
-rw-r--r--plugins/arm/processor.c31
-rw-r--r--plugins/arm/v7/processor.c93
-rw-r--r--plugins/dalvik/processor.c86
-rw-r--r--plugins/dalvik/v35/processor.c29
-rw-r--r--plugins/pychrysalide/analysis/constants.c5
-rw-r--r--plugins/pychrysalide/arch/processor.c428
-rw-r--r--plugins/pychrysalide/helpers.h5
-rw-r--r--src/analysis/binary.c4
-rw-r--r--src/arch/processor-int.h27
-rw-r--r--src/arch/processor.c48
-rw-r--r--src/arch/processor.h2
-rw-r--r--src/core/processors.c3
12 files changed, 677 insertions, 84 deletions
diff --git a/plugins/arm/processor.c b/plugins/arm/processor.c
index ede8674..830fa8a 100644
--- a/plugins/arm/processor.c
+++ b/plugins/arm/processor.c
@@ -40,6 +40,9 @@ static void g_arm_processor_dispose(GArmProcessor *);
/* Procède à la libération totale de la mémoire. */
static void g_arm_processor_finalize(GArmProcessor *);
+/* Indique si l'architecture possède un espace virtuel ou non. */
+static bool g_arm_processor_has_virtual_space(const GArmProcessor *);
+
/* Indique le type défini par la GLib pour le processeur ARM. */
@@ -61,12 +64,17 @@ G_DEFINE_TYPE(GArmProcessor, g_arm_processor, G_TYPE_ARCH_PROCESSOR);
static void g_arm_processor_class_init(GArmProcessorClass *klass)
{
GObjectClass *object_class; /* Autre version de la classe */
+ GArchProcessorClass *proc; /* Encore une autre vision... */
object_class = G_OBJECT_CLASS(klass);
object_class->dispose = (GObjectFinalizeFunc/* ! */)g_arm_processor_dispose;
object_class->finalize = (GObjectFinalizeFunc)g_arm_processor_finalize;
+ proc = G_ARCH_PROCESSOR_CLASS(klass);
+
+ proc->has_vspace = (has_processor_vspace_fc)g_arm_processor_has_virtual_space;
+
}
@@ -124,3 +132,26 @@ static void g_arm_processor_finalize(GArmProcessor *proc)
G_OBJECT_CLASS(g_arm_processor_parent_class)->finalize(G_OBJECT(proc));
}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Indique si l'architecture possède un espace virtuel ou non. *
+* *
+* Retour : true si un espace virtuel existe, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arm_processor_has_virtual_space(const GArmProcessor *proc)
+{
+ bool result; /* Indication à retourner */
+
+ result = true;
+
+ return result;
+
+}
diff --git a/plugins/arm/v7/processor.c b/plugins/arm/v7/processor.c
index 078cc2d..7852284 100644
--- a/plugins/arm/v7/processor.c
+++ b/plugins/arm/v7/processor.c
@@ -66,6 +66,15 @@ static void g_armv7_processor_finalize(GArmV7Processor *);
/* Fournit la désignation interne du processeur d'architecture. */
static char *g_armv7_processor_get_key(const GArmV7Processor *);
+/* Fournit le nom humain de l'architecture visée. */
+static char *g_armv7_processor_get_desc(const GArmV7Processor *);
+
+/* Fournit la taille de l'espace mémoire d'une architecture. */
+static MemoryDataSize g_armv7_processor_get_memory_size(const GArmV7Processor *);
+
+/* Fournit la taille min. des instructions d'une architecture. */
+static MemoryDataSize g_armv7_processor_get_instruction_min_size(const GArmV7Processor *);
+
/* Fournit un contexte pour l'exécution du processeur ARM. */
static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *);
@@ -102,16 +111,12 @@ static void g_armv7_processor_class_init(GArmV7ProcessorClass *klass)
proc = G_ARCH_PROCESSOR_CLASS(klass);
- proc->desc = "ARM v7";
-
- proc->endianness = SRE_LITTLE;
- proc->memsize = MDS_32_BITS;
- proc->inssize = MDS_32_BITS;
- proc->virt_space = true;
-
proc->get_key = (get_processor_key_fc)g_armv7_processor_get_key;
- proc->get_ctx = (get_processor_context_fc)g_armv7_processor_get_context;
+ proc->get_desc = (get_processor_desc_fc)g_armv7_processor_get_desc;
+ proc->get_memsize = (get_processor_memsize_fc)g_armv7_processor_get_memory_size;
+ proc->get_inssize = (get_processor_inssize_fc)g_armv7_processor_get_instruction_min_size;
+ proc->get_ctx = (get_processor_context_fc)g_armv7_processor_get_context;
proc->disassemble = (disass_instr_fc)g_armv7_processor_disassemble;
}
@@ -131,6 +136,7 @@ static void g_armv7_processor_class_init(GArmV7ProcessorClass *klass)
static void g_armv7_processor_init(GArmV7Processor *proc)
{
+ G_ARCH_PROCESSOR(proc)->endianness = SRE_LITTLE;
}
@@ -221,6 +227,75 @@ static char *g_armv7_processor_get_key(const GArmV7Processor *proc)
/******************************************************************************
* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit le nom humain de l'architecture visée. *
+* *
+* Retour : Désignation humaine associée au processeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_armv7_processor_get_desc(const GArmV7Processor *proc)
+{
+ char *result; /* Désignation à renvoyer */
+
+ result = strdup("ARM v7");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille de l'espace mémoire d'une architecture. *
+* *
+* Retour : Taille de l'espace mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static MemoryDataSize g_armv7_processor_get_memory_size(const GArmV7Processor *proc)
+{
+ MemoryDataSize result; /* Taille à retourner */
+
+ result = MDS_32_BITS;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille min. des instructions d'une architecture. *
+* *
+* Retour : Taille d'encodage des instructions. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static MemoryDataSize g_armv7_processor_get_instruction_min_size(const GArmV7Processor *proc)
+{
+ MemoryDataSize result; /* Taille à retourner */
+
+ result = MDS_32_BITS;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture, spectatrice ici. *
* *
* Description : Fournit un contexte pour l'exécution du processeur Arm. *
@@ -262,7 +337,7 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
uint32_t raw32; /* Donnée 32 bits à analyser */
ArmV7InstrSet iset; /* Type de jeu d'instructions */
- endian = G_ARCH_PROCESSOR_GET_CLASS(proc)->endianness;
+ endian = G_ARCH_PROCESSOR(proc)->endianness;
iset = g_armv7_context_find_encoding(ctx, get_virt_addr(pos));
diff --git a/plugins/dalvik/processor.c b/plugins/dalvik/processor.c
index 38f245c..a1a211e 100644
--- a/plugins/dalvik/processor.c
+++ b/plugins/dalvik/processor.c
@@ -50,6 +50,15 @@ static void g_dalvik_processor_dispose(GDalvikProcessor *);
/* Procède à la libération totale de la mémoire. */
static void g_dalvik_processor_finalize(GDalvikProcessor *);
+/* Fournit la taille de l'espace mémoire d'une architecture. */
+static MemoryDataSize g_dalvik_processor_get_memory_size(const GDalvikProcessor *);
+
+/* Fournit la taille min. des instructions d'une architecture. */
+static MemoryDataSize g_dalvik_processor_get_instruction_min_size(const GDalvikProcessor *);
+
+/* Indique si l'architecture possède un espace virtuel ou non. */
+static bool g_dalvik_processor_has_virtual_space(const GDalvikProcessor *);
+
/* Fournit un contexte pour l'exécution du processeur Dalvik. */
static GDalvikContext *g_dalvik_processor_get_context(const GDalvikProcessor *);
@@ -83,10 +92,9 @@ static void g_dalvik_processor_class_init(GDalvikProcessorClass *klass)
proc = G_ARCH_PROCESSOR_CLASS(klass);
- proc->endianness = SRE_LITTLE;
- proc->memsize = MDS_32_BITS;
- proc->inssize = MDS_16_BITS;
- proc->virt_space = false;
+ proc->get_memsize = (get_processor_memsize_fc)g_dalvik_processor_get_memory_size;
+ proc->get_inssize = (get_processor_inssize_fc)g_dalvik_processor_get_instruction_min_size;
+ proc->has_vspace = (has_processor_vspace_fc)g_dalvik_processor_has_virtual_space;
proc->get_ctx = (get_processor_context_fc)g_dalvik_processor_get_context;
@@ -107,6 +115,7 @@ static void g_dalvik_processor_class_init(GDalvikProcessorClass *klass)
static void g_dalvik_processor_init(GDalvikProcessor *proc)
{
+ G_ARCH_PROCESSOR(proc)->endianness = SRE_LITTLE;
}
@@ -151,6 +160,75 @@ static void g_dalvik_processor_finalize(GDalvikProcessor *proc)
/******************************************************************************
* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille de l'espace mémoire d'une architecture. *
+* *
+* Retour : Taille de l'espace mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static MemoryDataSize g_dalvik_processor_get_memory_size(const GDalvikProcessor *proc)
+{
+ MemoryDataSize result; /* Taille à retourner */
+
+ result = MDS_32_BITS;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille min. des instructions d'une architecture. *
+* *
+* Retour : Taille d'encodage des instructions. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static MemoryDataSize g_dalvik_processor_get_instruction_min_size(const GDalvikProcessor *proc)
+{
+ MemoryDataSize result; /* Taille à retourner */
+
+ result = MDS_16_BITS;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Indique si l'architecture possède un espace virtuel ou non. *
+* *
+* Retour : true si un espace virtuel existe, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_dalvik_processor_has_virtual_space(const GDalvikProcessor *proc)
+{
+ bool result; /* Indication à retourner */
+
+ result = false;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture, spectatrice ici. *
* *
* Description : Fournit un contexte pour l'exécution du processeur Dalvik. *
diff --git a/plugins/dalvik/v35/processor.c b/plugins/dalvik/v35/processor.c
index 0865ee7..7e79e46 100644
--- a/plugins/dalvik/v35/processor.c
+++ b/plugins/dalvik/v35/processor.c
@@ -67,6 +67,9 @@ static void g_dalvik35_processor_finalize(GDalvik35Processor *);
/* Fournit la désignation interne du processeur d'architecture. */
static char *g_dalvik35_processor_get_key(const GDalvik35Processor *);
+/* Fournit le nom humain de l'architecture visée. */
+static char *g_dalvik35_processor_get_desc(const GDalvik35Processor *);
+
/* Décode une instruction dans un flux de données. */
static GArchInstruction *g_dalvik35_processor_disassemble(const GArchProcessor *, GDalvikContext *, const GBinContent *, vmpa2t *, GExeFormat *);
@@ -100,9 +103,8 @@ static void g_dalvik35_processor_class_init(GDalvik35ProcessorClass *klass)
proc = G_ARCH_PROCESSOR_CLASS(klass);
- proc->desc = "Dalvik Virtual Machine v35";
-
proc->get_key = (get_processor_key_fc)g_dalvik35_processor_get_key;
+ proc->get_desc = (get_processor_desc_fc)g_dalvik35_processor_get_desc;
proc->disassemble = (disass_instr_fc)g_dalvik35_processor_disassemble;
@@ -213,6 +215,29 @@ static char *g_dalvik35_processor_get_key(const GDalvik35Processor *proc)
/******************************************************************************
* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit le nom humain de l'architecture visée. *
+* *
+* Retour : Désignation humaine associée au processeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_dalvik35_processor_get_desc(const GDalvik35Processor *proc)
+{
+ char *result; /* Désignation à renvoyer */
+
+ result = strdup("Dalvik Virtual Machine v35");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : proc = architecture visée par la procédure. *
* ctx = contexte lié à l'exécution du processeur. *
* content = flux de données à analyser. *
diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c
index d014fb7..87f91a3 100644
--- a/plugins/pychrysalide/analysis/constants.c
+++ b/plugins/pychrysalide/analysis/constants.c
@@ -78,6 +78,11 @@ bool define_analysis_content_constants(PyTypeObject *type)
if (result) result = add_const_to_group(values, "_16_BITS_SIGNED", MDS_16_BITS_SIGNED);
if (result) result = add_const_to_group(values, "_32_BITS_SIGNED", MDS_32_BITS_SIGNED);
if (result) result = add_const_to_group(values, "_64_BITS_SIGNED", MDS_64_BITS_SIGNED);
+ if (result) result = add_const_to_group(values, "_4_BITS", MDS_4_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "_8_BITS", MDS_8_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "_16_BITS", MDS_16_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "_32_BITS", MDS_32_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "_64_BITS", MDS_64_BITS_UNSIGNED);
if (!result)
{
diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c
index f04929e..1cfb989 100644
--- a/plugins/pychrysalide/arch/processor.c
+++ b/plugins/pychrysalide/arch/processor.c
@@ -45,6 +45,31 @@
+#define ARCH_PROCESSOR_DOC \
+ "The ArchProcessor object aims to get subclassed to create" \
+ " processors for new architectures.\n" \
+ "\n" \
+ "Several items have to be defined as class attributes in the final" \
+ " class:\n" \
+ "* *_key*: a string providing a small name used to identify the" \
+ " architecture;\n" \
+ "* *_desc*: a string for a human readable description of the" \
+ " new architecture;\n" \
+ "* *_memory_size*: size of the memory space, as a" \
+ " pychrysalide.analysis.BinContent.MemoryDataSize value;\n" \
+ "* *_ins_min_size*: size of the smallest instruction, as a" \
+ " pychrysalide.analysis.BinContent.MemoryDataSize value;\n" \
+ "* *_virtual_space*: a boolean value indicating if the architecture"\
+ " supports a virtual space.\n" \
+ "\n" \
+ "Calls to the *__init__* constructor of this abstract object expect"\
+ " the following arguments as keyword parameters:\n" \
+ "* *endianness*: endianness to apply to the binary content to" \
+ " disassemble, as a pychrysalide.analysis.BinContent.SourceEndian" \
+ " value.\n"
+
+
+
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
@@ -63,6 +88,18 @@ static int py_arch_processor_init(PyObject *, PyObject *, PyObject *);
/* Fournit la désignation interne du processeur d'architecture. */
static char *py_arch_processor_get_key_wrapper(const GArchProcessor *);
+/* Fournit le nom humain de l'architecture visée. */
+static char *py_arch_processor_get_desc_wrapper(const GArchProcessor *);
+
+/* Fournit la taille de l'espace mémoire d'une architecture. */
+static MemoryDataSize py_arch_processor_get_memory_size_wrapper(const GArchProcessor *);
+
+/* Fournit la taille min. des instructions d'une architecture. */
+static MemoryDataSize py_arch_processor_get_instruction_min_size_wrapper(const GArchProcessor *);
+
+/* Indique si l'architecture possède un espace virtuel ou non. */
+static bool py_arch_processor_has_virtual_space_wrapper(const GArchProcessor *);
+
/* Fournit un contexte propre au processeur d'une architecture. */
static GProcContext *py_arch_processor_get_context_wrapper(const GArchProcessor *);
@@ -74,6 +111,12 @@ static GArchInstruction *py_arch_processor_disassemble_wrapper(const GArchProces
/* ---------------------------- DEFINITION DE PROCESSEUR ---------------------------- */
+/* Fournit la désignation interne du processeur d'architecture. */
+static PyObject *py_arch_processor_get_key(PyObject *, void *);
+
+/* Fournit le nom humain de l'architecture visée. */
+static PyObject *py_arch_processor_get_desc(PyObject *, void *);
+
/* Fournit le boustime du processeur d'une architecture. */
static PyObject *py_arch_processor_get_endianness(PyObject *, void *);
@@ -81,7 +124,7 @@ static PyObject *py_arch_processor_get_endianness(PyObject *, void *);
static PyObject *py_arch_processor_get_memory_size(PyObject *, void *);
/* Fournit la taille min. des instructions d'une architecture. */
-static PyObject *py_arch_processor_get_instruction_min_size(PyObject *, void *);
+static PyObject *py_arch_processor_get_ins_min_size(PyObject *, void *);
/* Indique si l'architecture possède un espace virtuel ou non. */
static PyObject *py_arch_processor_has_virtual_space(PyObject *, void *);
@@ -229,8 +272,12 @@ static void py_arch_processor_init_gclass(GArchProcessorClass *class, gpointer u
}
class->get_key = py_arch_processor_get_key_wrapper;
- class->get_ctx = py_arch_processor_get_context_wrapper;
+ class->get_desc = py_arch_processor_get_desc_wrapper;
+ class->get_memsize = py_arch_processor_get_memory_size_wrapper;
+ class->get_inssize = py_arch_processor_get_instruction_min_size_wrapper;
+ class->has_vspace = py_arch_processor_has_virtual_space_wrapper;
+ class->get_ctx = py_arch_processor_get_context_wrapper;
class->disassemble = py_arch_processor_disassemble_wrapper;
}
@@ -271,20 +318,16 @@ static void py_arch_processor_init_ginstance(GArchProcessor *proc, GArchProcesso
static int py_arch_processor_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- unsigned long endianness; /* Boutisme du processeur */
- unsigned long mem_size; /* Taille d'adressage */
- unsigned long ins_min_size; /* Taille minimale d'instruct° */
- int vspace; /* Support d'un espace virtuel */
+ unsigned int endianness; /* Boutisme du processeur */
int ret; /* Bilan de lecture des args. */
PyObject *new_kwds; /* Nouveau dictionnaire épuré */
GArchProcessor *proc; /* Processeur à manipuler */
- static char *kwlist[] = { "endianness", "mem_size", "ins_min_size", "vspace", NULL };
+ static char *kwlist[] = { "endianness", NULL };
/* Récupération des paramètres */
- ret = PyArg_ParseTupleAndKeywords(args, kwds, "kkkp", kwlist,
- &endianness, &mem_size, &ins_min_size, &vspace);
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "I", kwlist, &endianness);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
@@ -301,14 +344,9 @@ static int py_arch_processor_init(PyObject *self, PyObject *args, PyObject *kwds
proc = G_ARCH_PROCESSOR(pygobject_get(self));
- /*
proc->endianness = endianness;
- proc->memsize = mem_size;
- proc->inssize = ins_min_size;
- proc->virt_space = vspace;
- */
- register_dynamic_type_pattern(G_OBJECT(proc));
+ //register_dynamic_type_pattern(G_OBJECT(proc));
return 0;
@@ -334,8 +372,6 @@ static char *py_arch_processor_get_key_wrapper(const GArchProcessor *proc)
PyObject *pyobj; /* Objet Python concerné */
PyObject *pykey; /* Clef en objet Python */
int ret; /* Bilan d'une conversion */
- GArchProcessorClass *class; /* Classe de l'objet courant */
- GArchProcessorClass *parent; /* Classe parente */
result = NULL;
@@ -343,9 +379,9 @@ static char *py_arch_processor_get_key_wrapper(const GArchProcessor *proc)
pyobj = pygobject_new(G_OBJECT(proc));
- if (has_python_method(pyobj, "_get_key"))
+ if (PyObject_HasAttrString(pyobj, "_key"))
{
- pykey = run_python_method(pyobj, "_get_key", NULL);
+ pykey = PyObject_GetAttrString(pyobj, "_key");
if (pykey != NULL)
{
@@ -360,13 +396,203 @@ static char *py_arch_processor_get_key_wrapper(const GArchProcessor *proc)
}
- else
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit le nom humain de l'architecture visée. *
+* *
+* Retour : Désignation humaine associée au processeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_arch_processor_get_desc_wrapper(const GArchProcessor *proc)
+{
+ char *result; /* Désignation à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pydesc; /* Description en objet Python */
+ int ret; /* Bilan d'une conversion */
+
+ result = NULL;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(proc));
+
+ if (PyObject_HasAttrString(pyobj, "_desc"))
{
- class = G_ARCH_PROCESSOR_GET_CLASS(proc);
- parent = g_type_class_peek_parent(class);
+ pydesc = PyObject_GetAttrString(pyobj, "_desc");
+
+ if (pydesc != NULL)
+ {
+ ret = PyUnicode_Check(pydesc);
+
+ if (ret)
+ result = strdup(PyUnicode_AsUTF8(pydesc));
+
+ Py_DECREF(pydesc);
+
+ }
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille de l'espace mémoire d'une architecture. *
+* *
+* Retour : Taille de l'espace mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static MemoryDataSize py_arch_processor_get_memory_size_wrapper(const GArchProcessor *proc)
+{
+ MemoryDataSize result; /* Taille à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pysize; /* Taille en objet Python */
+ int ret; /* Bilan d'une conversion */
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(proc));
+
+ if (PyObject_HasAttrString(pyobj, "_memory_size"))
+ {
+ pysize = PyObject_GetAttrString(pyobj, "_memory_size");
+
+ if (pysize != NULL)
+ {
+ ret = PyLong_Check(pysize);
+
+ if (ret)
+ result = PyLong_AsUnsignedLong(pysize);
+
+ Py_DECREF(pysize);
+
+ }
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Fournit la taille min. des instructions d'une architecture. *
+* *
+* Retour : Taille d'encodage des instructions. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static MemoryDataSize py_arch_processor_get_instruction_min_size_wrapper(const GArchProcessor *proc)
+{
+ MemoryDataSize result; /* Taille à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pysize; /* Taille en objet Python */
+ int ret; /* Bilan d'une conversion */
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(proc));
- if (parent->get_key != NULL)
- result = parent->get_key(proc);
+ if (PyObject_HasAttrString(pyobj, "_ins_min_size"))
+ {
+ pysize = PyObject_GetAttrString(pyobj, "_ins_min_size");
+
+ if (pysize != NULL)
+ {
+ ret = PyLong_Check(pysize);
+
+ if (ret)
+ result = PyLong_AsUnsignedLong(pysize);
+
+ Py_DECREF(pysize);
+
+ }
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = processeur d'architecture à consulter. *
+* *
+* Description : Indique si l'architecture possède un espace virtuel ou non. *
+* *
+* Retour : true si un espace virtuel existe, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_arch_processor_has_virtual_space_wrapper(const GArchProcessor *proc)
+{
+ bool result; /* Indication à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyhas; /* Présence en objet Python */
+ int ret; /* Bilan d'une conversion */
+
+ result = false;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(proc));
+
+ if (PyObject_HasAttrString(pyobj, "_virtual_space"))
+ {
+ pyhas = PyObject_GetAttrString(pyobj, "_virtual_space");
+
+ if (pyhas != NULL)
+ {
+ ret = PyBool_Check(pyhas);
+
+ if (ret)
+ result = (pyhas == Py_True);
+
+ Py_DECREF(pyhas);
+
+ }
}
@@ -535,6 +761,100 @@ static GArchInstruction *py_arch_processor_disassemble_wrapper(const GArchProces
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
+* Description : Fournit la désignation interne du processeur d'architecture. *
+* *
+* Retour : Simple chaîne de caractères. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_processor_get_key(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GArchProcessor *proc; /* Version GLib de l'opérande */
+ char *key; /* Désignation du processeur */
+
+#define ARCH_PROCESSOR_KEY_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ key, py_arch_processor, \
+ "Provide the small name used to identify the architecture," \
+ " as a code string." \
+)
+
+ proc = G_ARCH_PROCESSOR(pygobject_get(self));
+ assert(proc != NULL);
+
+ key = g_arch_processor_get_key(proc);
+
+ if (key != NULL)
+ {
+ result = PyUnicode_FromString(key);
+ free(key);
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit le nom humain de l'architecture visée. *
+* *
+* Retour : Désignation humaine associée au processeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_arch_processor_get_desc(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GArchProcessor *proc; /* Version GLib de l'opérande */
+ char *desc; /* Désignation du processeur */
+
+#define ARCH_PROCESSOR_DESC_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ desc, py_arch_processor, \
+ "Provide a a human readable description of the new" \
+ " architecture, as a simple string." \
+)
+
+ proc = G_ARCH_PROCESSOR(pygobject_get(self));
+ assert(proc != NULL);
+
+ desc = g_arch_processor_get_desc(proc);
+
+ if (desc != NULL)
+ {
+ result = PyUnicode_FromString(desc);
+ free(desc);
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
* Description : Fournit le boustime du processeur d'une architecture. *
* *
* Retour : Boutisme associé au processeur. *
@@ -549,12 +869,19 @@ static PyObject *py_arch_processor_get_endianness(PyObject *self, void *closure)
GArchProcessor *proc; /* Version GLib de l'opérande */
SourceEndian endianness; /* Boutisme du processeur */
+#define ARCH_PROCESSOR_ENDIANNESS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ endianness, py_arch_processor, \
+ "Provide the processor endianness, as a" \
+ " pychrysalide.analysis.BinContent.SourceEndian value." \
+)
+
proc = G_ARCH_PROCESSOR(pygobject_get(self));
assert(proc != NULL);
endianness = g_arch_processor_get_endianness(proc);
- result = Py_BuildValue("I", endianness);
+ result = cast_with_constants_group_from_type(get_python_binary_content_type(), "SourceEndian", endianness);
return result;
@@ -580,12 +907,19 @@ static PyObject *py_arch_processor_get_memory_size(PyObject *self, void *closure
GArchProcessor *proc; /* Version GLib de l'opérande */
MemoryDataSize size; /* Type de donnée représentée */
+#define ARCH_PROCESSOR_MEMORY_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ memory_size, py_arch_processor, \
+ "Provide the size of the architecture memory address space," \
+ " as a pychrysalide.analysis.BinContent.MemoryDataSize value." \
+)
+
proc = G_ARCH_PROCESSOR(pygobject_get(self));
assert(proc != NULL);
size = g_arch_processor_get_memory_size(proc);
- result = Py_BuildValue("I", size);
+ result = cast_with_constants_group_from_type(get_python_binary_content_type(), "MemoryDataSize", size);
return result;
@@ -605,18 +939,25 @@ static PyObject *py_arch_processor_get_memory_size(PyObject *self, void *closure
* *
******************************************************************************/
-static PyObject *py_arch_processor_get_instruction_min_size(PyObject *self, void *closure)
+static PyObject *py_arch_processor_get_ins_min_size(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
GArchProcessor *proc; /* Version GLib de l'opérande */
MemoryDataSize size; /* Type de donnée représentée */
+#define ARCH_PROCESSOR_INS_MIN_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ ins_min_size, py_arch_processor, \
+ "Provide the minimal size of one processor instruction, as a" \
+ " pychrysalide.analysis.BinContent.MemoryDataSize value." \
+)
+
proc = G_ARCH_PROCESSOR(pygobject_get(self));
assert(proc != NULL);
size = g_arch_processor_get_instruction_min_size(proc);
- result = Py_BuildValue("I", size);
+ result = cast_with_constants_group_from_type(get_python_binary_content_type(), "MemoryDataSize", size);
return result;
@@ -642,6 +983,13 @@ static PyObject *py_arch_processor_has_virtual_space(PyObject *self, void *closu
GArchProcessor *proc; /* Architecture visée */
bool status; /* Bilan de consultation */
+#define ARCH_PROCESSOR_VIRTUAL_SPACE_ATTRIB PYTHON_HAS_DEF_FULL \
+( \
+ virtual_space, py_arch_processor, \
+ "Tell if the processor provides a virtual address space. This" \
+ " status is a boolean value." \
+)
+
proc = G_ARCH_PROCESSOR(pygobject_get(self));
status = g_arch_processor_has_virtual_space(proc);
@@ -1066,22 +1414,12 @@ PyTypeObject *get_python_arch_processor_type(void)
};
static PyGetSetDef py_arch_processor_getseters[] = {
- {
- "endianness", py_arch_processor_get_endianness, NULL,
- "Provide the processor endianness.", NULL
- },
- {
- "mem_size", py_arch_processor_get_memory_size, NULL,
- "Provide the size of memory addresses for the given architecture.", NULL
- },
- {
- "ins_min_size", py_arch_processor_get_instruction_min_size, NULL,
- "Provide the minimal size of one processor instruction.", NULL
- },
- {
- "virtual_space", py_arch_processor_has_virtual_space, NULL,
- "Tell if the processor provides a virtual address space.", NULL
- },
+ ARCH_PROCESSOR_KEY_ATTRIB,
+ ARCH_PROCESSOR_DESC_ATTRIB,
+ ARCH_PROCESSOR_ENDIANNESS_ATTRIB,
+ ARCH_PROCESSOR_MEMORY_SIZE_ATTRIB,
+ ARCH_PROCESSOR_INS_MIN_SIZE_ATTRIB,
+ ARCH_PROCESSOR_VIRTUAL_SPACE_ATTRIB,
{
"errors", py_arch_processor_get_errors, NULL,
"List of all detected errors which occurred during the disassembling process.", NULL
@@ -1102,7 +1440,7 @@ PyTypeObject *get_python_arch_processor_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide processor for a given architecture.",
+ .tp_doc = ARCH_PROCESSOR_DOC,
.tp_methods = py_arch_processor_methods,
.tp_getset = py_arch_processor_getseters,
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 924ba02..fe13f84 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -97,9 +97,12 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
closure \
}
-#define PYTHON_IS_DEF_FULL(name, base, doc) \
+#define PYTHON_IS_DEF_FULL(name, base, doc) \
PYTHON_GETSET_DEF("is_" #name, base ## _is_ ## name, NULL, doc, NULL)
+#define PYTHON_HAS_DEF_FULL(name, base, doc) \
+ PYTHON_GETSET_DEF(#name, base ## _has_ ## name, NULL, doc, NULL)
+
#define PYTHON_GET_DEF_FULL(name, base, doc) \
PYTHON_GETSET_DEF(#name, base ## _get_ ## name, NULL, doc, NULL)
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index e875679..0f7b096 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -1647,7 +1647,7 @@ static bool g_loaded_binary_analyze(GLoadedBinary *binary, bool connect, bool ca
bool result; /* Bilan à retourner */
GBinFormat *format; /* Format lié au binaire */
const char *arch; /* Architecture d'exécution */
- const char *desc; /* Description humaine associée*/
+ char *desc; /* Description humaine associée*/
bool has_virt; /* Présence de virtuel ? */
GProcContext *context; /* Contexte de suivi dédié */
GWidthTracker *tracker; /* Gestionnaire de largeur */
@@ -1690,6 +1690,8 @@ static bool g_loaded_binary_analyze(GLoadedBinary *binary, bool connect, bool ca
log_variadic_message(LMT_INFO, _("Detected architecture: %s"), desc);
+ free(desc);
+
g_signal_connect(binary->proc, "changed", G_CALLBACK(on_binary_processor_changed), binary);
has_virt = g_arch_processor_has_virtual_space(binary->proc);
diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h
index 34ba66a..6187ff0 100644
--- a/src/arch/processor-int.h
+++ b/src/arch/processor-int.h
@@ -36,6 +36,18 @@
/* Fournit la désignation interne du processeur d'architecture. */
typedef char * (* get_processor_key_fc) (const GArchProcessor *);
+/* Fournit le nom humain de l'architecture visée. */
+typedef char * (* get_processor_desc_fc) (const GArchProcessor *);
+
+/* Fournit la taille de l'espace mémoire d'une architecture. */
+typedef MemoryDataSize (* get_processor_memsize_fc) (const GArchProcessor *);
+
+/* Fournit la taille min. des instructions d'une architecture. */
+typedef MemoryDataSize (* get_processor_inssize_fc) (const GArchProcessor *);
+
+/* Indique si l'architecture possède un espace virtuel ou non. */
+typedef bool (* has_processor_vspace_fc) (const GArchProcessor *);
+
/* Fournit un contexte propre au processeur d'une architecture. */
typedef GProcContext * (* get_processor_context_fc) (const GArchProcessor *);
@@ -69,6 +81,8 @@ struct _GArchProcessor
{
GObject parent; /* A laisser en premier */
+ SourceEndian endianness; /* Boutisme de l'architecture */
+
GArchInstruction **instructions; /* Instructions désassemblées */
size_t instr_count; /* Taille de la liste aplatie */
unsigned int stamp; /* Marque de suivi des modifs */
@@ -95,16 +109,13 @@ struct _GArchProcessorClass
{
GObjectClass parent; /* A laisser en premier */
- const char *desc; /* Description humaine liée */
-
- SourceEndian endianness; /* Boutisme de l'architecture */
- MemoryDataSize memsize; /* Taille de l'espace mémoire */
- MemoryDataSize inssize; /* Taille min. d'encodage */
- bool virt_space; /* Présence d'espace virtuel ? */
-
get_processor_key_fc get_key; /* Code représentant la classe */
- get_processor_context_fc get_ctx; /* Obtention d'un contexte */
+ get_processor_desc_fc get_desc; /* Description humaine */
+ get_processor_memsize_fc get_memsize; /* Taille d'un mot classique */
+ get_processor_inssize_fc get_inssize; /* Taille minimale d'instruct° */
+ has_processor_vspace_fc has_vspace; /* Présence d'un espace virtuel*/
+ get_processor_context_fc get_ctx; /* Obtention d'un contexte */
disass_instr_fc disassemble; /* Traduction en instructions */
/* Signaux */
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 7dbd8eb..59af6cd 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -290,7 +290,10 @@ char *g_arch_processor_get_key(const GArchProcessor *proc)
class = G_ARCH_PROCESSOR_GET_CLASS(proc);
if (class->get_key == NULL)
+ {
+ assert(false);
result = NULL;
+ }
else
result = class->get_key(proc);
@@ -312,14 +315,21 @@ char *g_arch_processor_get_key(const GArchProcessor *proc)
* *
******************************************************************************/
-const char *g_arch_processor_get_desc(const GArchProcessor *proc)
+char *g_arch_processor_get_desc(const GArchProcessor *proc)
{
- const char *result; /* Désignation à renvoyer */
+ char *result; /* Désignation à renvoyer */
GArchProcessorClass *class; /* Classe de l'instance */
class = G_ARCH_PROCESSOR_GET_CLASS(proc);
- result = class->desc;
+ if (class->get_desc == NULL)
+ {
+ assert(false);
+ result = NULL;
+ }
+
+ else
+ result = class->get_desc(proc);
return result;
@@ -341,11 +351,8 @@ const char *g_arch_processor_get_desc(const GArchProcessor *proc)
SourceEndian g_arch_processor_get_endianness(const GArchProcessor *proc)
{
SourceEndian result; /* Boutisme à retourner */
- GArchProcessorClass *class; /* Classe de l'instance */
- class = G_ARCH_PROCESSOR_GET_CLASS(proc);
-
- result = class->endianness;
+ result = proc->endianness;
return result;
@@ -371,7 +378,14 @@ MemoryDataSize g_arch_processor_get_memory_size(const GArchProcessor *proc)
class = G_ARCH_PROCESSOR_GET_CLASS(proc);
- result = class->memsize;
+ if (class->get_memsize == NULL)
+ {
+ assert(false);
+ result = MDS_UNDEFINED;
+ }
+
+ else
+ result = class->get_memsize(proc);
return result;
@@ -397,7 +411,14 @@ MemoryDataSize g_arch_processor_get_instruction_min_size(const GArchProcessor *p
class = G_ARCH_PROCESSOR_GET_CLASS(proc);
- result = class->inssize;
+ if (class->get_inssize == NULL)
+ {
+ assert(false);
+ result = MDS_UNDEFINED;
+ }
+
+ else
+ result = class->get_inssize(proc);
return result;
@@ -423,7 +444,14 @@ bool g_arch_processor_has_virtual_space(const GArchProcessor *proc)
class = G_ARCH_PROCESSOR_GET_CLASS(proc);
- result = class->virt_space;
+ if (class->has_vspace == NULL)
+ {
+ assert(false);
+ result = false;
+ }
+
+ else
+ result = class->has_vspace(proc);
return result;
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 7edf341..b88fa6f 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -59,7 +59,7 @@ GType g_arch_processor_get_type(void);
char *g_arch_processor_get_key(const GArchProcessor *);
/* Fournit le nom humain de l'architecture visée. */
-const char *g_arch_processor_get_desc(const GArchProcessor *);
+char *g_arch_processor_get_desc(const GArchProcessor *);
/* Fournit le boustime du processeur d'une architecture. */
SourceEndian g_arch_processor_get_endianness(const GArchProcessor *);
diff --git a/src/core/processors.c b/src/core/processors.c
index 7234365..48e2cd2 100644
--- a/src/core/processors.c
+++ b/src/core/processors.c
@@ -108,9 +108,6 @@ bool register_processor_type(GType type)
key = g_arch_processor_get_key(proc);
if (key == NULL) goto done;
- result = (key != NULL);
-
-
G_LOCK(_pdef_access);
new = find_processor_by_key(key);