From 526985383c4e601775b4f04b273566b8ab930a58 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 23 Feb 2020 23:51:40 +0100 Subject: Defined a working way to build routines from Python. --- plugins/pychrysalide/analysis/routine.c | 126 +++++++++++++++++++++++++------- src/analysis/disass/routines.c | 2 + src/analysis/routine.c | 2 + 3 files changed, 105 insertions(+), 25 deletions(-) diff --git a/plugins/pychrysalide/analysis/routine.c b/plugins/pychrysalide/analysis/routine.c index 0c0ef89..dee07f7 100644 --- a/plugins/pychrysalide/analysis/routine.c +++ b/plugins/pychrysalide/analysis/routine.c @@ -50,6 +50,9 @@ static PyObject *py_binary_routine_to_str(PyObject *); /* Crée un nouvel objet Python de type 'BinRoutine'. */ static PyObject *py_binary_routine_new(PyTypeObject *, PyObject *, PyObject *); +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_binary_routine_init(PyObject *, PyObject *, PyObject *); + /* Fournit le groupe d'appartenance d'une routine donnée. */ static PyObject *py_binary_routine_get_namespace(PyObject *, void *); @@ -143,6 +146,49 @@ static PyObject *py_binary_routine_new(PyTypeObject *type, PyObject *args, PyObj /****************************************************************************** * * +* Paramètres : self = objet à initialiser (théoriquement). * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Initialise une instance sur la base du dérivé de GObject. * +* * +* Retour : 0. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_binary_routine_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + int result; /* Bilan à retourner */ + + /** + * Si cette fonction n'est pas définie, l'initialisation de l'instance + * se réalise via py_binary_symbol_init(), et l'interface attend là + * des arguments... + */ + +#define BINARY_ROUTINE_DOC \ + "BinRoutine is an object for a function in a binary.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " BinRoutine()" \ + "\n" \ + "As routines can be built from demangling, with no information other than" \ + " a name at first glance, the usual process is to create a routine object" \ + " and to define its core properties (namely a location range and a symbol" \ + " type) after this operation." + + result = 0; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -160,6 +206,13 @@ static PyObject *py_binary_routine_get_namespace(PyObject *self, void *closure) GBinRoutine *routine; /* Elément à consulter */ GDataType *ns; /* Espace de noms */ +#define BINARY_ROUTINE_NAMESPACE_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + namespace, py_binary_routine, \ + "Namespace of the routine, provided as a" \ + " pychrysalide.analysis.DataType instance, or None if any." \ +) + routine = G_BIN_ROUTINE(pygobject_get(self)); ns = g_binary_routine_get_namespace(routine); @@ -258,6 +311,12 @@ static PyObject *py_binary_routine_get_name(PyObject *self, void *closure) GBinRoutine *routine; /* Elément à consulter */ const char *name; /* Désignation courante */ +#define BINARY_ROUTINE_NAME_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + name, py_binary_routine, \ + "String for the raw name of the routine or None if any." \ +) + routine = G_BIN_ROUTINE(pygobject_get(self)); name = g_binary_routine_get_name(routine); @@ -330,6 +389,17 @@ static PyObject *py_binary_routine_get_typed_name(PyObject *self, void *closure) GBinRoutine *routine; /* Elément à consulter */ GDataType *name; /* Type de nom */ +#define BINARY_ROUTINE_TYPED_NAME_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + typed_name, py_binary_routine, \ + "Typed name of the routine, provided as a" \ + " pychrysalide.analysis.DataType instance, or None if any.\n" \ + "\n" \ + "When a routine is built from a demangling operation, its final" \ + " name carries some type information. This kind of information can" \ + " be retrived thanks to this attribute." \ +) + routine = G_BIN_ROUTINE(pygobject_get(self)); name = g_binary_routine_get_typed_name(routine); @@ -413,6 +483,13 @@ static PyObject *py_binary_routine_get_return_type(PyObject *self, void *closure GBinRoutine *routine; /* Elément à consulter */ GDataType *ret; /* Type de retour */ +#define BINARY_ROUTINE_RETURN_TYPE_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + return_type, py_binary_routine, \ + "Return of the routine, provided as a" \ + " pychrysalide.analysis.DataType instance, or None if any." \ +) + routine = G_BIN_ROUTINE(pygobject_get(self)); ret = g_binary_routine_get_return_type(routine); @@ -498,6 +575,13 @@ static PyObject *py_binary_routine_get_args(PyObject *self, void *closure) size_t i; /* Boucle de parcours */ GBinVariable *arg; /* Argument à transcrire */ +#define BINARY_ROUTINE_ARGS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + args, py_binary_routine, \ + "Arguments for the routine, provided as a tuple of" \ + " pychrysalide.analysis.BinVariable instances." \ +) + routine = G_BIN_ROUTINE(pygobject_get(self)); count = g_binary_routine_get_args_count(routine); @@ -538,6 +622,14 @@ static PyObject *py_binary_routine_get_basic_blocks(PyObject *self, void *closur GBinRoutine *routine; /* Version native */ GBlockList *blocks; /* Blocs basiques de routine */ +#define BINARY_ROUTINE_BASIC_BLOCKS_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + basic_blocks, py_binary_routine, \ + "Basic blocks for the routine.\n" \ + "\n" \ + "This list is managed by a pychrysalide.analysis.BlockList instance." \ +) + routine = G_BIN_ROUTINE(pygobject_get(self)); blocks = g_binary_routine_get_basic_blocks(routine); @@ -602,30 +694,12 @@ PyTypeObject *get_python_binary_routine_type(void) }; static PyGetSetDef py_binary_routine_getseters[] = { - { - "namespace", py_binary_routine_get_namespace, py_binary_routine_set_namespace, - "Namespace for the routine, None if any.", NULL - }, - { - "name", py_binary_routine_get_name, py_binary_routine_set_name, - "Name of the current routine.", NULL - }, - { - "typed_name", py_binary_routine_get_typed_name, py_binary_routine_set_typed_name, - "Name of the current routine provided by a type.", NULL - }, - { - "ret", py_binary_routine_get_return_type, py_binary_routine_set_return_type, - "Return type of the routine, None if any.", NULL - }, - { - "args", py_binary_routine_get_args, NULL, - "Arguments for the routine.", NULL - }, - { - "basic_blocks", py_binary_routine_get_basic_blocks, py_binary_routine_set_basic_blocks, - "Basic blocks of the binary routine.", NULL - }, + BINARY_ROUTINE_NAMESPACE_ATTRIB, + BINARY_ROUTINE_NAME_ATTRIB, + BINARY_ROUTINE_TYPED_NAME_ATTRIB, + BINARY_ROUTINE_RETURN_TYPE_ATTRIB, + BINARY_ROUTINE_ARGS_ATTRIB, + BINARY_ROUTINE_BASIC_BLOCKS_ATTRIB, { NULL } }; @@ -639,10 +713,12 @@ PyTypeObject *get_python_binary_routine_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide binary routine", + .tp_doc = BINARY_ROUTINE_DOC, .tp_methods = py_binary_routine_methods, .tp_getset = py_binary_routine_getseters, + + .tp_init = py_binary_routine_init, .tp_new = py_binary_routine_new }; diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c index 5fc1dcd..be68d68 100644 --- a/src/analysis/disass/routines.c +++ b/src/analysis/disass/routines.c @@ -405,6 +405,8 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, GBinRoutine *routine, rank_routine_blocks(routine); + g_object_unref(G_OBJECT(blocks)); + /* Nettoyage final */ end_dragon_knight(knight); diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 02bd167..8c38ff1 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -792,6 +792,8 @@ void g_binary_routine_set_basic_blocks(GBinRoutine *routine, GBlockList *blocks) { g_clear_object(&routine->blocks); + g_object_ref(G_OBJECT(blocks)); + routine->blocks = blocks; } -- cgit v0.11.2-87-g4458