diff options
Diffstat (limited to 'plugins/pychrysalide/arch')
-rw-r--r-- | plugins/pychrysalide/arch/processor.c | 20 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/vmpa.c | 313 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/vmpa.h | 3 |
3 files changed, 175 insertions, 161 deletions
diff --git a/plugins/pychrysalide/arch/processor.c b/plugins/pychrysalide/arch/processor.c index f356a91..c356fa4 100644 --- a/plugins/pychrysalide/arch/processor.c +++ b/plugins/pychrysalide/arch/processor.c @@ -645,28 +645,22 @@ static PyObject *py_arch_processor_disassemble(PyObject *self, PyObject *args) PyObject *result; /* Instance à retourner */ GProcContext *ctx; /* Contexte de désassemblage */ GBinContent *content; /* Contenu binaire à parcourir */ - PyObject *pypos; /* Position en objet Python */ + vmpa2t *addr; /* Position d'analyse courante */ GExeFormat *format; /* Format de fichier associé */ int ret; /* Bilan de lecture des args. */ - vmpa2t pos; /* Position d'analyse courante */ GArchProcessor *proc; /* Processeur manipulé */ GArchInstruction *instr; /* Instruction mise en place */ ret = PyArg_ParseTuple(args, "O&O&OO&", convert_to_proc_context, &ctx, convert_to_binary_content, &content, - &pypos, + convert_any_to_vmpa, &addr, convert_to_executable_format, &format); if (!ret) return NULL; - ret = convert_any_to_vmpa(pypos, &pos); - if (ret != 1) return NULL; - proc = G_ARCH_PROCESSOR(pygobject_get(self)); - instr = g_arch_processor_disassemble(proc, ctx, content, &pos, format); - - copy_vmpa(get_internal_vmpa(pypos), &pos); + instr = g_arch_processor_disassemble(proc, ctx, content, addr, format); if (instr != NULL) { @@ -679,6 +673,8 @@ static PyObject *py_arch_processor_disassemble(PyObject *self, PyObject *args) Py_INCREF(result); } + clean_vmpa_arg(addr); + return result; } @@ -706,7 +702,7 @@ static PyObject *py_arch_processor_disassemble(PyObject *self, PyObject *args) static PyObject *py_arch_processor_add_error(PyObject *self, PyObject *args) { ArchProcessingError type; /* Type d'erreur détectée */ - vmpa2t addr; /* Position d'une erreur */ + vmpa2t *addr; /* Position d'une erreur */ const char *desc; /* Description d'une erreur */ int ret; /* Bilan de lecture des args. */ GArchProcessor *proc; /* Processeur manipulé */ @@ -716,7 +712,9 @@ static PyObject *py_arch_processor_add_error(PyObject *self, PyObject *args) proc = G_ARCH_PROCESSOR(pygobject_get(self)); - g_arch_processor_add_error(proc, type, &addr, desc); + g_arch_processor_add_error(proc, type, addr, desc); + + clean_vmpa_arg(addr); Py_RETURN_NONE; diff --git a/plugins/pychrysalide/arch/vmpa.c b/plugins/pychrysalide/arch/vmpa.c index aa745cf..af4821d 100644 --- a/plugins/pychrysalide/arch/vmpa.c +++ b/plugins/pychrysalide/arch/vmpa.c @@ -26,10 +26,13 @@ #include <assert.h> +#include <malloc.h> +#include <stddef.h> #include <string.h> #include <i18n.h> +#include <common/macros.h> #include "constants.h" @@ -38,26 +41,22 @@ - - - - - - /* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */ - +/* Encapsulation d'une localisation */ typedef struct _py_vmpa_t { - PyObject_HEAD + PyObject_HEAD /* Préambule Python */ - vmpa2t addr; + vmpa2t addr; /* Elément natif */ + bool tmp_arg; /* Nature de l'objet Python */ } py_vmpa_t; - +/* Initialise un objet Python de type 'vmpa2t'. */ +static int py_vmpa_init(py_vmpa_t *, PyObject *, PyObject *); /* Fournit une représentation d'une variable 'vmpa_t'. */ static PyObject *py_vmpa_to_str(PyObject *); @@ -71,33 +70,30 @@ static PyObject *py_vmpa_get_value(PyObject *, void *); /* Définit une partie du contenu de la position représentée. */ static int py_vmpa_set_value(PyObject *, PyObject *, void *); -/* Initialise un objet Python de type 'vmpa2t'. */ -static int py_vmpa_init(py_vmpa_t *, PyObject *, PyObject *); - /* Effectue une conversion d'un objet Python en type 'vmpa_t'. */ static bool convert_pyobj_to_vmpa(PyObject *, vmpa2t *); /* Effectue une opération de type 'add' avec le type 'vmpa'. */ static PyObject *py_vmpa_nb_add(PyObject *, PyObject *); -/* Définit les constantes pour les localisations. */ -static bool py_vmpa_define_constants(PyTypeObject *); - /* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ -/* Couverture mémoire */ +/* Encapsulation d'une couverture mémoire */ typedef struct _py_mrange_t { PyObject_HEAD /* Préambule Python */ - mrange_t range; /* Informations internes */ + mrange_t range; /* Elément natif */ } py_mrange_t; +/* Initialise un objet Python de type 'mrange_t'. */ +static int py_mrange_init(py_mrange_t *, PyObject *, PyObject *); + /* Fournit une représentation d'une variable 'mrange_t'. */ static PyObject *py_mrange_to_str(PyObject *); @@ -131,20 +127,66 @@ static PyObject *py_mrange_get_end_addr(PyObject *, void *); -/* Initialise un objet Python de type 'mrange_t'. */ -static int py_mrange_init(py_mrange_t *, PyObject *, PyObject *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UNE POSITION EN MEMOIRE */ +/* ---------------------------------------------------------------------------------- */ +/****************************************************************************** +* * +* Paramètres : self = instance d'objet à initialiser. * +* args = arguments passés pour l'appel. * +* kwds = mots clefs éventuellement fournis en complément. * +* * +* Description : Initialise un objet Python de type 'vmpa2t'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +static int py_vmpa_init(py_vmpa_t *self, PyObject *args, PyObject *kwds) +{ + int result; /* Bilan à retourner */ + unsigned long long phy; /* Position physique */ + unsigned long long virt; /* Adresse en mémoire virtuelle*/ + int ret; /* Bilan de lecture des args. */ +#define VMPA_DOC \ + "VMPA stands for Virtual Memory or Physical Address.\n" \ + "\n" \ + "Thus vmpa objects are locations inside a binary content. Their" \ + " coordinates are composed of a physical offset and a virtual address." \ + " Both of them can be undefined thanks to special values" \ + " pychrysalide.arch.vmpa.VmpaSpecialValue." \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " vmpa(phys=NO_PHYSICAL, virt=NO_VIRTUAL)" \ + "\n" \ + "Where phys and virt are the values of the physical and virtual" \ + " positions for the location." + result = -1; + phy = VMPA_NO_PHYSICAL; + virt = VMPA_NO_VIRTUAL; -/* ---------------------------------------------------------------------------------- */ -/* DEFINITION D'UNE POSITION EN MEMOIRE */ -/* ---------------------------------------------------------------------------------- */ + ret = PyArg_ParseTuple(args, "|KK", &phy, &virt); + if (!ret) goto exit; + + init_vmpa(&self->addr, phy, virt); + self->tmp_arg = false; + result = 0; + + exit: + + return result; + +} /****************************************************************************** @@ -380,48 +422,6 @@ static int py_vmpa_set_value(PyObject *self, PyObject *value, void *closure) /****************************************************************************** * * -* Paramètres : self = instance d'objet à initialiser. * -* args = arguments passés pour l'appel. * -* kwds = mots clefs éventuellement fournis en complément. * -* * -* Description : Initialise un objet Python de type 'vmpa2t'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_vmpa_init(py_vmpa_t *self, PyObject *args, PyObject *kwds) -{ - int result; /* Bilan à retourner */ - unsigned long long phy; /* Position physique */ - unsigned long long virt; /* Adresse en mémoire virtuelle*/ - int ret; /* Bilan de lecture des args. */ - - result = -1; - - phy = VMPA_NO_PHYSICAL; - virt = VMPA_NO_VIRTUAL; - - ret = PyArg_ParseTuple(args, "|KK", &phy, &virt); - if (!ret) goto exit; - - init_vmpa(&self->addr, phy, virt); - - result = 0; - - exit: - - return result; - -} - - - - -/****************************************************************************** -* * * Paramètres : obj = objet Python à tenter de convertir. * * addr = structure équivalente pour Chrysalide. * * * @@ -521,32 +521,6 @@ static PyObject *py_vmpa_nb_add(PyObject *o1, PyObject *o2) /****************************************************************************** * * -* Paramètres : obj_type = type dont le dictionnaire est à compléter. * -* * -* Description : Définit les constantes pour les localisations. * -* * -* Retour : true en cas de succès de l'opération, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool py_vmpa_define_constants(PyTypeObject *obj_type) -{ - bool result; /* Bilan à retourner */ - - result = true; - - if (result) result = PyDict_AddULongMacro(obj_type, VMPA_NO_PHYSICAL); - if (result) result = PyDict_AddULongMacro(obj_type, VMPA_NO_VIRTUAL); - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -634,7 +608,7 @@ PyTypeObject *get_python_vmpa_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "Python object for vmpa_t.", + .tp_doc = VMPA_DOC, .tp_richcompare = py_vmpa_richcompare, @@ -674,9 +648,6 @@ bool ensure_python_vmpa_is_registered(void) if (PyType_Ready(type) != 0) return false; - if (!py_vmpa_define_constants(type)) - return false; - module = get_access_to_python_module("pychrysalide.arch"); if (!register_python_module_object(module, type)) @@ -763,24 +734,42 @@ PyObject *build_from_internal_vmpa(const vmpa2t *addr) int convert_any_to_vmpa(PyObject *arg, void *dst) { int result; /* Bilan à retourner */ +#ifndef NDEBUG + py_vmpa_t *self; /* Objet Python alloué */ +#endif int ret; /* Test intermédiaire */ - vmpa2t *src; /* Modèle de données à copier */ PY_LONG_LONG value; /* Valeur de type générique */ int overflow; /* Détection d'une grosse val. */ + py_vmpa_t *tmp; /* Objet creux temporaire */ result = 0; + /* Nettoyage en cours ? */ + + if (arg == NULL) + { +#ifndef NDEBUG + self = container_of(*(vmpa2t **)dst, py_vmpa_t, addr); + assert(self->tmp_arg); +#endif + + clean_vmpa_arg(*(vmpa2t **)dst); + + result = 1; + goto done; + + } + /* Si l'objet est au bon format, rien à faire ! */ ret = PyObject_IsInstance(arg, (PyObject *)get_python_vmpa_type()); if (ret == 1) { - src = get_internal_vmpa(arg); - copy_vmpa((vmpa2t *)dst, src); + *((vmpa2t **)dst) = get_internal_vmpa(arg); result = 1; - goto catv_done; + goto done; } @@ -793,31 +782,100 @@ int convert_any_to_vmpa(PyObject *arg, void *dst) else { - init_vmpa((vmpa2t *)dst, VMPA_NO_PHYSICAL, value); + tmp = malloc(sizeof(py_vmpa_t)); - result = 1; - goto catv_done; + init_vmpa(&tmp->addr, VMPA_NO_PHYSICAL, value); + + tmp->tmp_arg = true; + + *((vmpa2t **)dst) = &tmp->addr; + + result = Py_CLEANUP_SUPPORTED; + goto done; } PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to vmpa"); - catv_done: + done: return result; } +/****************************************************************************** +* * +* Paramètres : addr = localisation obtenue par lecture d'argument. * +* * +* Description : Libère la mémoire allouée pour un passage d'argument. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void clean_vmpa_arg(vmpa2t *addr) +{ + py_vmpa_t *self; /* Objet Python alloué */ + + self = container_of(addr, py_vmpa_t, addr); + + if (self->tmp_arg) + free(self); + +} + + /* ---------------------------------------------------------------------------------- */ /* DEFINITION D'UNE ZONE EN MEMOIRE */ /* ---------------------------------------------------------------------------------- */ +/****************************************************************************** +* * +* Paramètres : self = instance d'objet à initialiser. * +* args = arguments passés pour l'appel. * +* kwds = mots clefs éventuellement fournis en complément. * +* * +* Description : Initialise un objet Python de type 'mrange_t'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +static int py_mrange_init(py_mrange_t *self, PyObject *args, PyObject *kwds) +{ + int result; /* Bilan à retourner */ + PyObject *py_vmpa; /* Localisation version Python */ + unsigned long long length; /* Taille physique */ + int ret; /* Bilan de lecture des args. */ + vmpa2t *addr; /* Localisation version C */ + result = -1; + ret = PyArg_ParseTuple(args, "OK", &py_vmpa, &length); + if (!ret) goto exit; + + ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type()); + if (!ret) goto exit; + + addr = get_internal_vmpa(py_vmpa); + if (addr == NULL) goto exit; + + init_mrange(&self->range, addr, length); + + result = 0; + + exit: + + return result; + +} /****************************************************************************** @@ -1130,51 +1188,6 @@ static PyObject *py_mrange_get_end_addr(PyObject *self, void *closure) -/****************************************************************************** -* * -* Paramètres : self = instance d'objet à initialiser. * -* args = arguments passés pour l'appel. * -* kwds = mots clefs éventuellement fournis en complément. * -* * -* Description : Initialise un objet Python de type 'mrange_t'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_mrange_init(py_mrange_t *self, PyObject *args, PyObject *kwds) -{ - int result; /* Bilan à retourner */ - PyObject *py_vmpa; /* Localisation version Python */ - unsigned long long length; /* Taille physique */ - int ret; /* Bilan de lecture des args. */ - vmpa2t *addr; /* Localisation version C */ - - result = -1; - - ret = PyArg_ParseTuple(args, "OK", &py_vmpa, &length); - if (!ret) goto exit; - - ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type()); - if (!ret) goto exit; - - addr = get_internal_vmpa(py_vmpa); - if (addr == NULL) goto exit; - - init_mrange(&self->range, addr, length); - - result = 0; - - exit: - - return result; - -} - - - @@ -1379,13 +1392,13 @@ int convert_any_to_mrange(PyObject *arg, void *dst) copy_mrange((mrange_t *)dst, src); result = 1; - goto catm_done; + goto done; } PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to mrange"); - catm_done: + done: return result; diff --git a/plugins/pychrysalide/arch/vmpa.h b/plugins/pychrysalide/arch/vmpa.h index 9b5ee7a..526283d 100644 --- a/plugins/pychrysalide/arch/vmpa.h +++ b/plugins/pychrysalide/arch/vmpa.h @@ -49,6 +49,9 @@ PyObject *build_from_internal_vmpa(const vmpa2t *); /* Tente de convertir en adresse n'importe quoi. */ int convert_any_to_vmpa(PyObject *, void *); +/* Libère la mémoire allouée pour un passage d'argument. */ +void clean_vmpa_arg(vmpa2t *); + /* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ |