diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-04-21 18:44:33 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-04-21 18:44:33 (GMT) |
commit | cd54168f9877ed4ee16ee1e25c72e8338eed7928 (patch) | |
tree | 04dc1a85a28ff8a95eaaa6a0bbd5909ea2dc6397 /plugins | |
parent | 3dada5fbc27777217625603905727364a0cc996d (diff) |
Redefined the interface for creating new processors from Python.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/arm/processor.c | 31 | ||||
-rw-r--r-- | plugins/arm/v7/processor.c | 93 | ||||
-rw-r--r-- | plugins/dalvik/processor.c | 86 | ||||
-rw-r--r-- | plugins/dalvik/v35/processor.c | 29 | ||||
-rw-r--r-- | plugins/pychrysalide/analysis/constants.c | 5 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/processor.c | 428 | ||||
-rw-r--r-- | plugins/pychrysalide/helpers.h | 5 |
7 files changed, 616 insertions, 61 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) |