summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/pychrysa/analysis/Makefile.am9
-rw-r--r--plugins/pychrysa/analysis/block.c261
-rw-r--r--plugins/pychrysa/analysis/block.h39
-rw-r--r--plugins/pychrysa/analysis/blocks/Makefile.am17
-rw-r--r--plugins/pychrysa/analysis/blocks/flow.c149
-rw-r--r--plugins/pychrysa/analysis/blocks/flow.h39
-rw-r--r--plugins/pychrysa/analysis/blocks/module.c68
-rw-r--r--plugins/pychrysa/analysis/blocks/module.h39
-rw-r--r--plugins/pychrysa/analysis/blocks/virtual.c104
-rw-r--r--plugins/pychrysa/analysis/blocks/virtual.h39
-rw-r--r--plugins/pychrysa/analysis/module.c6
-rw-r--r--plugins/pychrysa/analysis/routine.c205
-rw-r--r--plugins/pychrysa/analysis/routine.h39
-rw-r--r--plugins/pychrysa/format/dex/dex.c18
-rw-r--r--plugins/pychrysa/format/executable.c186
-rw-r--r--plugins/pychrysa/format/executable.h26
-rw-r--r--plugins/pychrysa/format/format.c64
-rw-r--r--plugins/pychrysa/format/module.c4
-rw-r--r--plugins/pychrysa/helpers.c33
-rw-r--r--plugins/pychrysa/helpers.h5
-rw-r--r--plugins/pychrysa/plugin.c24
-rw-r--r--plugins/python/Makefile.am2
-rw-r--r--plugins/python/samples/Makefile.am7
-rw-r--r--plugins/python/samples/__init__.py2
-rw-r--r--plugins/python/samples/basic_blocks.py80
-rw-r--r--plugins/python/samples/demo.py30
26 files changed, 1302 insertions, 193 deletions
diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am
index 66da864..3480e96 100644
--- a/plugins/pychrysa/analysis/Makefile.am
+++ b/plugins/pychrysa/analysis/Makefile.am
@@ -3,11 +3,14 @@ noinst_LTLIBRARIES = libpychrysaanalysis.la
libpychrysaanalysis_la_SOURCES = \
binary.h binary.c \
+ block.h block.c \
module.h module.c \
- roptions.h roptions.c
+ roptions.h roptions.c \
+ routine.h routine.c
libpychrysaanalysis_la_LIBADD = \
- binaries/libpychrysaanalysisbinaries.la
+ binaries/libpychrysaanalysisbinaries.la \
+ blocks/libpychrysaanalysisblocks.la
libpychrysaanalysis_la_LDFLAGS =
@@ -19,4 +22,4 @@ AM_CPPFLAGS =
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = binaries
+SUBDIRS = binaries blocks
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);
+
+}
diff --git a/plugins/pychrysa/analysis/block.h b/plugins/pychrysa/analysis/block.h
new file mode 100644
index 0000000..2169ed2
--- /dev/null
+++ b/plugins/pychrysa/analysis/block.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * block.h - prototypes pour l'équivalent Python du fichier "analysis/block.h"
+ *
+ * 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
+ */
+
+
+#ifndef _PLUGINS_PYOIDA_ANALYSIS_BLOCK_H
+#define _PLUGINS_PYOIDA_ANALYSIS_BLOCK_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.analysis.InstrBlock'. */
+bool register_python_instructions_block(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYOIDA_ANALYSIS_BLOCK_H */
diff --git a/plugins/pychrysa/analysis/blocks/Makefile.am b/plugins/pychrysa/analysis/blocks/Makefile.am
new file mode 100644
index 0000000..46e99ce
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisblocks.la
+
+libpychrysaanalysisblocks_la_SOURCES = \
+ flow.h flow.c \
+ module.h module.c \
+ virtual.h virtual.c
+
+libpychrysaanalysisblocks_la_LDFLAGS =
+
+
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I../../../../src
+
+AM_CPPFLAGS =
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/analysis/blocks/flow.c b/plugins/pychrysa/analysis/blocks/flow.c
new file mode 100644
index 0000000..216156c
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/flow.c
@@ -0,0 +1,149 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * flow.h - équivalent Python du fichier "analysis/blocks/flow.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 "flow.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/blocks/flow.h>
+
+
+
+
+
+
+
+
+/* Fournit les adresses limites d'un bloc d'exécution. */
+static PyObject *py_flow_block_get_boundary_addresses(PyObject *, void *);
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant une instruction. *
+* closure = adresse non utilisée ici. *
+* *
+* Description : Fournit les adresses limites d'un bloc d'exécution. *
+* *
+* Retour : Valeur associée à la propriété consultée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_flow_block_get_boundary_addresses(PyObject *self, void *closure)
+{
+ PyObject *result; /* Trouvailles à retourner */
+ GFlowBlock *block; /* Version native */
+ vmpa_t start; /* Adresse de départ du bloc */
+ vmpa_t end; /* Dernière adresse du bloc */
+
+ block = G_FLOW_BLOCK(pygobject_get(self));
+ g_flow_block_get_boundary_addresses(block, &start, &end);
+
+ result = Py_BuildValue("(KK)", start, end);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide....blocks.FlowBlock'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_flow_block(PyObject *module)
+{
+ PyObject *parent_mod; /* Module de la classe parente */
+ int ret; /* Bilan d'un appel */
+
+ static PyMethodDef py_flow_block_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_flow_block_getseters[] = {
+ {
+ "boundary_addresses", (getter)py_flow_block_get_boundary_addresses, (setter)NULL,
+ "Provide the boundary addresses of the current flow block.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_flow_block_type = {
+
+ PyObject_HEAD_INIT(NULL)
+
+ .tp_name = "pychrysalide.analysis.blocks.FlowBlock",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide basic flow block",
+
+ .tp_methods = py_flow_block_methods,
+ .tp_getset = py_flow_block_getseters
+
+ };
+
+ parent_mod = PyImport_ImportModule("pychrysalide.analysis");
+ if (parent_mod == NULL) return false;
+
+ py_flow_block_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "InstrBlock");
+ Py_DECREF(parent_mod);
+
+ if (PyType_Ready(&py_flow_block_type) < 0)
+ return false;
+
+ Py_INCREF(&py_flow_block_type);
+ ret = PyModule_AddObject(module, "FlowBlock", (PyObject *)&py_flow_block_type);
+
+ pygobject_register_class(module, "GFlowBlock", G_TYPE_FLOW_BLOCK, &py_flow_block_type,
+ Py_BuildValue("(O)", py_flow_block_type.tp_base));
+
+ return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/analysis/blocks/flow.h b/plugins/pychrysa/analysis/blocks/flow.h
new file mode 100644
index 0000000..f18fca1
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/flow.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * flow.h - prototypes pour l'équivalent Python du fichier "analysis/blocks/flow.h"
+ *
+ * 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
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_BLOCKS_FLOW_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_BLOCKS_FLOW_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.analysis.blocks.FlowBlock'. */
+bool register_python_flow_block(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_ANALYSIS_BLOCKS_FLOW_H */
diff --git a/plugins/pychrysa/analysis/blocks/module.c b/plugins/pychrysa/analysis/blocks/module.c
new file mode 100644
index 0000000..88ed8ac
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/module.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire blocks en tant que module
+ *
+ * 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 "module.h"
+
+
+#include "flow.h"
+#include "virtual.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Ajoute le module 'blocks' au module Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_blocks_module_to_python_module(PyObject *super)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *module; /* Module Python mis en place */
+ int ret; /* Bilan d'un appel */
+
+ static PyMethodDef py_blocks_methods[] = {
+ { NULL }
+ };
+
+ module = Py_InitModule("pychrysalide.analysis.blocks", py_blocks_methods);
+ if (module == NULL) return false;
+
+ Py_INCREF(module);
+ ret = PyModule_AddObject(super, "pychrysalide.analysis.blocks", module);
+
+ result = (ret == 0);
+
+ result &= register_python_flow_block(module);
+ result &= register_python_virtual_block(module);
+
+ return result;
+
+}
diff --git a/plugins/pychrysa/analysis/blocks/module.h b/plugins/pychrysa/analysis/blocks/module.h
new file mode 100644
index 0000000..1b30d0a
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/module.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire blocks en tant que module
+ *
+ * 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
+ */
+
+
+#ifndef _PLUGINS_PYOIDA_ANALYSIS_BLOCKS_MODULE_H
+#define _PLUGINS_PYOIDA_ANALYSIS_BLOCKS_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'blocks' au module Python. */
+bool add_blocks_module_to_python_module(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYOIDA_ANALYSIS_BLOCKS_MODULE_H */
diff --git a/plugins/pychrysa/analysis/blocks/virtual.c b/plugins/pychrysa/analysis/blocks/virtual.c
new file mode 100644
index 0000000..a87fbd3
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/virtual.c
@@ -0,0 +1,104 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * virtual.h - équivalent Python du fichier "analysis/blocks/virtual.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 "virtual.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/blocks/virtual.h>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.....VirtualBlock'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_virtual_block(PyObject *module)
+{
+ PyObject *parent_mod; /* Module de la classe parente */
+ int ret; /* Bilan d'un appel */
+
+ static PyMethodDef py_virtual_block_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_virtual_block_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_virtual_block_type = {
+
+ PyObject_HEAD_INIT(NULL)
+
+ .tp_name = "pychrysalide.analysis.blocks.VirtualBlock",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide basic virtual block",
+
+ .tp_methods = py_virtual_block_methods,
+ .tp_getset = py_virtual_block_getseters
+
+ };
+
+ parent_mod = PyImport_ImportModule("pychrysalide.analysis");
+ if (parent_mod == NULL) return false;
+
+ py_virtual_block_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "InstrBlock");
+ Py_DECREF(parent_mod);
+
+ if (PyType_Ready(&py_virtual_block_type) < 0)
+ return false;
+
+ Py_INCREF(&py_virtual_block_type);
+ ret = PyModule_AddObject(module, "VirtualBlock", (PyObject *)&py_virtual_block_type);
+
+ pygobject_register_class(module, "GVirtualBlock", G_TYPE_VIRTUAL_BLOCK, &py_virtual_block_type,
+ Py_BuildValue("(O)", py_virtual_block_type.tp_base));
+
+ return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/analysis/blocks/virtual.h b/plugins/pychrysa/analysis/blocks/virtual.h
new file mode 100644
index 0000000..4c56876
--- /dev/null
+++ b/plugins/pychrysa/analysis/blocks/virtual.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * virtual.h - prototypes pour l'équivalent Python du fichier "analysis/blocks/virtual.h"
+ *
+ * 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
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_BLOCKS_VIRTUAL_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_BLOCKS_VIRTUAL_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.analysis.blocks.VirtualBlock'. */
+bool register_python_virtual_block(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_ANALYSIS_BLOCKS_VIRTUAL_H */
diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c
index 05c2e2e..0dfb5e0 100644
--- a/plugins/pychrysa/analysis/module.c
+++ b/plugins/pychrysa/analysis/module.c
@@ -26,7 +26,10 @@
#include "binary.h"
+#include "block.h"
+#include "routine.h"
#include "binaries/module.h"
+#include "blocks/module.h"
@@ -61,7 +64,10 @@ bool add_analysis_module_to_python_module(PyObject *super)
result = (ret == 0);
result &= register_python_loaded_binary(module);
+ result &= register_python_binary_routine(module);
+ result &= register_python_instructions_block(module);
result &= add_binaries_module_to_python_module(module);
+ result &= add_blocks_module_to_python_module(module);
return result;
diff --git a/plugins/pychrysa/analysis/routine.c b/plugins/pychrysa/analysis/routine.c
new file mode 100644
index 0000000..97834c5
--- /dev/null
+++ b/plugins/pychrysa/analysis/routine.c
@@ -0,0 +1,205 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * routine.c - équivalent Python du fichier "analysis/routine.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 "routine.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/routine.h>
+
+
+
+
+/* Crée un nouvel objet Python de type 'BinaryRoutine'. */
+static PyObject *py_binary_routine_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Fournit les blocs basiques de la routine. */
+static PyObject *py_binary_routine_get_basic_blocks(PyObject *, void *);
+
+
+
+/* Décrit le prototype de la routine sous forme de caractères. */
+static PyObject *py_binary_routine_str(PyObject *);
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'BinaryRoutine'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_routine_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Création à retourner */
+
+ result = pygobject_new(G_OBJECT(g_binary_routine_new()));
+
+ return result;
+
+}
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant une routine binaire. *
+* closure = adresse non utilisée ici. *
+* *
+* Description : Fournit les blocs basiques de la routine. *
+* *
+* Retour : Ensemble de blocs déterminés via les instructions. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_routine_get_basic_blocks(PyObject *self, void *closure)
+{
+ PyObject *result; /* Eléments à retourner */
+ GBinRoutine *routine; /* Version native */
+ GInstrBlock *blocks; /* Blocs basiques de routine */
+
+ routine = G_BIN_ROUTINE(pygobject_get(self));
+ blocks = g_binary_routine_get_basic_blocks(routine);
+
+ result = pygobject_new(G_OBJECT(blocks));
+
+ return result;
+
+}
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant une routine binaire. *
+* *
+* Description : Décrit le prototype de la routine sous forme de caractères. *
+* *
+* Retour : Chaîne de caractères. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_routine_str(PyObject *self)
+{
+ PyObject *result; /* Chaîne à retourner */
+ GBinRoutine *routine; /* Version native */
+ char *string; /* Description à libérer */
+
+ routine = G_BIN_ROUTINE(pygobject_get(self));
+ string = g_binary_routine_to_string(routine);
+
+ result = PyString_FromString(string);
+
+ free(string);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_binary_routine(PyObject *module)
+{
+ PyObject *pygobj_mod; /* Module Python-GObject */
+ int ret; /* Bilan d'un appel */
+
+ static PyMethodDef py_binary_routine_methods[] = {
+ { NULL }
+ };
+
+ static PyGetSetDef py_binary_routine_getseters[] = {
+ {
+ "basic_blocks", (getter)py_binary_routine_get_basic_blocks, (setter)NULL,
+ "Provide the basic blocks of the binary routine.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_binary_routine_type = {
+
+ PyObject_HEAD_INIT(NULL)
+
+ .tp_name = "pychrysalide.analysis.BinaryRoutine",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_str = py_binary_routine_str,
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = "PyChrysalide binary routine",
+
+ .tp_methods = py_binary_routine_methods,
+ .tp_getset = py_binary_routine_getseters,
+ .tp_new = (newfunc)py_binary_routine_new
+
+ };
+
+ pygobj_mod = PyImport_ImportModule("gobject");
+ if (pygobj_mod == NULL) return false;
+
+ py_binary_routine_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject");
+ Py_DECREF(pygobj_mod);
+
+ if (PyType_Ready(&py_binary_routine_type) < 0)
+ return false;
+
+ Py_INCREF(&py_binary_routine_type);
+ ret = PyModule_AddObject(module, "BinaryRoutine", (PyObject *)&py_binary_routine_type);
+
+ pygobject_register_class(module, "GBinRoutine", G_TYPE_BIN_ROUTINE, &py_binary_routine_type,
+ Py_BuildValue("(O)", py_binary_routine_type.tp_base));
+
+ return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/analysis/routine.h b/plugins/pychrysa/analysis/routine.h
new file mode 100644
index 0000000..1f3d054
--- /dev/null
+++ b/plugins/pychrysa/analysis/routine.h
@@ -0,0 +1,39 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * routine.h - prototypes pour l'équivalent Python du fichier "analysis/routine.h"
+ *
+ * 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
+ */
+
+
+#ifndef _PLUGINS_PYOIDA_ANALYSIS_ROUTINE_H
+#define _PLUGINS_PYOIDA_ANALYSIS_ROUTINE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Prend en charge l'objet 'pychrysalide.analysis.BinaryRoutine'. */
+bool register_python_binary_routine(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYOIDA_ANALYSIS_ROUTINE_H */
diff --git a/plugins/pychrysa/format/dex/dex.c b/plugins/pychrysa/format/dex/dex.c
index cae87f7..3e2746e 100644
--- a/plugins/pychrysa/format/dex/dex.c
+++ b/plugins/pychrysa/format/dex/dex.c
@@ -168,7 +168,7 @@ static PyObject *py_dex_format_get_class(PyObject *self, PyObject *args)
bool register_python_dex_format(PyObject *module)
{
- PyObject *pygobj_mod; /* Module Python-GObject */
+ PyObject *parent_mod; /* Accès au module parent */
int ret; /* Bilan d'un appel */
static PyMethodDef py_dex_format_methods[] = {
@@ -206,11 +206,11 @@ bool register_python_dex_format(PyObject *module)
};
- pygobj_mod = PyImport_ImportModule("pychrysalide.format");
- if (pygobj_mod == NULL) return false;
+ parent_mod = PyImport_ImportModule("pychrysalide.format");
+ if (parent_mod == NULL) return false;
- py_dex_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "BinFormat");
- Py_DECREF(pygobj_mod);
+ py_dex_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "ExeFormat");
+ Py_DECREF(parent_mod);
if (PyType_Ready(&py_dex_format_type) < 0)
return false;
@@ -218,8 +218,14 @@ bool register_python_dex_format(PyObject *module)
Py_INCREF(&py_dex_format_type);
ret = PyModule_AddObject(module, "DexFormat", (PyObject *)&py_dex_format_type);
+ parent_mod = PyImport_ImportModule("pychrysalide.format");
+ if (parent_mod == NULL) return false;
+
pygobject_register_class(module, "GDexFormat", G_TYPE_DEX_FORMAT, &py_dex_format_type,
- Py_BuildValue("(O)", py_dex_format_type.tp_base));
+ Py_BuildValue("(OO)", py_dex_format_type.tp_base,
+ PyObject_GetAttrString(parent_mod, "BinFormat")));
+
+ Py_DECREF(parent_mod);
return (ret == 0);
diff --git a/plugins/pychrysa/format/executable.c b/plugins/pychrysa/format/executable.c
index 43375ea..d4f2df6 100644
--- a/plugins/pychrysa/format/executable.c
+++ b/plugins/pychrysa/format/executable.c
@@ -25,61 +25,23 @@
#include "executable.h"
-#include "format.h"
+#include <pygobject.h>
+#include <format/format.h>
+#include "../quirks.h"
+/* Crée un nouvel objet Python de type 'BinFormat'. */
+static PyObject *py_executable_format_new(PyTypeObject *, PyObject *, PyObject *);
-/******************************************************************************
-* *
-* Paramètres : format = instance existante GLib. *
-* *
-* Description : Crée un nouvel objet Python de type 'ExeFormat'. *
-* *
-* Retour : Instance Python mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-PyObject *py_executable_format_from_c(GExeFormat *format)
-{
- return NULL;//py_binary_format_from_c(G_BIN_FORMAT(format));
-
-}
-
-
-
-
-
-
-
-
-/* Classe 'format.executable' pour Python */
-typedef struct _py_executable
-{
- PyObject_HEAD
-
- GExeFormat *glib; /* Format d'exécutable GLib */
-} py_executable;
-
-
-/* Crée un nouvel objet Python de type 'py_executable'. */
-static PyObject *py_executable_new(PyTypeObject *, PyObject *, PyObject *);
-
-
-
-
-
-/* Fournit le type d'objet 'format.executable' pour Python. */
-static PyTypeObject *get_format_executable_type(void);
+#define _(str) str
@@ -90,78 +52,20 @@ static PyTypeObject *get_format_executable_type(void);
* args = arguments fournis à l'appel. *
* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un nouvel objet Python de type 'py_executable'. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_executable_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- py_executable *result; /* Instance à retourner */
-
- result = (py_executable *)type->tp_alloc(type, 0);
-
- return (PyObject *)result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : executable = objet GLib existant à transposer. *
+* Description : Crée un nouvel objet Python de type 'BinFormat'. *
* *
-* Description : Convertit une instance GLib en objet Python 'py_executable'. *
-* *
-* Retour : - *
+* Retour : Instance Python mise en place. *
* *
* Remarques : - *
* *
******************************************************************************/
-PyObject *py_executable_convert(GExeFormat *executable)
+static PyObject *py_executable_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- py_executable *result; /* Instance à retourner */
- PyTypeObject *type; /* Type Python à instancier */
-
- result = (py_executable *)g_object_get_data(G_OBJECT(executable), "python_object");
-
- if (result == NULL)
- {
- type = get_format_executable_type();
-
- result = (py_executable *)type->tp_alloc(type, 0);
-
- result->glib = executable;
- g_object_ref(executable);
-
- g_object_set_data(G_OBJECT(executable), "python_object", result);
-
- }
- else Py_INCREF((PyObject *)result);
-
- return (PyObject *)result;
-
-}
+ PyErr_SetString(PyExc_ValueError,
+ _("pychrysalide.format.ExeFormat can not be instanciated directly"));
-
-/******************************************************************************
-* *
-* Paramètres : executable = instance Python dont la référence est à donner. *
-* *
-* Description : Fournit l'instance GLib d'une instance Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GExeFormat *py_executable_get_glib_instance(PyObject *executable)
-{
- return ((py_executable *)executable)->glib;
+ return NULL;
}
@@ -171,81 +75,59 @@ GExeFormat *py_executable_get_glib_instance(PyObject *executable)
-
-
-
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Fournit le type d'objet 'format.executable' pour Python. *
+* Description : Prend en charge l'objet 'pychrysalide.gui.panels.BinFormat'. *
* *
-* Retour : Adresse du type vivant à manipuler. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyTypeObject *get_format_executable_type(void)
+bool register_python_executable_format(PyObject *module)
{
- static PyTypeObject *result = NULL; /* Type pour objet à retourner */
+ PyObject *parent_mod; /* Accès au module parent */
+ int ret; /* Bilan d'un appel */
- static PyMethodDef py_executable_methods[] = {
+ static PyMethodDef py_executable_format_methods[] = {
{ NULL }
};
- static PyGetSetDef py_executable_getset[] = {
+ static PyGetSetDef py_executable_format_getseters[] = {
{ NULL }
};
- static PyTypeObject py_executable_type = {
+ static PyTypeObject py_executable_format_type = {
PyObject_HEAD_INIT(NULL)
- .tp_name = "pyoida.format.Executable",
- .tp_basicsize = sizeof(py_executable),
+ .tp_name = "pychrysalide.format.ExeFormat",
+ .tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyOIDA loaded executable to analyse",
+ .tp_doc = "PyChrysalide executable format",
- .tp_methods = py_executable_methods,
- .tp_getset = py_executable_getset,
- .tp_new = (newfunc)py_executable_new
+ .tp_methods = py_executable_format_methods,
+ .tp_getset = py_executable_format_getseters,
+ .tp_new = (newfunc)py_executable_format_new
};
- if (result == NULL) result = &py_executable_type;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : module = module dont la définition est à compléter. *
-* *
-* Description : Ajoute l'objet 'format.executable' au module Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool add_format_executable_to_python_module(PyObject *module)
-{
- PyTypeObject *py_executable_type; /* Type défini pour Python */
- int ret; /* Bilan d'un appel */
+ parent_mod = PyImport_ImportModule("pychrysalide.format");
+ if (parent_mod == NULL) return false;
- py_executable_type = get_format_executable_type();
+ py_executable_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "BinFormat");
+ Py_DECREF(parent_mod);
- if (PyType_Ready(py_executable_type) < 0)
+ if (PyType_Ready(&py_executable_format_type) < 0)
return false;
- Py_INCREF(py_executable_type);
- ret = PyModule_AddObject(module, "Executable", (PyObject *)py_executable_type);
+ Py_INCREF(&py_executable_format_type);
+ ret = PyModule_AddObject(module, "ExeFormat", (PyObject *)&py_executable_format_type);
return (ret == 0);
diff --git a/plugins/pychrysa/format/executable.h b/plugins/pychrysa/format/executable.h
index 4109784..50faee6 100644
--- a/plugins/pychrysa/format/executable.h
+++ b/plugins/pychrysa/format/executable.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* executable.h - prototypes pour l'équivalent Python du fichier "format/executable.h"
*
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -22,32 +22,18 @@
*/
-#ifndef _PLUGINS_PYOIDA_FORMAT_EXECUTABLE_H
-#define _PLUGINS_PYOIDA_FORMAT_EXECUTABLE_H
+#ifndef _PLUGINS_PYCHRYSA_FORMAT_EXECUTABLE_H
+#define _PLUGINS_PYCHRYSA_FORMAT_EXECUTABLE_H
#include <Python.h>
#include <stdbool.h>
-#include <format/executable.h>
+/* Prend en charge l'objet 'pychrysalide.format.ExeFormat'. */
+bool register_python_executable_format(PyObject *module);
-/* Crée un nouvel objet Python de type 'ExeFormat'. */
-PyObject *py_executable_format_from_c(GExeFormat *);
-
-
-/* Convertit une instance GLib en objet Python 'py_executable'. */
-PyObject *py_executable_convert(GExeFormat *);
-
-/* Fournit l'instance GLib d'une instance Python. */
-GExeFormat *py_executable_get_glib_instance(PyObject *);
-
-/* Ajoute l'objet 'format.executable' au module Python. */
-bool add_format_executable_to_python_module(PyObject *);
-
-
-
-#endif /* _PLUGINS_PYOIDA_FORMAT_EXECUTABLE_H */
+#endif /* _PLUGINS_PYCHRYSA_FORMAT_EXECUTABLE_H */
diff --git a/plugins/pychrysa/format/format.c b/plugins/pychrysa/format/format.c
index 4032da0..8a4bfb4 100644
--- a/plugins/pychrysa/format/format.c
+++ b/plugins/pychrysa/format/format.c
@@ -31,11 +31,19 @@
#include <format/format.h>
-#include "dex/dex.h"
#include "../quirks.h"
+
+
+
+#define _(str) str
+
+
+
+
+
/* Crée un nouvel objet Python de type 'BinFormat'. */
static PyObject *py_binary_format_new(PyTypeObject *, PyObject *, PyObject *);
@@ -43,6 +51,11 @@ static PyObject *py_binary_format_new(PyTypeObject *, PyObject *, PyObject *);
static PyObject *py_binary_format_resolve_relative_routine(PyObject *, PyObject *);
+/* Fournit le prototype de toutes les routines détectées. */
+static PyObject *py_binary_format_get_routines(PyObject *, void *);
+
+
+
/******************************************************************************
* *
@@ -60,7 +73,10 @@ static PyObject *py_binary_format_resolve_relative_routine(PyObject *, PyObject
static PyObject *py_binary_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- Py_RETURN_NONE;
+ PyErr_SetString(PyExc_ValueError,
+ _("pychrysalide.format.BinFormat can not be instanciated directly"));
+
+ return NULL;
}
@@ -70,9 +86,14 @@ static PyObject *py_binary_format_new(PyTypeObject *type, PyObject *args, PyObje
+
+
+
+
+
/******************************************************************************
* *
-* Paramètres : self = classe représentant un binaire. *
+* Paramètres : self = classe représentant un format binaire. *
* args = arguments fournis à l'appel. *
* *
* Description : Recherche une position dans une routine selon une adresse. *
@@ -113,6 +134,39 @@ static PyObject *py_binary_format_resolve_relative_routine(PyObject *self, PyObj
+/******************************************************************************
+* *
+* Paramètres : self = classe représentant un format binaire. *
+* closure = adresse non utilisée ici. *
+* *
+* Description : Fournit le prototype de toutes les routines détectées. *
+* *
+* Retour : Liste de routine, vide ou non. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_binary_format_get_routines(PyObject *self, void *closure)
+{
+ PyObject *result; /* Tuple à retourner */
+ GBinFormat *format; /* Format à manipuler */
+ GBinRoutine **routines; /* Routines binaires présentes */
+ size_t count; /* Quantité de ces routines */
+ size_t i; /* Boucle de parcours */
+
+ format = G_BIN_FORMAT(pygobject_get(self));
+ routines = g_binary_format_get_routines(format, &count);
+
+ result = PyTuple_New(count);
+
+ for (i = 0; i < count; i++)
+ PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(routines[i])));
+
+ return result;
+
+}
+
@@ -143,6 +197,10 @@ bool register_python_binary_format(PyObject *module)
};
static PyGetSetDef py_binary_format_getseters[] = {
+ {
+ "routines", (getter)py_binary_format_get_routines, (setter)NULL,
+ "Provide the list of all detected routines in the binary format.", NULL
+ },
{ NULL }
};
diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c
index 92c3966..3045dac 100644
--- a/plugins/pychrysa/format/module.c
+++ b/plugins/pychrysa/format/module.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* module.c - intégration du répertoire format en tant que module
*
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -64,7 +64,7 @@ bool add_format_module_to_python_module(PyObject *super)
result = (ret == 0);
result &= register_python_binary_format(module);
- result &= add_format_executable_to_python_module(module);
+ result &= register_python_executable_format(module);
result &= add_format_dex_module_to_python_module(module);
diff --git a/plugins/pychrysa/helpers.c b/plugins/pychrysa/helpers.c
index bc420c0..d8f7b0b 100644
--- a/plugins/pychrysa/helpers.c
+++ b/plugins/pychrysa/helpers.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* helpers.c - simplification des interactions de base avec Python
*
- * Copyright (C) 2012 Cyrille Bagard
+ * Copyright (C) 2012-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -49,6 +49,35 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args
func = PyObject_GetAttrString(module, method);
if (func == NULL) return NULL;
+ result = _run_python_method(func, args);
+
+ Py_DECREF(func);
+
+ return result;
+
+}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : func = fonction Python à appeler. *
+* args = arguments à associer à l'opération. *
+* *
+* Description : Appelle une routine Python. *
+* *
+* Retour : Retour obtenu ou NULL si erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *_run_python_method(PyObject *func, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+
+ result = NULL;
+
if (PyCallable_Check(func))
{
result = PyObject_CallObject(func, args);
@@ -56,8 +85,6 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args
}
else if (PyErr_Occurred()) PyErr_Print();
- Py_DECREF(func);
-
return result;
}
diff --git a/plugins/pychrysa/helpers.h b/plugins/pychrysa/helpers.h
index 474978b..1fc6eaa 100644
--- a/plugins/pychrysa/helpers.h
+++ b/plugins/pychrysa/helpers.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* helpers.h - prototypes pour la simplification des interactions de base avec Python
*
- * Copyright (C) 2012 Cyrille Bagard
+ * Copyright (C) 2012-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -32,6 +32,9 @@
/* Appelle une routine Python. */
PyObject *run_python_method(PyObject *, const char *, PyObject *);
+/* Appelle une routine Python. */
+PyObject *_run_python_method(PyObject *, PyObject *);
+
#endif /* _PLUGINS_HELPERS_H */
diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c
index c562044..e2ba78b 100644
--- a/plugins/pychrysa/plugin.c
+++ b/plugins/pychrysa/plugin.c
@@ -392,8 +392,13 @@ static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin)
value = run_python_method(plugin->instance, "get_action", NULL);
- result = PyLong_AsLong(value);
- Py_DECREF(value);
+ if (value != NULL)
+ {
+ result = PyLong_AsLong(value);
+ Py_DECREF(value);
+ }
+ else
+ result = PGA_NONE;
return result;
@@ -651,6 +656,21 @@ static bool pychrysa_plugin_define_constants(PyObject *dict)
ret = PyDict_SetItemString(dict, "PGA_DISASSEMBLE", PyInt_FromLong(PGA_DISASSEMBLE));
if (ret == -1) return false;
+ ret = PyDict_SetItemString(dict, "PGA_BINARY_DISASSEMBLED", PyInt_FromLong(PGA_BINARY_DISASSEMBLED));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "PGA_BINARY_LINKED", PyInt_FromLong(PGA_BINARY_LINKED));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "PGA_BINARY_BOUNDED", PyInt_FromLong(PGA_BINARY_BOUNDED));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "PGA_BINARY_GROUPED", PyInt_FromLong(PGA_BINARY_GROUPED));
+ if (ret == -1) return false;
+
+ ret = PyDict_SetItemString(dict, "PGA_BINARY_PRINTED", PyInt_FromLong(PGA_BINARY_PRINTED));
+ if (ret == -1) return false;
+
ret = PyDict_SetItemString(dict, "PGA_DISASS_PROCESS", PyInt_FromLong(PGA_DISASS_PROCESS));
if (ret == -1) return false;
diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am
index 3583a21..7bb4122 100644
--- a/plugins/python/Makefile.am
+++ b/plugins/python/Makefile.am
@@ -1,2 +1,2 @@
-SUBDIRS = androperms apkfiles
+SUBDIRS = androperms apkfiles samples
diff --git a/plugins/python/samples/Makefile.am b/plugins/python/samples/Makefile.am
new file mode 100644
index 0000000..38ab6c8
--- /dev/null
+++ b/plugins/python/samples/Makefile.am
@@ -0,0 +1,7 @@
+
+samplesdir = $(datadir)/openida/plugins/python/samples
+
+samples_DATA = \
+ __init__.py \
+ basic_blocks.py \
+ demo.py
diff --git a/plugins/python/samples/__init__.py b/plugins/python/samples/__init__.py
new file mode 100644
index 0000000..7186d48
--- /dev/null
+++ b/plugins/python/samples/__init__.py
@@ -0,0 +1,2 @@
+
+from demo import Demo as samples
diff --git a/plugins/python/samples/basic_blocks.py b/plugins/python/samples/basic_blocks.py
new file mode 100644
index 0000000..583723c
--- /dev/null
+++ b/plugins/python/samples/basic_blocks.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import re
+from pychrysalide.analysis import InstrBlock
+from pychrysalide.analysis.blocks import FlowBlock
+
+
+class VisitIndent:
+
+ def __init__(self):
+ self.offset = 0
+
+ def get_padding(self):
+ return ' ' * self.offset
+
+ def inc_offset(self):
+ self.offset = self.offset + 1
+
+ def dec_offset(self):
+ self.offset = self.offset - 1
+
+
+def get_c_address_of_pygobject(obj):
+ """Parse the string representation of a given object and return its memory address."""
+
+ ret = re.match('.*(0x[0-9a-f]+)\)>', str(obj), re.I)
+
+ if ret == None:
+ result = '???'
+ else:
+ result = ret.group(1)
+
+ return result
+
+
+def visit_block(block, order, indent):
+ """Describe each visited basic block."""
+
+ padding = indent.get_padding()
+ addr = get_c_address_of_pygobject(block)
+
+ if isinstance(block, FlowBlock):
+
+ start, end = block.boundary_addresses
+ links = block.get_links_block()
+
+ if links != None:
+ laddr = get_c_address_of_pygobject(links)
+ print '%s- flow %s : 0x%08lx -> 0x%08lx (links = %s)' % (padding, addr, start, end, laddr)
+
+ else:
+ print '%s- flow %s : 0x%08lx -> 0x%08lx' % (padding, addr, start, end)
+
+ else:
+
+ if order != InstrBlock.BVO_OUT:
+
+ print '%s- virtual %s' % (padding, addr)
+ indent.inc_offset()
+
+ else:
+ indent.dec_offset()
+
+ return True
+
+
+def show_basic_blocks(binary):
+ """Print the tree of all basic blocks for each routine of a given binary."""
+
+ fmt = binary.get_format()
+ indent = VisitIndent()
+
+ for r in fmt.routines:
+
+ print '==== %s ====' % str(r)
+
+ r.basic_blocks.visit(visit_block, indent)
+
+ print
diff --git a/plugins/python/samples/demo.py b/plugins/python/samples/demo.py
new file mode 100644
index 0000000..c406231
--- /dev/null
+++ b/plugins/python/samples/demo.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pychrysalide import Plugin
+from pychrysalide.gui.panels import LogPanel
+
+from basic_blocks import show_basic_blocks
+
+
+class Demo(Plugin):
+ """Demonstration plugin."""
+
+ def init(self, ref):
+ """Initialize the plugin."""
+
+ LogPanel.log_message(LogPanel.LMT_WARNING, 'Welcome to the demo Python plugin !')
+
+ return True
+
+
+ def get_action(self):
+ """Register the plugin for given actions."""
+
+ return Plugin.PGA_BINARY_GROUPED
+
+
+ def execute_on_binary(self, binary, action):
+ """Process registered actions."""
+
+ show_basic_blocks(binary)