summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/arch
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/arch')
-rw-r--r--plugins/pychrysalide/arch/processor.c20
-rw-r--r--plugins/pychrysalide/arch/vmpa.c313
-rw-r--r--plugins/pychrysalide/arch/vmpa.h3
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 ------------------------ */