From cd54168f9877ed4ee16ee1e25c72e8338eed7928 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 21 Apr 2020 20:44:33 +0200 Subject: Redefined the interface for creating new processors from Python. --- plugins/arm/processor.c | 31 +++ plugins/arm/v7/processor.c | 93 ++++++- plugins/dalvik/processor.c | 86 +++++- plugins/dalvik/v35/processor.c | 29 +- plugins/pychrysalide/analysis/constants.c | 5 + plugins/pychrysalide/arch/processor.c | 428 ++++++++++++++++++++++++++---- plugins/pychrysalide/helpers.h | 5 +- src/analysis/binary.c | 4 +- src/arch/processor-int.h | 27 +- src/arch/processor.c | 48 +++- src/arch/processor.h | 2 +- src/core/processors.c | 3 - 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); -- cgit v0.11.2-87-g4458