From e957ec4ff043f6025d6a993bb6e97fe7d57a8bd6 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 13 Dec 2018 23:55:39 +0100 Subject: Extended the Python API for code blocks. --- plugins/pychrysalide/analysis/block.c | 139 ++++++++++++++++++++++++--- plugins/pychrysalide/analysis/disass/block.c | 44 ++++++++- 2 files changed, 171 insertions(+), 12 deletions(-) diff --git a/plugins/pychrysalide/analysis/block.c b/plugins/pychrysalide/analysis/block.c index a091a6d..563b4d2 100644 --- a/plugins/pychrysalide/analysis/block.c +++ b/plugins/pychrysalide/analysis/block.c @@ -46,6 +46,12 @@ static PyObject *py_code_block_get_index(PyObject *, void *); /* Fournit le rang du bloc de code dans le flot d'exécution. */ static PyObject *py_code_block_get_rank(PyObject *, void *); +/* Fournit les détails d'une source de bloc de code. */ +static PyObject *py_code_block_get_sources(PyObject *, void *); + +/* Fournit les détails des destinations de bloc de code. */ +static PyObject *py_code_block_get_destinations(PyObject *, void *); + /* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */ @@ -54,8 +60,8 @@ static PyObject *py_code_block_get_rank(PyObject *, void *); /* Recherche un bloc de code débutant à une adresse donnée. */ static PyObject *py_block_list_find_by_starting_addr(PyObject *, PyObject *); -/* Fournit l'ensemble des blocs de code inclus dans une liste. */ -static PyObject *py_block_list_get_items(PyObject *, void *); +/* Itère sur l'ensemble des blocs de code inclus dans une liste. */ +static PyObject *py_block_list_iter(PyObject *); @@ -126,6 +132,110 @@ static PyObject *py_code_block_get_rank(PyObject *self, void *closure) /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit les détails d'une source de bloc de code. * +* * +* Retour : Liens déterminés vers des bloc de code de source. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_code_block_get_sources(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GCodeBlock *block; /* Bloc de code à consulter */ + size_t count; /* Quantité de blocs liés */ + size_t i; /* Boucle de parcours */ + const block_link_t *link; /* Informations conservées */ + PyObject *info; /* Informations à transmettre */ + + block = G_CODE_BLOCK(pygobject_get(self)); + + g_code_block_lock_src(block); + + count = g_code_block_count_sources(block); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + link = g_code_block_get_source(block, i); + + info = PyTuple_New(2); + + PyTuple_SetItem(info, 0, pygobject_new(G_OBJECT(link->linked))); + PyTuple_SetItem(info, 1, PyLong_FromUnsignedLong(link->type)); + + PyTuple_SetItem(result, i, info); + + unref_block_link(link); + + } + + g_code_block_unlock_src(block); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit les détails des destinations de bloc de code. * +* * +* Retour : Liens déterminés vers des bloc de code de destination. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_code_block_get_destinations(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GCodeBlock *block; /* Bloc de code à consulter */ + size_t count; /* Quantité de blocs liés */ + size_t i; /* Boucle de parcours */ + const block_link_t *link; /* Informations conservées */ + PyObject *info; /* Informations à transmettre */ + + block = G_CODE_BLOCK(pygobject_get(self)); + + g_code_block_lock_dest(block); + + count = g_code_block_count_destinations(block); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + link = g_code_block_get_destination(block, i); + + info = PyTuple_New(2); + + PyTuple_SetItem(info, 0, pygobject_new(G_OBJECT(link->linked))); + PyTuple_SetItem(info, 1, PyLong_FromUnsignedLong(link->type)); + + PyTuple_SetItem(result, i, info); + + unref_block_link(link); + + } + + g_code_block_unlock_dest(block); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -151,6 +261,14 @@ PyTypeObject *get_python_code_block_type(void) "rank", py_code_block_get_rank, NULL, "Rang of the code block.", NULL }, + { + "sources", py_code_block_get_sources, NULL, + "List of source blocks.", NULL + }, + { + "destinations", py_code_block_get_destinations, NULL, + "List of destination blocks.", NULL + }, { NULL } }; @@ -262,18 +380,17 @@ static PyObject *py_block_list_find_by_starting_addr(PyObject *self, PyObject *a /****************************************************************************** * * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * +* Paramètres : self = objet Python concerné par l'appel. * * * -* Description : Fournit l'ensemble des blocs de code inclus dans une liste. * +* Description : Itère sur l'ensemble des blocs de code inclus dans une liste.* * * -* Retour : Liste de blocs de code. * +* Retour : Liste de blocs de code capable d'itération. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_block_list_get_items(PyObject *self, void *closure) +static PyObject *py_block_list_iter(PyObject *self) { PyObject *result; /* Trouvailles à retourner */ GBlockList *list; /* Liste de blocs manipulée */ @@ -297,6 +414,8 @@ static PyObject *py_block_list_get_items(PyObject *self, void *closure) } + result = PySeqIter_New(result); + return result; } @@ -326,10 +445,6 @@ PyTypeObject *get_python_block_list_type(void) }; static PyGetSetDef py_block_list_getseters[] = { - { - "items", py_block_list_get_items, NULL, - "All code blocks included in the list.", NULL - }, { NULL } }; @@ -343,6 +458,8 @@ PyTypeObject *get_python_block_list_type(void) .tp_doc = "PyChrysalide basic block", + .tp_iter = py_block_list_iter, + .tp_methods = py_block_list_methods, .tp_getset = py_block_list_getseters, diff --git a/plugins/pychrysalide/analysis/disass/block.c b/plugins/pychrysalide/analysis/disass/block.c index 6855368..38e65a1 100644 --- a/plugins/pychrysalide/analysis/disass/block.c +++ b/plugins/pychrysalide/analysis/disass/block.c @@ -40,7 +40,8 @@ /* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */ - +/* Fournit les instructions limites d'un bloc basique. */ +static PyObject *py_basic_block_get_boundaries(PyObject *, void *); @@ -51,6 +52,43 @@ /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit les instructions limites d'un bloc basique. * +* * +* Retour : Première et dernière instructions du bloc. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_basic_block_get_boundaries(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GBasicBlock *block; /* Bloc de code à consulter */ + GArchInstruction *first; /* Première instruction de bloc*/ + GArchInstruction *last; /* Dernière instruction de bloc*/ + + block = G_BASIC_BLOCK(pygobject_get(self)); + + g_basic_block_get_boundaries(block, &first, &last); + + result = PyTuple_New(2); + + PyTuple_SetItem(result, 0, pygobject_new(G_OBJECT(first))); + PyTuple_SetItem(result, 1, pygobject_new(G_OBJECT(last))); + + g_object_unref(G_OBJECT(first)); + g_object_unref(G_OBJECT(last)); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -68,6 +106,10 @@ PyTypeObject *get_python_basic_block_type(void) }; static PyGetSetDef py_basic_block_getseters[] = { + { + "boundaries", py_basic_block_get_boundaries, NULL, + "First and last instructions of the basic block.", NULL + }, { NULL } }; -- cgit v0.11.2-87-g4458