From 14d17285cdfae2fe6bd7df0e873ef11ef876e12c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 19 Apr 2019 22:55:58 +0200 Subject: Restricted instructions iterators to get routine contents. --- plugins/pychrysalide/arch/instriter.c | 96 ++++++++++++++++++++++++++++++----- plugins/pychrysalide/arch/processor.c | 45 ++++++++++++++++ plugins/pychrysalide/arch/processor.h | 3 ++ plugins/pychrysalide/arch/vmpa.c | 44 ++++++++++++++++ plugins/pychrysalide/arch/vmpa.h | 3 ++ src/arch/instriter.c | 10 ++++ 6 files changed, 189 insertions(+), 12 deletions(-) diff --git a/plugins/pychrysalide/arch/instriter.c b/plugins/pychrysalide/arch/instriter.c index bb1e1a3..381f967 100644 --- a/plugins/pychrysalide/arch/instriter.c +++ b/plugins/pychrysalide/arch/instriter.c @@ -28,10 +28,12 @@ #include +#include #include #include "processor.h" +#include "vmpa.h" #include "../access.h" #include "../helpers.h" @@ -54,6 +56,9 @@ static void py_instr_iterator_dealloc(PyInstrIterator *); /* Fournit l'instruction qui en suit une autre. */ static PyObject *py_instr_iterator_next(PyInstrIterator *); +/* Limite le parcours des instructions à une zone donnée. */ +static PyObject *py_instr_iterator_restrict(PyObject *, PyObject *); + /* Initialise un nouvel itérateur. */ static int py_instr_iterator_init(PyInstrIterator *, PyObject *, PyObject *); @@ -140,27 +145,51 @@ static PyObject *py_instr_iterator_next(PyInstrIterator *self) static int py_instr_iterator_init(PyInstrIterator *self, PyObject *args, PyObject *kwds) { int result; /* Bilan à retourner */ - PyObject *proc_obj; /* Processeur version Python */ - unsigned long index; /* Indice de première instruc. */ - int ret; /* Bilan de lecture des args. */ GArchProcessor *proc; /* Version native du processeur*/ + PyObject *start; /* Position de départ */ + int ret; /* Bilan de lecture des args. */ + PyTypeObject *py_vmpa_type; /* Type Python pour 'vmpa' */ + PY_LONG_LONG index; /* Indice de première instruc. */ + int overflow; /* Détection d'une grosse val. */ result = -1; - ret = PyArg_ParseTuple(args, "Ok", &proc_obj, &index); - if (ret == 0) goto piii_exit; + ret = PyArg_ParseTuple(args, "O&O", convert_to_arch_processor, &proc, &start); + if (!ret) goto exit; - ret = PyObject_IsInstance(proc_obj, (PyObject *)get_python_arch_processor_type()); - if (!ret) goto piii_exit; + py_vmpa_type = get_python_vmpa_type(); - proc = G_ARCH_PROCESSOR(pygobject_get(proc_obj)); + ret = PyObject_IsInstance(start, (PyObject *)py_vmpa_type); - self->native = create_instruction_iterator(proc, index); - self->first_time = true; + /* Si l'argument est une adresse... */ + if (ret == 1) + { + self->native = g_arch_processor_get_iter_from_address(proc, get_internal_vmpa(start)); + result = 0; + } + + /* Si l'argument est un indice... */ + else + { + index = PyLong_AsLongLongAndOverflow(start, &overflow); - result = 0; + if (index == -1 && (overflow == 1 || PyErr_Occurred())) + { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, _("Unable to cast object as index.")); + } - piii_exit: + else + { + self->native = create_instruction_iterator(proc, index); + result = 0; + } + + } + + self->first_time = true; + + exit: return result; @@ -169,6 +198,39 @@ static int py_instr_iterator_init(PyInstrIterator *self, PyObject *args, PyObjec /****************************************************************************** * * +* Paramètres : self = itérateur d'instructions à manipuler. * +* args = bornes de l'espace de parcours. * +* * +* Description : Limite le parcours des instructions à une zone donnée. * +* * +* Retour : Itérateur mis à jour. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_instr_iterator_restrict(PyObject *self, PyObject *args) +{ + mrange_t range; /* Espace mémoire fourni */ + int ret; /* Bilan de lecture des args. */ + PyInstrIterator *iter; /* Autre version d'objet */ + + ret = PyArg_ParseTuple(args, "O&", convert_any_to_mrange, &range); + if (!ret) return NULL; + + iter = (PyInstrIterator *)self; + + restrict_instruction_iterator(iter->native, &range); + + Py_INCREF(self); + + return self; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -181,6 +243,15 @@ static int py_instr_iterator_init(PyInstrIterator *self, PyObject *args, PyObjec PyTypeObject *get_python_instr_iterator_type(void) { + static PyMethodDef py_instr_iterator_methods[] = { + { + "restrict", py_instr_iterator_restrict, + METH_VARARGS, + "restrict($self, range, /)\n--\n\nLimit the instruction iterator to a memory range." + }, + { NULL } + }; + static PyTypeObject py_instr_iterator_type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -197,6 +268,7 @@ PyTypeObject *get_python_instr_iterator_type(void) .tp_iter = PyObject_SelfIter, .tp_iternext = (iternextfunc)py_instr_iterator_next, + .tp_methods = py_instr_iterator_methods, .tp_init = (initproc)py_instr_iterator_init, .tp_new = PyType_GenericNew, diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c index 78109ee..94ba7df 100644 --- a/plugins/pychrysalide/arch/processor.c +++ b/plugins/pychrysalide/arch/processor.c @@ -1087,6 +1087,51 @@ bool ensure_python_arch_processor_is_registered(void) } +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en processeur d'architecture. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_arch_processor(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_arch_processor_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to arch processor"); + break; + + case 1: + *((GArchProcessor **)dst) = G_ARCH_PROCESSOR(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* TRADUCTION D'EMPLACEMENT */ diff --git a/plugins/pychrysalide/arch/processor.h b/plugins/pychrysalide/arch/processor.h index 22331fc..c824f5e 100644 --- a/plugins/pychrysalide/arch/processor.h +++ b/plugins/pychrysalide/arch/processor.h @@ -43,6 +43,9 @@ PyTypeObject *get_python_arch_processor_type(void); /* Prend en charge l'objet 'pychrysalide.arch.ArchProcessor'. */ bool ensure_python_arch_processor_is_registered(void); +/* Tente de convertir en processeur d'architecture. */ +int convert_to_arch_processor(PyObject *, void *); + /* ---------------------------- TRADUCTION D'EMPLACEMENT ---------------------------- */ diff --git a/plugins/pychrysalide/arch/vmpa.c b/plugins/pychrysalide/arch/vmpa.c index b042a9f..015687f 100644 --- a/plugins/pychrysalide/arch/vmpa.c +++ b/plugins/pychrysalide/arch/vmpa.c @@ -1342,3 +1342,47 @@ PyObject *build_from_internal_mrange(const mrange_t *range) return result; } + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en espace mémoire n'importe quoi. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_any_to_mrange(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + int ret; /* Test intermédiaire */ + mrange_t *src; /* Modèle de données à copier */ + + result = 0; + + /* Si l'objet est au bon format, rien à faire ! */ + + ret = PyObject_IsInstance(arg, (PyObject *)get_python_mrange_type()); + + if (ret == 1) + { + src = get_internal_mrange(arg); + copy_mrange((mrange_t *)dst, src); + + result = 1; + goto catm_done; + + } + + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to mrange"); + + catm_done: + + return result; + +} diff --git a/plugins/pychrysalide/arch/vmpa.h b/plugins/pychrysalide/arch/vmpa.h index 7705a10..9b5ee7a 100644 --- a/plugins/pychrysalide/arch/vmpa.h +++ b/plugins/pychrysalide/arch/vmpa.h @@ -66,6 +66,9 @@ mrange_t *get_internal_mrange(PyObject *); /* Convertit une structure de type 'mrange_t' en objet Python. */ PyObject *build_from_internal_mrange(const mrange_t *); +/* Tente de convertir en espace mémoire n'importe quoi. */ +int convert_any_to_mrange(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_ARCH_VMPA_H */ diff --git a/src/arch/instriter.c b/src/arch/instriter.c index d968ba8..a603383 100644 --- a/src/arch/instriter.c +++ b/src/arch/instriter.c @@ -150,6 +150,16 @@ void delete_instruction_iterator(instr_iter_t *iter) void restrict_instruction_iterator(instr_iter_t *iter, const mrange_t *range) { + instr_iter_t *new; /* Itérateur actualisé */ + + new = g_arch_processor_get_iter_from_address(iter->proc, get_mrange_addr(range)); + + if (new) + { + iter->index = new->index; + delete_instruction_iterator(new); + } + copy_mrange(&iter->restriction, range); iter->is_restricted = true; -- cgit v0.11.2-87-g4458