diff options
Diffstat (limited to 'plugins/pychrysalide/arch')
-rw-r--r-- | plugins/pychrysalide/arch/processor.c | 428 |
1 files changed, 383 insertions, 45 deletions
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, |