summaryrefslogtreecommitdiff
path: root/plugins/pychrysa/analysis/block.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-01-26 19:41:04 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-01-26 19:41:04 (GMT)
commit2050b07c42c15738662dd9b3c5841694b64ab2a3 (patch)
treef6283df4b4775f0c4e42e14025d67443f8fdf9b5 /plugins/pychrysa/analysis/block.c
parentb0b35292cb22899b1b23556be452eb827e4010d7 (diff)
Provided some debug helpers as plugin samples.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@330 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/pychrysa/analysis/block.c')
-rw-r--r--plugins/pychrysa/analysis/block.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/plugins/pychrysa/analysis/block.c b/plugins/pychrysa/analysis/block.c
new file mode 100644
index 0000000..2b405cd
--- /dev/null
+++ b/plugins/pychrysa/analysis/block.c
@@ -0,0 +1,261 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * block.c - équivalent Python du fichier "analysis/block.c"
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "block.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/block.h>
+
+
+#include "../helpers.h"
+
+
+
+/* Permet la jonction entre C et Python lors des visites */
+typedef struct _py_block_vdata
+{
+ PyObject *func; /* Fonction à appeler */
+ PyObject *user; /* Donnée à faire suivre */
+
+} py_block_vdata;
+
+
+/* Parcourt le bloc d'instructions dans un ordre donné. */
+static bool py_block_visitor_glue(GInstrBlock *, BlockVisitOrder, py_block_vdata *);
+
+/* Parcourt tous les blocs d'instructions dans un ordre donné. */
+static PyObject *py_instructions_block_visit(PyObject *, PyObject *);
+
+/* Fournit l'ensemble contenant les blocs liés. */
+static PyObject *py_instructions_block_get_links_block(PyObject *, PyObject *);
+
+/* Définit les constantes pour les blocs basiques. */
+static bool py_instructions_block_define_constants(PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : block = bloc d'instructions concerné par la visite. *
+* order = indication sur la position dans le parcours. *
+* data = donnée utilisateur à associer au parcours. *
+* *
+* Description : Parcourt le bloc d'instructions dans un ordre donné. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_block_visitor_glue(GInstrBlock *block, BlockVisitOrder order, py_block_vdata *data)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *value; /* Retour obtenu */
+
+ Py_INCREF(data->user);
+
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(block)));
+ PyTuple_SetItem(args, 1, PyInt_FromLong(order));
+ PyTuple_SetItem(args, 2, data->user);
+
+ value = _run_python_method(data->func, args);
+ result = (value == Py_True);
+
+ Py_XDECREF(value);
+ Py_DECREF(args);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant un binaire. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Parcourt tous les blocs d'instructions dans un ordre donné. *
+* *
+* Retour : True si le parcours a été jusqu'à son terme, False sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_instructions_block_visit(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Conclusion à retourner */
+ py_block_vdata data; /* Transition entre C et Python*/
+ int ret; /* Bilan de lecture des args. */
+ GInstrBlock *block; /* Point de départ des visites */
+ bool status; /* Bilan du parcours */
+
+ ret = PyArg_ParseTuple(args, "OO", &data.func, &data.user);
+ if (!ret) Py_RETURN_NONE;
+
+ block = G_INSTR_BLOCK(pygobject_get(self));
+ status = g_instr_block_visit(block, (instr_block_visitor_cb)py_block_visitor_glue, &data);
+
+ result = (status ? Py_True : Py_False);
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant un binaire. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Fournit l'ensemble contenant les blocs liés. *
+* *
+* Retour : Bloc contenant les blocs liés au bloc. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_instructions_block_get_links_block(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Conclusion à retourner */
+ GInstrBlock *block; /* Point de départ des visites */
+
+ block = G_INSTR_BLOCK(pygobject_get(self));
+
+ block = g_instr_block_get_links_block(block);
+
+ result = pygobject_new(G_OBJECT(block));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dict = dictionnaire à compléter. *
+* *
+* Description : Définit les constantes pour les blocs basiques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_instructions_block_define_constants(PyObject *dict)
+{
+ int ret; /* Bilan d'un ajout */
+
+ ret = PyDict_SetItemString(dict, "BVO_IN", PyInt_FromLong(BVO_IN));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "BVO_PENDING", PyInt_FromLong(BVO_PENDING));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "BVO_OUT", PyInt_FromLong(BVO_OUT));
+ if (ret == -1) return false;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_instructions_block(PyObject *module)
+{
+ PyObject *parent_mod; /* Module de la classe parente */
+ int ret; /* Bilan d'un appel */
+
+ static PyMethodDef py_instructions_block_methods[] = {
+ {
+ "visit", (PyCFunction)py_instructions_block_visit,
+ METH_VARARGS,
+ "Visit all the basic blocks, starting at the provided one."
+ },
+ {
+ "get_links_block", (PyCFunction)py_instructions_block_get_links_block,
+ METH_VARARGS,
+ "Get the block containing all blocks linked to the caller."
+ },
+ { NULL }
+ };
+
+ static PyGetSetDef py_instructions_block_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_instructions_block_type = {
+
+ PyObject_HEAD_INIT(NULL)
+
+ .tp_name = "pychrysalide.analysis.InstrBlock",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide basic block",
+
+ .tp_methods = py_instructions_block_methods,
+ .tp_getset = py_instructions_block_getseters
+
+ };
+
+ parent_mod = PyImport_ImportModule("gobject");
+ if (parent_mod == NULL) return false;
+
+ py_instructions_block_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject");
+ Py_DECREF(parent_mod);
+
+ if (PyType_Ready(&py_instructions_block_type) < 0)
+ return false;
+
+ if (!py_instructions_block_define_constants(py_instructions_block_type.tp_dict))
+ return false;
+
+ Py_INCREF(&py_instructions_block_type);
+ ret = PyModule_AddObject(module, "InstrBlock", (PyObject *)&py_instructions_block_type);
+
+ return (ret == 0);
+
+}