From 3bfff245c47c4dd1404c5ea7af0ff4858ac8d130 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 21 Dec 2012 23:34:14 +0000 Subject: Resolved relative addresses for routines and fixed bugs related to PyGObjects construction. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@308 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 97 +++++++++++++++++ configure.ac | 1 + plugins/pychrysa/analysis/Makefile.am | 4 + plugins/pychrysa/analysis/binaries/Makefile.am | 16 +++ plugins/pychrysa/analysis/binaries/file.c | 142 +++++++++++++++++++++++++ plugins/pychrysa/analysis/binaries/file.h | 39 +++++++ plugins/pychrysa/analysis/binaries/module.c | 66 ++++++++++++ plugins/pychrysa/analysis/binaries/module.h | 39 +++++++ plugins/pychrysa/analysis/binary.c | 76 +------------ plugins/pychrysa/analysis/binary.h | 5 - plugins/pychrysa/analysis/module.c | 2 + plugins/pychrysa/analysis/roptions.c | 4 +- plugins/pychrysa/arch/instruction.c | 62 +++++------ plugins/pychrysa/arch/instruction.h | 5 - plugins/pychrysa/arch/processor.c | 26 ----- plugins/pychrysa/debug/debugger.c | 4 +- plugins/pychrysa/format/dex/class.c | 34 ++---- plugins/pychrysa/format/dex/class.h | 5 - plugins/pychrysa/format/dex/dex.c | 50 +++------ plugins/pychrysa/format/dex/dex.h | 5 - plugins/pychrysa/format/executable.c | 2 +- plugins/pychrysa/format/format.c | 65 +++++++---- plugins/pychrysa/format/format.h | 5 - plugins/pychrysa/format/module.c | 2 + plugins/pychrysa/glibext/bufferline.c | 34 ++---- plugins/pychrysa/glibext/bufferline.h | 5 - plugins/pychrysa/glibext/codebuffer.c | 40 ++----- plugins/pychrysa/glibext/codebuffer.h | 5 - plugins/pychrysa/gtkext/viewpanel.c | 39 ++----- plugins/pychrysa/gtkext/viewpanel.h | 5 - plugins/pychrysa/gui/editem.c | 10 +- plugins/pychrysa/gui/panels/panel.c | 5 +- plugins/pychrysa/plugin.c | 69 ++---------- plugins/pychrysa/pychrysa.c | 8 +- plugins/pychrysa/quirks.c | 60 ++++++++++- plugins/pychrysa/quirks.h | 3 + plugins/python/androperms/androperms.py | 18 ++-- plugins/python/androperms/db.py | 24 ++--- plugins/python/androperms/panel.py | 8 +- src/analysis/routine.c | 37 ++++++- src/analysis/routine.h | 5 +- src/format/format.c | 44 ++++++++ src/format/format.h | 3 + 43 files changed, 727 insertions(+), 451 deletions(-) create mode 100644 plugins/pychrysa/analysis/binaries/Makefile.am create mode 100644 plugins/pychrysa/analysis/binaries/file.c create mode 100644 plugins/pychrysa/analysis/binaries/file.h create mode 100644 plugins/pychrysa/analysis/binaries/module.c create mode 100644 plugins/pychrysa/analysis/binaries/module.h diff --git a/ChangeLog b/ChangeLog index a0579f3..2878a1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,100 @@ +12-12-22 Cyrille Bagard + + * configure.ac: + Add the new Makfile from the 'plugins/pychrysa/analysis/binaries' + directory to AC_CONFIG_FILES. + + * plugins/pychrysa/analysis/binaries/file.c: + * plugins/pychrysa/analysis/binaries/file.h: + * plugins/pychrysa/analysis/binaries/Makefile.am: + * plugins/pychrysa/analysis/binaries/module.c: + * plugins/pychrysa/analysis/binaries/module.h: + New entries: introduce the real object for file binaries. + + * plugins/pychrysa/analysis/binary.c: + * plugins/pychrysa/analysis/binary.h: + Fix bugs related to PyGObjects construction. Update the code. + + * plugins/pychrysa/analysis/Makefile.am: + Add the 'binaries/libpychrysaanalysisbinaries.la' file to + libpychrysaanalysis_la_LIBADD and 'binaries' to SUBDIRS. + + * plugins/pychrysa/analysis/module.c: + Register the 'binaries' module. + + * plugins/pychrysa/analysis/roptions.c: + Fix leaks when returning the Py_None singleton. + + * plugins/pychrysa/arch/instruction.c: + * plugins/pychrysa/arch/instruction.h: + Fix memory leaks in the iterator and bugs related to PyGObjects + construction. + + * plugins/pychrysa/arch/processor.c: + Clean the code. + + * plugins/pychrysa/debug/debugger.c: + Fix leaks when returning the Py_None singleton. + + * plugins/pychrysa/format/dex/class.c: + * plugins/pychrysa/format/dex/class.h: + * plugins/pychrysa/format/dex/dex.c: + * plugins/pychrysa/format/dex/dex.h: + Fix memory leaks and search for relative addresses. Fix bugs related to + PyGObjects construction. + + * plugins/pychrysa/format/executable.c: + Disable the py_executable_format_from_c() function. + + * plugins/pychrysa/format/format.c: + * plugins/pychrysa/format/format.h: + Fix memory leaks and search for relative addresses. Fix bugs related to + PyGObjects construction. + + * plugins/pychrysa/format/module.c: + Register the 'BinaryFormat' Python object. + + * plugins/pychrysa/glibext/bufferline.c: + * plugins/pychrysa/glibext/bufferline.h: + Fix bugs related to PyGObjects construction. + + * plugins/pychrysa/glibext/codebuffer.c: + * plugins/pychrysa/glibext/codebuffer.h: + * plugins/pychrysa/gtkext/viewpanel.c: + * plugins/pychrysa/gtkext/viewpanel.h: + Fix bugs related to PyGObjects construction. Fix leaks when returning + the Py_None singleton. + + * plugins/pychrysa/gui/editem.c: + Update the code. + + * plugins/pychrysa/gui/panels/panel.c: + Fix memory leaks. + + * plugins/pychrysa/plugin.c: + Fix memory leaks and clean the code. + + * plugins/pychrysa/pychrysa.c: + Change the threshold of the Python garbage collector, as there still are + memory leaks to fix. + + * plugins/pychrysa/quirks.c: + * plugins/pychrysa/quirks.h: + Increase the threshold of the Python garbage collector. + + * plugins/python/androperms/androperms.py: + * plugins/python/androperms/db.py: + * plugins/python/androperms/panel.py: + Clean the code and display relative addresses. + + * src/analysis/routine.c: + * src/analysis/routine.h: + Provide the long name of a given routine. + + * src/format/format.c: + * src/format/format.h: + Resolve relative addresses for routines. + 12-12-21 Cyrille Bagard * configure.ac: diff --git a/configure.ac b/configure.ac index 5658e46..e9f7a4e 100644 --- a/configure.ac +++ b/configure.ac @@ -243,6 +243,7 @@ AC_CONFIG_FILES([Makefile plugins/govm/Makefile plugins/pychrysa/Makefile plugins/pychrysa/analysis/Makefile + plugins/pychrysa/analysis/binaries/Makefile plugins/pychrysa/arch/Makefile plugins/pychrysa/debug/Makefile plugins/pychrysa/format/Makefile diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am index f5322e8..66da864 100644 --- a/plugins/pychrysa/analysis/Makefile.am +++ b/plugins/pychrysa/analysis/Makefile.am @@ -6,6 +6,8 @@ libpychrysaanalysis_la_SOURCES = \ module.h module.c \ roptions.h roptions.c +libpychrysaanalysis_la_LIBADD = \ + binaries/libpychrysaanalysisbinaries.la libpychrysaanalysis_la_LDFLAGS = @@ -16,3 +18,5 @@ INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_ AM_CPPFLAGS = AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = binaries diff --git a/plugins/pychrysa/analysis/binaries/Makefile.am b/plugins/pychrysa/analysis/binaries/Makefile.am new file mode 100644 index 0000000..7643acf --- /dev/null +++ b/plugins/pychrysa/analysis/binaries/Makefile.am @@ -0,0 +1,16 @@ + +noinst_LTLIBRARIES = libpychrysaanalysisbinaries.la + +libpychrysaanalysisbinaries_la_SOURCES =\ + file.h file.c \ + module.h module.c + +libpychrysaanalysisbinaries_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/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c new file mode 100644 index 0000000..70192e9 --- /dev/null +++ b/plugins/pychrysa/analysis/binaries/file.c @@ -0,0 +1,142 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * file.c - prototypes pour l'équivalent Python du fichier "analysis/binaries/file.c" + * + * Copyright (C) 2012 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 "file.h" + + + +#include + + +#include + + + + +/* Crée un nouvel objet Python de type 'FileBinary'. */ +static PyObject *py_file_binary_new(PyTypeObject *, PyObject *, 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 'FileBinary'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_file_binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + char *filename; /* Nom du fichier à charger */ + int ret; /* Bilan de lecture des args. */ + GLoadedBinary *binary; /* Version GLib du format */ + + ret = PyArg_ParseTuple(args, "s", &filename); + if (!ret) Py_RETURN_NONE; + + binary = g_file_binary_new_from_file(filename); + + result = pygobject_new(G_OBJECT(binary)); + //g_object_unref(binary); + + 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_file_binary(PyObject *module) +{ + PyObject *parent_mod; /* Module Python-LoadedBinary */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_file_binary_methods[] = { + { NULL } + }; + + static PyGetSetDef py_file_binary_getseters[] = { + { NULL } + }; + + static PyTypeObject py_file_binary_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.analysis.binaries.FileBinary", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide file binary", + + .tp_methods = py_file_binary_methods, + .tp_getset = py_file_binary_getseters, + .tp_new = (newfunc)py_file_binary_new + + }; + + parent_mod = PyImport_ImportModule("pychrysalide.analysis"); + if (parent_mod == NULL) return false; + + py_file_binary_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "LoadedBinary"); + Py_DECREF(parent_mod); + + if (PyType_Ready(&py_file_binary_type) < 0) + return false; + + Py_INCREF(&py_file_binary_type); + ret = PyModule_AddObject(module, "FileBinary", (PyObject *)&py_file_binary_type); + + pygobject_register_class(module, "GFileBinary", G_TYPE_FILE_BINARY, &py_file_binary_type, + Py_BuildValue("(O)", py_file_binary_type.tp_base)); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/analysis/binaries/file.h b/plugins/pychrysa/analysis/binaries/file.h new file mode 100644 index 0000000..7cc3e26 --- /dev/null +++ b/plugins/pychrysa/analysis/binaries/file.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * file.h - prototypes pour l'équivalent Python du fichier "analysis/binaries/file.h" + * + * Copyright (C) 2012 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_BINARIES_FILE_H +#define _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_FILE_H + + +#include +#include + + + +/* Prend en charge l'objet 'pychrysalide.analysis.binaries.FileBinary'. */ +bool register_python_file_binary(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_FILE_H */ diff --git a/plugins/pychrysa/analysis/binaries/module.c b/plugins/pychrysa/analysis/binaries/module.c new file mode 100644 index 0000000..084e0a4 --- /dev/null +++ b/plugins/pychrysa/analysis/binaries/module.c @@ -0,0 +1,66 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire binaries en tant que module + * + * Copyright (C) 2012 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 "file.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'binaries' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_binaries_module_to_python_module(PyObject *super) +{ + bool result; + PyObject *module; + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_format_methods[] = { + { NULL } + }; + + module = Py_InitModule("pychrysalide.analysis.binaries", py_format_methods); + if (module == NULL) return false; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "pychrysalide.analysis.binaries", module); + + result = (ret != 0); + + result &= register_python_file_binary(module); + + return result; + +} diff --git a/plugins/pychrysa/analysis/binaries/module.h b/plugins/pychrysa/analysis/binaries/module.h new file mode 100644 index 0000000..228f33c --- /dev/null +++ b/plugins/pychrysa/analysis/binaries/module.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire binaries en tant que module + * + * Copyright (C) 2012 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_BINARIES_MODULE_H +#define _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_MODULE_H + + +#include +#include + + + +/* Ajoute le module 'binaries' au module Python. */ +bool add_binaries_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSA_ANALYSIS_BINARIES_MODULE_H */ diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c index e8158a2..abbbad5 100644 --- a/plugins/pychrysa/analysis/binary.c +++ b/plugins/pychrysa/analysis/binary.c @@ -28,7 +28,7 @@ #include -#include /* REMME ! */ +#include #include "../quirks.h" @@ -38,9 +38,6 @@ -/* Crée un nouvel objet Python de type 'LoadedBinary'. */ -static PyObject *py_loaded_binary_new(PyTypeObject *, PyObject *, PyObject *); - /* Fournit le fichier correspondant à l'élément binaire. */ static PyObject *py_loaded_binary_get_filename(PyObject *self, PyObject *args); @@ -60,68 +57,6 @@ static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *); /****************************************************************************** * * -* 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 'LoadedBinary'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_loaded_binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - char *filename; /* Nom du fichier à charger */ - int ret; /* Bilan de lecture des args. */ - GLoadedBinary *binary; /* Version GLib du format */ - - ret = PyArg_ParseTuple(args, "s", &filename); - if (!ret) return Py_None; - - binary = g_file_binary_new_from_file(filename); - - result = py_loaded_binary_from_c(binary); - g_object_unref(binary); - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * -* Paramètres : binary = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'LoadedBinary'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *py_loaded_binary_from_c(GLoadedBinary *binary) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - - module = PyImport_ImportModule("pychrysalide.analysis"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "LoadedBinary"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(binary), type); - - return pygobject_new(G_OBJECT(binary)); - -} - - -/****************************************************************************** -* * * Paramètres : self = classe représentant un binaire. * * args = arguments fournis à l'appel. * * * @@ -172,7 +107,7 @@ static PyObject *py_loaded_binary_get_format(PyObject *self, PyObject *args) binary = G_LOADED_BINARY(pygobject_get(self)); format = g_loaded_binary_get_format(binary); - result = py_executable_format_from_c(format); + result = pygobject_new(G_OBJECT(format)); return result; @@ -202,7 +137,7 @@ static PyObject *py_loaded_binary_get_instructions(PyObject *self, PyObject *arg instr = g_loaded_binary_get_instructions(binary); - result = py_arch_instruction_from_c(instr); + result = pygobject_new(G_OBJECT(instr)); return result; @@ -234,7 +169,7 @@ static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *self, void * binary = G_LOADED_BINARY(pygobject_get(self)); buffer = g_loaded_binary_get_disassembled_buffer(binary); - result = py_code_buffer_from_c(buffer); + result = pygobject_new(G_OBJECT(buffer)); return result; @@ -304,8 +239,7 @@ bool register_python_loaded_binary(PyObject *module) .tp_doc = "PyChrysalide loaded binary", .tp_methods = py_loaded_binary_methods, - .tp_getset = py_loaded_binary_getseters, - .tp_new = (newfunc)py_loaded_binary_new + .tp_getset = py_loaded_binary_getseters }; diff --git a/plugins/pychrysa/analysis/binary.h b/plugins/pychrysa/analysis/binary.h index 33ead7e..e161a5b 100644 --- a/plugins/pychrysa/analysis/binary.h +++ b/plugins/pychrysa/analysis/binary.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'LoadedBinary'. */ -PyObject *py_loaded_binary_from_c(GLoadedBinary *); - /* Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'. */ bool register_python_loaded_binary(PyObject *); diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c index 42b888e..688ea12 100644 --- a/plugins/pychrysa/analysis/module.c +++ b/plugins/pychrysa/analysis/module.c @@ -26,6 +26,7 @@ #include "binary.h" +#include "binaries/module.h" @@ -60,6 +61,7 @@ bool add_analysis_module_to_python_module(PyObject *super) result = (ret != 0); result &= register_python_loaded_binary(module); + result &= add_binaries_module_to_python_module(module); return result; diff --git a/plugins/pychrysa/analysis/roptions.c b/plugins/pychrysa/analysis/roptions.c index 57a4f52..a2b72e1 100644 --- a/plugins/pychrysa/analysis/roptions.c +++ b/plugins/pychrysa/analysis/roptions.c @@ -85,7 +85,7 @@ static PyObject *py_rendering_options_new(PyTypeObject *type, PyObject *args, Py GExeFormat *_executable; /* Version GLib du format */ ret = PyArg_ParseTuple(args, "O", &executable); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; result = (py_rendering_options *)type->tp_alloc(type, 0); @@ -199,7 +199,7 @@ static PyObject *py_rendering_options_show_code(PyObject *self, PyObject *args) printf("show code :: %d\n", state); - return Py_None; + Py_RETURN_NONE; } diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c index bed937b..09397fc 100644 --- a/plugins/pychrysa/arch/instruction.c +++ b/plugins/pychrysa/arch/instruction.c @@ -30,6 +30,9 @@ #include +#include + + #include "../quirks.h" @@ -105,13 +108,14 @@ static PyObject *py_arch_instruction_iterator_create(PyObject *origin) Py_DECREF(module); result = (PyArchInstructionIter *)type->tp_alloc(type, 0); + Py_DECREF(type); if (result != NULL) { + Py_INCREF(origin); result->head = G_ARCH_INSTRUCTION(pygobject_get(origin)); g_object_ref(G_OBJECT(result->head)); - Py_INCREF(origin); result->current = origin; } @@ -134,8 +138,12 @@ static PyObject *py_arch_instruction_iterator_create(PyObject *origin) static void py_arch_instruction_iterator_dealloc(PyArchInstructionIter *self) { + PyObject *first; /* Récupération de la première */ + + first = pychrysalide_get_pygobject(G_OBJECT(self->head)); + + Py_DECREF(first); g_object_unref(G_OBJECT(self->head)); - Py_DECREF(self->current); #if PY_VERSION_HEX < 0x03000000 self->ob_type->tp_free((PyObject *)self); @@ -167,6 +175,8 @@ static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *self) { self->started = true; result = self->current; + Py_INCREF(result); + } else { @@ -175,17 +185,14 @@ static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *self) if (next != NULL) { - result = py_arch_instruction_from_c(next); - - Py_INCREF(result); - Py_DECREF(self->current); + result = pygobject_new(G_OBJECT(next)); self->current = result; - } else result = NULL; } + Py_XINCREF(result); return (PyObject *)result; } @@ -258,35 +265,7 @@ bool register_python_arch_instruction_iterator(PyObject *module) static PyObject *py_arch_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - return Py_None; - -} - - -/****************************************************************************** -* * -* Paramètres : binary = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'ArchInstruction'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *py_arch_instruction_from_c(GArchInstruction *instr) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - - module = PyImport_ImportModule("pychrysalide.arch"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "ArchInstruction"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(instr), type); - - return pygobject_new(G_OBJECT(instr)); + Py_RETURN_NONE; } @@ -337,12 +316,15 @@ static PyObject *py_arch_instruction_get_location(PyObject *self, char *name) if (strcmp(name, "offset") == 0) result = PyLong_FromLong(offset); - else if (strcmp(name, "") == 0) + else if (strcmp(name, "length") == 0) result = PyLong_FromLong(length); - else /*if (strcmp(name, "") == 0)*/ + else if (strcmp(name, "address") == 0) result = PyLong_FromLongLong(address); + else + result = NULL; + return result; } @@ -449,6 +431,10 @@ bool register_python_arch_instruction(PyObject *module) Py_INCREF(&py_arch_instruction_type); ret = PyModule_AddObject(module, "ArchInstruction", (PyObject *)&py_arch_instruction_type); + pygobject_register_class(module, "GArchInstruction", G_TYPE_ARCH_INSTRUCTION, + &py_arch_instruction_type, + Py_BuildValue("(O)", py_arch_instruction_type.tp_base)); + return (ret == 0); } diff --git a/plugins/pychrysa/arch/instruction.h b/plugins/pychrysa/arch/instruction.h index 545d88e..d91b8d1 100644 --- a/plugins/pychrysa/arch/instruction.h +++ b/plugins/pychrysa/arch/instruction.h @@ -29,8 +29,6 @@ #include #include -#include - /* --------------------- ITERATEUR POUR BOUCLE SUR INSTRUCTIONS --------------------- */ @@ -44,9 +42,6 @@ bool register_python_arch_instruction_iterator(PyObject *); /* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */ -/* Crée un nouvel objet Python de type 'ArchInstruction'. */ -PyObject *py_arch_instruction_from_c(GArchInstruction *); - /* Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. */ bool register_python_arch_instruction(PyObject *); diff --git a/plugins/pychrysa/arch/processor.c b/plugins/pychrysa/arch/processor.c index 0a3fe95..cc1113a 100644 --- a/plugins/pychrysa/arch/processor.c +++ b/plugins/pychrysa/arch/processor.c @@ -224,32 +224,6 @@ static PyObject *py_processor_new(PyTypeObject *type, PyObject *args, PyObject * -static PyObject *util_FromImport(const char *name, const char *from_item) -{ - PyObject *from_list; - PyObject *module; - PyObject *item; - - /* Make the from list. */ - from_list = PyList_New(1); - PyList_SetItem(from_list, 0, PyString_FromString(from_item)); - - /* Attempt the import, with const correctness removed. */ - module = PyImport_ImportModuleEx((char *)name, NULL, NULL, from_list); - Py_DECREF(from_list); - if (!module) - { - return NULL; - } - - /* Get the from_item from the module. */ - item = PyObject_GetAttrString(module, (char *)from_item); - Py_DECREF(module); - - return item; -} - - diff --git a/plugins/pychrysa/debug/debugger.c b/plugins/pychrysa/debug/debugger.c index c27d30d..1e82272 100644 --- a/plugins/pychrysa/debug/debugger.c +++ b/plugins/pychrysa/debug/debugger.c @@ -67,7 +67,7 @@ static PyObject *py_binary_debugger_new(PyTypeObject *type, PyObject *args, PyOb GBinaryDebugger *debugger; /* Version GLib du format */ ret = PyArg_ParseTuple(args, "l", &dtype); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; debugger = g_new_binary_debugger(dtype, NULL/* FIXME */); @@ -188,7 +188,7 @@ static PyObject *py_binary_debugger_get_frames_stack(PyObject *self, PyObject *a debugger = G_BINARY_DEBUGGER(pygobject_get(self)); if (!PyArg_ParseTuple(args, "k", &thread)) - return Py_None; + Py_RETURN_NONE; frames = g_binary_debugger_get_frames_stack(debugger, thread, &count); diff --git a/plugins/pychrysa/format/dex/class.c b/plugins/pychrysa/format/dex/class.c index 97c1968..bc07fae 100644 --- a/plugins/pychrysa/format/dex/class.c +++ b/plugins/pychrysa/format/dex/class.c @@ -28,6 +28,9 @@ #include +#include + + #include "../../quirks.h" @@ -53,37 +56,11 @@ static PyObject *py_dex_class_new(PyTypeObject *, PyObject *, PyObject *); static PyObject *py_dex_class_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - return Py_None; + Py_RETURN_NONE; } -/****************************************************************************** -* * -* Paramètres : item = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'DexClass'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *py_dex_class_from_c(GDexClass *class) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - - module = PyImport_ImportModule("pychrysalide.format.dex"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "DexClass"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(class), type); - - return pygobject_new(G_OBJECT(class)); - -} @@ -152,6 +129,9 @@ bool register_python_dex_class(PyObject *module) Py_INCREF(&py_dex_class_type); ret = PyModule_AddObject(module, "DexClass", (PyObject *)&py_dex_class_type); + pygobject_register_class(module, "GDexClass", G_TYPE_DEX_CLASS, &py_dex_class_type, + Py_BuildValue("(O)", py_dex_class_type.tp_base)); + return (ret == 0); } diff --git a/plugins/pychrysa/format/dex/class.h b/plugins/pychrysa/format/dex/class.h index addf7ca..c2a8222 100644 --- a/plugins/pychrysa/format/dex/class.h +++ b/plugins/pychrysa/format/dex/class.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'DexClass'. */ -PyObject *py_dex_class_from_c(GDexClass *); - /* Prend en charge l'objet 'pychrysalide.format.dex.DexClass'. */ bool register_python_dex_class(PyObject *module); diff --git a/plugins/pychrysa/format/dex/dex.c b/plugins/pychrysa/format/dex/dex.c index 2df8d1b..cae87f7 100644 --- a/plugins/pychrysa/format/dex/dex.c +++ b/plugins/pychrysa/format/dex/dex.c @@ -27,6 +27,7 @@ #include + #include @@ -69,13 +70,13 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject GBinFormat *format; /* Version GLib du format */ ret = PyArg_ParseTuple(args, "s#", &content, &length); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; format = g_dex_format_new(content, length); - if (format == NULL) return Py_None; + if (format == NULL) Py_RETURN_NONE; - result = py_dex_format_from_c(G_DEX_FORMAT(format)); - g_object_unref(format); + result = pygobject_new(G_OBJECT(format)); + //g_object_unref(format); return (PyObject *)result; @@ -84,34 +85,6 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject /****************************************************************************** * * -* Paramètres : item = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'DexFormat'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *py_dex_format_from_c(GDexFormat *format) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - - module = PyImport_ImportModule("pychrysalide.format.dex"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "DexFormat"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(format), type); - - return pygobject_new(G_OBJECT(format)); - -} - - -/****************************************************************************** -* * * Paramètres : self = classe représentant un binaire. * * args = arguments fournis à l'appel. * * * @@ -162,14 +135,14 @@ static PyObject *py_dex_format_get_class(PyObject *self, PyObject *args) GDexClass *class; /* Classe à communiquer */ ret = PyArg_ParseTuple(args, "i", &index); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; format = G_DEX_FORMAT(pygobject_get(self)); class = g_dex_format_get_class(format, index); - if (class == NULL) return Py_None; + if (class == NULL) Py_RETURN_NONE; - result = py_dex_class_from_c(class); + result = pygobject_new(G_OBJECT(class)); return result; @@ -233,10 +206,10 @@ bool register_python_dex_format(PyObject *module) }; - pygobj_mod = PyImport_ImportModule("gobject"); + pygobj_mod = PyImport_ImportModule("pychrysalide.format"); if (pygobj_mod == NULL) return false; - py_dex_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); + py_dex_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "BinFormat"); Py_DECREF(pygobj_mod); if (PyType_Ready(&py_dex_format_type) < 0) @@ -245,6 +218,9 @@ bool register_python_dex_format(PyObject *module) Py_INCREF(&py_dex_format_type); ret = PyModule_AddObject(module, "DexFormat", (PyObject *)&py_dex_format_type); + pygobject_register_class(module, "GDexFormat", G_TYPE_DEX_FORMAT, &py_dex_format_type, + Py_BuildValue("(O)", py_dex_format_type.tp_base)); + return (ret == 0); } diff --git a/plugins/pychrysa/format/dex/dex.h b/plugins/pychrysa/format/dex/dex.h index 65eec0d..dc97269 100644 --- a/plugins/pychrysa/format/dex/dex.h +++ b/plugins/pychrysa/format/dex/dex.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'DexFormat'. */ -PyObject *py_dex_format_from_c(GDexFormat *); - /* Prend en charge l'objet 'pychrysalide.format.dex.DexFormat'. */ bool register_python_dex_format(PyObject *module); diff --git a/plugins/pychrysa/format/executable.c b/plugins/pychrysa/format/executable.c index 7cdc855..43375ea 100644 --- a/plugins/pychrysa/format/executable.c +++ b/plugins/pychrysa/format/executable.c @@ -48,7 +48,7 @@ PyObject *py_executable_format_from_c(GExeFormat *format) { - return py_binary_format_from_c(G_BIN_FORMAT(format)); + return NULL;//py_binary_format_from_c(G_BIN_FORMAT(format)); } diff --git a/plugins/pychrysa/format/format.c b/plugins/pychrysa/format/format.c index ea556ba..4032da0 100644 --- a/plugins/pychrysa/format/format.c +++ b/plugins/pychrysa/format/format.c @@ -28,6 +28,9 @@ #include +#include + + #include "dex/dex.h" #include "../quirks.h" @@ -36,6 +39,9 @@ /* Crée un nouvel objet Python de type 'BinFormat'. */ static PyObject *py_binary_format_new(PyTypeObject *, PyObject *, PyObject *); +/* Recherche une position dans une routine selon une adresse. */ +static PyObject *py_binary_format_resolve_relative_routine(PyObject *, PyObject *); + /****************************************************************************** @@ -54,43 +60,53 @@ static PyObject *py_binary_format_new(PyTypeObject *, PyObject *, PyObject *); static PyObject *py_binary_format_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - return Py_None; + Py_RETURN_NONE; } + + + + + /****************************************************************************** * * -* Paramètres : format = instance existante GLib. * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * * * -* Description : Crée un nouvel objet Python de type 'BinFormat'. * +* Description : Recherche une position dans une routine selon une adresse. * * * -* Retour : Instance Python mise en place. * +* Retour : Tuple (nom, décallage) ou Py_None. * * * * Remarques : - * * * ******************************************************************************/ -PyObject *py_binary_format_from_c(GBinFormat *format) +static PyObject *py_binary_format_resolve_relative_routine(PyObject *self, PyObject *args) { - PyObject *result; /* Conversion à retourner */ - GType type; /* Type réel du format */ + PyObject *result; /* Tuple à retourner */ + GBinFormat *format; /* Format à manipuler */ + vmpa_t addr; /* Adresse demandée en visuel */ + int ret; /* Bilan de lecture des args. */ + bool found; /* Bilan de la résolution */ + const char *label; /* Désignation de la trouvaille*/ - type = G_OBJECT_TYPE(G_OBJECT(format)); - - if (type == G_TYPE_DEX_FORMAT) - result = py_dex_format_from_c(G_DEX_FORMAT(format)); - else - result = Py_None; - - return result; - -} + format = G_BIN_FORMAT(pygobject_get(self)); + ret = PyArg_ParseTuple(args, "K", &addr); + if (!ret) Py_RETURN_NONE; + found = g_binary_format_resolve_relative_routine(format, &label, &addr); + if (!found) Py_RETURN_NONE; + result = PyTuple_New(2); + PyTuple_SetItem(result, 0, PyString_FromString(label)); + PyTuple_SetItem(result, 1, PyLong_FromLongLong(addr)); + return result; +} @@ -114,10 +130,15 @@ PyObject *py_binary_format_from_c(GBinFormat *format) bool register_python_binary_format(PyObject *module) { - PyObject *pygobj_mod; /* Module Python-GObject */ + PyObject *parent_mod; /* Module Python-GObject */ int ret; /* Bilan d'un appel */ static PyMethodDef py_binary_format_methods[] = { + { + "resolve_relative_routine", (PyCFunction)py_binary_format_resolve_relative_routine, + METH_VARARGS, + "Search a position inside a routine by a given address." + }, { NULL } }; @@ -142,11 +163,11 @@ bool register_python_binary_format(PyObject *module) }; - pygobj_mod = PyImport_ImportModule("gobject"); - if (pygobj_mod == NULL) return false; + parent_mod = PyImport_ImportModule("gobject"); + if (parent_mod == NULL) return false; - py_binary_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); - Py_DECREF(pygobj_mod); + py_binary_format_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "GObject"); + Py_DECREF(parent_mod); if (PyType_Ready(&py_binary_format_type) < 0) return false; diff --git a/plugins/pychrysa/format/format.h b/plugins/pychrysa/format/format.h index 8f38408..ede833e 100644 --- a/plugins/pychrysa/format/format.h +++ b/plugins/pychrysa/format/format.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'BinFormat'. */ -PyObject *py_binary_format_from_c(GBinFormat *); - /* Prend en charge l'objet 'pychrysalide.format.BinFormat'. */ bool register_python_binary_format(PyObject *module); diff --git a/plugins/pychrysa/format/module.c b/plugins/pychrysa/format/module.c index d3e863f..8bf2ed2 100644 --- a/plugins/pychrysa/format/module.c +++ b/plugins/pychrysa/format/module.c @@ -26,6 +26,7 @@ #include "executable.h" +#include "format.h" #include "dex/module.h" @@ -62,6 +63,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 &= add_format_dex_module_to_python_module(module); diff --git a/plugins/pychrysa/glibext/bufferline.c b/plugins/pychrysa/glibext/bufferline.c index 1e3b611..3804082 100644 --- a/plugins/pychrysa/glibext/bufferline.c +++ b/plugins/pychrysa/glibext/bufferline.c @@ -29,6 +29,9 @@ #include +#include + + #include "../quirks.h" @@ -40,34 +43,6 @@ static PyObject *py_buffer_line_get_text(PyObject *, PyObject *); /****************************************************************************** * * -* Paramètres : binary = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'BufferLine'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *py_buffer_line_from_c(GBufferLine *line) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - - module = PyImport_ImportModule("pychrysalide.glibext"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "BufferLine"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(line), type); - - return pygobject_new(G_OBJECT(line)); - -} - - -/****************************************************************************** -* * * Paramètres : self = classe représentant une ligne de tampon. * * args = arguments fournis à l'appel. * * * @@ -150,6 +125,9 @@ bool register_python_buffer_line(PyObject *module) Py_INCREF(&py_buffer_line_type); ret = PyModule_AddObject(module, "BufferLine", (PyObject *)&py_buffer_line_type); + pygobject_register_class(module, "GBufferLine", G_TYPE_BUFFER_LINE, &py_buffer_line_type, + Py_BuildValue("(O)", py_buffer_line_type.tp_base)); + return (ret == 0); } diff --git a/plugins/pychrysa/glibext/bufferline.h b/plugins/pychrysa/glibext/bufferline.h index d15928f..abe6cd8 100644 --- a/plugins/pychrysa/glibext/bufferline.h +++ b/plugins/pychrysa/glibext/bufferline.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'BufferLine'. */ -PyObject *py_buffer_line_from_c(GBufferLine *); - /* Prend en charge l'objet 'pychrysalide.glibext.BufferLine'. */ bool register_python_buffer_line(PyObject *); diff --git a/plugins/pychrysa/glibext/codebuffer.c b/plugins/pychrysa/glibext/codebuffer.c index a090e27..e4c94e3 100644 --- a/plugins/pychrysa/glibext/codebuffer.c +++ b/plugins/pychrysa/glibext/codebuffer.c @@ -28,6 +28,9 @@ #include +#include + + #include "../quirks.h" @@ -39,34 +42,6 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *, PyObject *); /****************************************************************************** * * -* Paramètres : binary = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'Codebuffer'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyObject *py_code_buffer_from_c(GCodeBuffer *buffer) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - - module = PyImport_ImportModule("pychrysalide.glibext"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "CodeBuffer"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(buffer), type); - - return pygobject_new(G_OBJECT(buffer)); - -} - - -/****************************************************************************** -* * * Paramètres : self = classe représentant un tampon de code. * * args = arguments fournis à l'appel. * * * @@ -89,12 +64,12 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args buffer = G_CODE_BUFFER(pygobject_get(self)); ret = PyArg_ParseTuple(args, "K", &addr); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; line = g_code_buffer_find_line_by_addr(buffer, addr); - if (line == NULL) return Py_None; + if (line == NULL) Py_RETURN_NONE; - result = py_buffer_line_from_c(line); + result = pygobject_new(G_OBJECT(line)); return result; @@ -154,6 +129,9 @@ bool register_python_code_buffer(PyObject *module) Py_INCREF(&py_code_buffer_type); ret = PyModule_AddObject(module, "CodeBuffer", (PyObject *)&py_code_buffer_type); + pygobject_register_class(module, "GCodeBuffer", G_TYPE_CODE_BUFFER, &py_code_buffer_type, + Py_BuildValue("(O)", py_code_buffer_type.tp_base)); + return (ret == 0); } diff --git a/plugins/pychrysa/glibext/codebuffer.h b/plugins/pychrysa/glibext/codebuffer.h index ba53fda..d80597e 100644 --- a/plugins/pychrysa/glibext/codebuffer.h +++ b/plugins/pychrysa/glibext/codebuffer.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'CodeBuffer'. */ -PyObject *py_code_buffer_from_c(GCodeBuffer *); - /* Prend en charge l'objet 'pychrysalide.glibext.CodeBuffer'. */ bool register_python_code_buffer(PyObject *); diff --git a/plugins/pychrysa/gtkext/viewpanel.c b/plugins/pychrysa/gtkext/viewpanel.c index c1108c2..9d5645a 100644 --- a/plugins/pychrysa/gtkext/viewpanel.c +++ b/plugins/pychrysa/gtkext/viewpanel.c @@ -28,6 +28,9 @@ #include +#include + + #include "../quirks.h" @@ -66,7 +69,7 @@ static PyObject *py_view_panel_new(PyTypeObject *type, PyObject *args, PyObject GEditorItem *item; /* Version GLib du format */ ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; item = g_view_panel_new(get_internal_ref(), name, lname, GTK_WIDGET(pygobject_get(widget)), path); @@ -78,35 +81,9 @@ static PyObject *py_view_panel_new(PyTypeObject *type, PyObject *args, PyObject #endif /* FIXME */ - return Py_None; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance existante GLib. * -* * -* Description : Crée un nouvel objet Python de type 'ViewPanel'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ -PyObject *py_view_panel_from_c(GtkViewPanel *item) -{ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type Python correspondant */ - module = PyImport_ImportModule("pychrysalide.gtkext"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "ViewPanel"); - Py_DECREF(module); - - pychrysalide_set_instance_data(G_OBJECT(item), type); - - return pygobject_new(G_OBJECT(item)); + Py_RETURN_NONE; } @@ -114,6 +91,7 @@ PyObject *py_view_panel_from_c(GtkViewPanel *item) + /****************************************************************************** * * * Paramètres : self = classe représentant un tampon de code. * @@ -136,7 +114,7 @@ static PyObject *py_view_panel_scroll_to_address(PyObject *self, PyObject *args) panel = GTK_VIEW_PANEL(pygobject_get(self)); ret = PyArg_ParseTuple(args, "K", &addr); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; gtk_view_panel_scroll_to_address(panel, addr); @@ -209,6 +187,9 @@ bool register_python_view_panel(PyObject *module) Py_INCREF(&py_view_panel_type); ret = PyModule_AddObject(module, "ViewPanel", (PyObject *)&py_view_panel_type); + pygobject_register_class(module, "GtkViewPanel", GTK_TYPE_VIEW_PANEL, &py_view_panel_type, + Py_BuildValue("(O)", py_view_panel_type.tp_base)); + return (ret == 0); } diff --git a/plugins/pychrysa/gtkext/viewpanel.h b/plugins/pychrysa/gtkext/viewpanel.h index 98b1150..7733e46 100644 --- a/plugins/pychrysa/gtkext/viewpanel.h +++ b/plugins/pychrysa/gtkext/viewpanel.h @@ -29,13 +29,8 @@ #include #include -#include - -/* Crée un nouvel objet Python de type 'ViewPanel'. */ -PyObject *py_view_panel_from_c(GtkViewPanel *); - /* Prend en charge l'objet 'pychrysalide.gtkext.ViewPanel'. */ bool register_python_view_panel(PyObject *module); diff --git a/plugins/pychrysa/gui/editem.c b/plugins/pychrysa/gui/editem.c index 3b7a8b8..c7e4724 100644 --- a/plugins/pychrysa/gui/editem.c +++ b/plugins/pychrysa/gui/editem.c @@ -97,7 +97,7 @@ static void _update_editor_item_for_binary_python_wrapper(GEditorItem *item, GLo target = pychrysalide_get_pygobject(G_OBJECT(item)); args = PyTuple_New(1); - PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary)); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary))); value = run_python_method(target, "update_for_binary", args); @@ -139,7 +139,7 @@ static void _update_editor_item_for_view_python_wrapper(GEditorItem *item, GtkVi target = pychrysalide_get_pygobject(G_OBJECT(item)); args = PyTuple_New(1); - PyTuple_SetItem(args, 0, py_view_panel_from_c(view)); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(view))); value = run_python_method(target, "update_for_view", args); @@ -181,7 +181,7 @@ static void _update_editor_item_for_view_content_python_wrapper(GEditorItem *ite target = pychrysalide_get_pygobject(G_OBJECT(item)); args = PyTuple_New(1); - PyTuple_SetItem(args, 0, py_view_panel_from_c(view)); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(view))); value = run_python_method(target, "update_for_content", args); @@ -280,7 +280,7 @@ static PyObject *py_editor_item_get_current_binary(PyObject *self, PyObject *arg result = Py_None; } else - result = py_loaded_binary_from_c(binary); + result = pygobject_new(G_OBJECT(binary)); return result; @@ -315,7 +315,7 @@ static PyObject *py_editor_item_get_current_view(PyObject *self, PyObject *args) result = Py_None; } else - result = py_view_panel_from_c(panel); + result = pygobject_new(G_OBJECT(panel)); return result; diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c index 4b982d0..fc261b5 100644 --- a/plugins/pychrysa/gui/panels/panel.c +++ b/plugins/pychrysa/gui/panels/panel.c @@ -65,7 +65,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject GEditorItem *item; /* Version GLib du format */ ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path); - if (!ret) return Py_None; + if (!ret) Py_RETURN_NONE; item = g_panel_item_new(get_internal_ref(), name, lname, GTK_WIDGET(pygobject_get(widget)), path); @@ -73,7 +73,7 @@ static PyObject *py_panel_item_new(PyTypeObject *type, PyObject *args, PyObject result = _py_panel_item_from_c(G_PANEL_ITEM(item), type); g_object_unref(item); - return (PyObject *)result; + return result; } @@ -102,6 +102,7 @@ PyObject *_py_panel_item_from_c(GPanelItem *item, PyTypeObject *type) type = (PyTypeObject *)PyObject_GetAttrString(module, "PanelItem"); Py_DECREF(module); } + else Py_INCREF(type); pychrysalide_set_instance_data(G_OBJECT(item), type); diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c index 1bda007..c562044 100644 --- a/plugins/pychrysa/plugin.c +++ b/plugins/pychrysa/plugin.c @@ -132,7 +132,7 @@ static PyObject *pychrysa_plugin_handle_debugger(PyObject *, PyObject *); - +#if 0 @@ -155,19 +155,7 @@ main2(const char *filename, const char *method) if (pFunc && PyCallable_Check(pFunc)) { pArgs = PyTuple_New(0/*argc - 3*/); -#if 0 - for (i = 0; i < argc - 3; ++i) { - pValue = PyLong_FromLong(atoi(argv[i + 3])); - if (!pValue) { - Py_DECREF(pArgs); - Py_DECREF(pModule); - fprintf(stderr, "Cannot convert argument\n"); - return 1; - } - /* pValue reference stolen here: */ - PyTuple_SetItem(pArgs, i, pValue); - } -#endif + pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); if (pValue != NULL) { @@ -199,7 +187,7 @@ main2(const char *filename, const char *method) } - +#endif @@ -540,7 +528,7 @@ static bool g_python_plugin_execute_on_binary(GPythonPlugin *plugin, GLoadedBina args = PyTuple_New(2); - PyTuple_SetItem(args, 0, py_loaded_binary_from_c(binary)); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary))); PyTuple_SetItem(args, 1, PyInt_FromLong(action)); value = run_python_method(plugin->instance, "execute_on_binary", args); @@ -752,7 +740,9 @@ static PyObject *pychrysa_plugin_is_matching(PyObject *self, PyObject *args) result = PyTuple_New(3); PyTuple_SetItem(result, 0, PyInt_FromLong(MFA_NONE)); + Py_DECREF(Py_None); PyTuple_SetItem(result, 1, Py_None); + Py_DECREF(Py_None); PyTuple_SetItem(result, 2, Py_None); return result; @@ -797,52 +787,12 @@ static PyObject *pychrysa_plugin_handle_debugger(PyObject *self, PyObject *args) static PyObject *pychrysa_plugin_run(PyObject *self, PyObject *args) { - return Py_None; - -} - - - - - -#include - -static int convert_to_w(PyGObject *obj, void **out) -{ - - //if (!pygobject_check(obj, - - *out = pygobject_get(obj); - - return (1); + Py_RETURN_NONE; } -static PyObject *add_wgt(PyObject *self, PyObject *args) -{ - GtkWidget *result; - GtkWidget *button; - - result = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_size_request(result, 400, 300); - gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); - gtk_container_set_border_width(GTK_CONTAINER(result), 4); - gtk_window_set_title(GTK_WINDOW(result), _("ChrysalideWWW")); - - gtk_widget_show (result); - - - if (!PyArg_ParseTuple(args, "O&", convert_to_w, &button)) - return Py_None; - - gtk_container_add(GTK_CONTAINER(result), button); - - - return Py_None; - -} @@ -893,11 +843,6 @@ static PyMethodDef pychrysa_plugin_methods[] = { METH_VARARGS, "Run the plugin for a specific action." }, - { - "add_wgt", (PyCFunction)add_wgt, - METH_VARARGS, - "Run the plugin for a specific action." - }, NULL }; diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index 0e8446d..94cd51e 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -129,6 +129,9 @@ bool init_plugin(GPluginModule *plugin, GObject *ref) Py_Initialize(); + //pychrysalide_set_gc_threshold(10000, 10000, 10000); + pychrysalide_set_gc_threshold(INT_MAX, INT_MAX, INT_MAX); + initpychrysa(); @@ -199,7 +202,8 @@ bool init_plugin(GPluginModule *plugin, GObject *ref) void exit_plugin(GPluginModule *plugin) { - Py_Finalize(); + /* FIXME */ + //Py_Finalize(); } @@ -290,7 +294,7 @@ PyMODINIT_FUNC initpychrysa(void) add_gtkext_module_to_python_module(module); add_gui_module_to_python_module(module); - add_log_to_python_module(module); + //add_log_to_python_module(module); add_plugin_to_python_module(module); } diff --git a/plugins/pychrysa/quirks.c b/plugins/pychrysa/quirks.c index 68f0a2e..2813fb2 100644 --- a/plugins/pychrysa/quirks.c +++ b/plugins/pychrysa/quirks.c @@ -30,6 +30,8 @@ #include +#include "helpers.h" + @@ -56,6 +58,7 @@ static void pygobject_data_free_fake(PyGObjectData_fake *data) { PyGILState_STATE state; /* Etat interne de Python */ GSList *iter; /* Boucle de parcours */ + GSList *old; /* Sauvegarde avant libération */ //state = pyglib_gil_state_ensure(); @@ -69,9 +72,10 @@ static void pygobject_data_free_fake(PyGObjectData_fake *data) * On obtient le lien avant la libération via * pygobject_unwatch_closure()... */ + old = iter; iter = iter->next; - g_closure_invalidate((GClosure *)iter->data); + g_closure_invalidate((GClosure *)old->data); } @@ -122,6 +126,47 @@ void pychrysalide_init_quirks(void) /****************************************************************************** * * +* Paramètres : threshold0 = seuil pour la collecte de niveau 0. * +* threshold1 = seuil pour la collecte de niveau 1. * +* threshold2 = seuil pour la collecte de niveau 2. * +* * +* Description : Modifie les seuils de collecte pour le collecteur de Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void pychrysalide_set_gc_threshold(int threshold0, int threshold1, int threshold2) +{ + PyObject *module; /* Module Python "gc" */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Valeurs obtenues */ + + module = PyImport_ImportModule("gc"); + + if (threshold0 == 0 && threshold1 == 0 && threshold2 == 0) + { + args = Py_BuildValue("()"); + value = run_python_method(module, "disable", args); + } + else + { + args = Py_BuildValue("(iii)", threshold0, threshold1, threshold2); + value = run_python_method(module, "set_threshold", args); + } + + Py_DECREF(value); + Py_DECREF(args); + + Py_DECREF(module); + +} + + +/****************************************************************************** +* * * Paramètres : obj = instance GLib crée en C. * * type = type de l'objet Python correspond. * * * @@ -139,17 +184,28 @@ void pychrysalide_set_instance_data(GObject *obj, PyTypeObject *type) data = g_object_get_qdata(obj, pygobject_instance_data_key_fake); + Py_INCREF(type); + if (data == NULL) { data = pygobject_data_new_fake(); + /** + * Dans la majorité des cas, le type est retrouvé depuis un appel à + * PyObject_GetAttrString(), qui fournit une nouvelle référence. + * Donc nul besoin d'incrémenter encore cette référence. + */ data->type = type; - Py_INCREF(type); g_object_set_qdata_full(obj, pygobject_instance_data_key_fake, data, (GDestroyNotify)pygobject_data_free_fake); } + /** + * On décharge l'usage du type : le compteur est déjà bien à jour si + * le (futur) objet est en mémoire. + */ + else Py_DECREF(type); } diff --git a/plugins/pychrysa/quirks.h b/plugins/pychrysa/quirks.h index ca198f3..991fe10 100644 --- a/plugins/pychrysa/quirks.h +++ b/plugins/pychrysa/quirks.h @@ -34,6 +34,9 @@ /* Définit les éléments immuables pour toute association. */ void pychrysalide_init_quirks(void); +/* Modifie les seuils de collecte pour le collecteur de Python. */ +void pychrysalide_set_gc_threshold(int, int, int); + /* Crée l'association précise attendue par Python-GObject. */ void pychrysalide_set_instance_data(GObject *, PyTypeObject *); diff --git a/plugins/python/androperms/androperms.py b/plugins/python/androperms/androperms.py index 18443fc..ddccb8a 100644 --- a/plugins/python/androperms/androperms.py +++ b/plugins/python/androperms/androperms.py @@ -56,8 +56,9 @@ class AndroPerms(Plugin): db = PermsDataBase() db.filter_permissions(plist) + fmt = binary.get_format() instrs = binary.get_instructions() - buffer = binary.disassembled_buffer + buf = binary.disassembled_buffer pfn = re.compile('<.* ([^ ]*)\(') @@ -65,15 +66,20 @@ class AndroPerms(Plugin): if i.keyword.startswith("invoke"): - line = buffer.find_line_by_addr(i.address) + line = buf.find_line_by_addr(i.address) text = line.get_text() - #print "check %s" % text - name = pfn.search(text) if name != None: - #print " --> ", name.group(1) - db.check_call(i.address, name.group(1)) + + resolved = fmt.resolve_relative_routine(i.address) + + if resolved == None: + reladdr = "0x%08x" % i.address + else: + reladdr = "<%s()+0x%x>" % (resolved[0], resolved[1]) + + db.check_call(i.address, name.group(1), reladdr) self._panel.memorize_permissions(binary, db.get_used_permissions()) diff --git a/plugins/python/androperms/db.py b/plugins/python/androperms/db.py index 625d400..7014915 100644 --- a/plugins/python/androperms/db.py +++ b/plugins/python/androperms/db.py @@ -53,7 +53,7 @@ class PermsDataBase: self._used[p] = [] - def check_call(self, addr, line): + def check_call(self, addr, line, reladdr): """Check if a call requires some rights.""" found = False @@ -69,23 +69,23 @@ class PermsDataBase: #if line.find(c) > -1: if c.find(line) > -1: - self._used[p].append([addr, c + "()"]) - #found = True + self._used[p].append([reladdr, c + "()", addr]) + found = True - if not found: + # if not found: - func = line.split('.')[-1] + # func = line.split('.')[-1] - for p in self._perms: + # for p in self._perms: - for c in self._perms[p]: + # for c in self._perms[p]: - if line.find("Wall") > -1: - print " <> ", c, " vs ", func + # if c.find(func) > -1: - if c.find(func) > -1: - self._used[p].append([addr, line + "()"]) - break + # #print ">>> %s found in %s" % (func, c) + + # self._used[p].append([reladdr, line + "()", addr]) + # break def get_used_permissions(self): diff --git a/plugins/python/androperms/panel.py b/plugins/python/androperms/panel.py index bebeed5..b892339 100644 --- a/plugins/python/androperms/panel.py +++ b/plugins/python/androperms/panel.py @@ -41,7 +41,7 @@ def _build_permissions_panel_content(): functions.pack_start(cell, True) functions.add_attribute(cell, 'text', 3) - store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str) + store = gtk.TreeStore(gtk.gdk.Pixbuf, str, gtk.gdk.Pixbuf, str, str) tree.set_model(store) return scrolled_window, tree, store @@ -97,13 +97,13 @@ class PermsPanel(PanelItem): img = os.path.dirname(os.path.abspath(__file__)) + '/android.png' buf = gtk.gdk.pixbuf_new_from_file(img) - it = self._store.append(None, [buf, p, None, None]) + it = self._store.append(None, [buf, p, None, None, None]) img = os.path.dirname(os.path.abspath(__file__)) + '/routine.png' buf = gtk.gdk.pixbuf_new_from_file(img) for f in used[p]: - self._store.append(it, [None, "0x%08x" % f[0], buf, f[1]]) + self._store.append(it, [None, f[0], buf, f[1], f[2]]) self._tree.expand_all() @@ -117,4 +117,4 @@ class PermsPanel(PanelItem): # On ne traite que les lignes de code if model.get_value(it, 0) == None: - self.get_current_view().scroll_to_address(int(model.get_value(it, 1), 16)) + self.get_current_view().scroll_to_address(int(model.get_value(it, 4))) diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 7a191c9..d52b74a 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -48,6 +48,7 @@ struct _GBinRoutine GDataType *namespace; /* Espace de noms / classe */ char *name; /* Désignation humaine */ GDataType *full_name; /* Désignation très complète */ + char *long_name; /* Désignation très complète ??*/ GBinVariable **args; /* Arguments de la routines */ size_t args_count; /* Nombre d'arguments */ @@ -421,7 +422,7 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name) * * ******************************************************************************/ -const char *g_binary_routine_get_name(const GBinRoutine *routine) +const char *g_binary_routine_get_name(GBinRoutine *routine) { if (routine->name == NULL && routine->full_name != NULL) g_binary_routine_set_name(routine, g_data_type_to_string(routine->full_name)); @@ -434,6 +435,40 @@ const char *g_binary_routine_get_name(const GBinRoutine *routine) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * +* * +* Description : Fournit le nom long et humain d'une routine. * +* * +* Retour : Désignation humainement lisible ou NULL si non définie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_routine_get_long_name(GBinRoutine *routine) +{ + if (routine->long_name == NULL) + { + if (routine->namespace != NULL) + { + routine->long_name = strdup(""); + routine->long_name = g_data_type_to_string(routine->namespace); + routine->long_name = stradd(routine->long_name, "." /* FIXME */); + } + else + routine->long_name = strdup(""); + + routine->long_name = stradd(routine->long_name, g_binary_routine_get_name(routine)); + + } + + return routine->long_name; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * * type = désignation complète du nom de la routine. * * * * Description : Définit de façon indirecte le nom humain d'une routine. * diff --git a/src/analysis/routine.h b/src/analysis/routine.h index de28f38..c6de039 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -111,7 +111,10 @@ GDataType *g_binary_routine_get_namespace(const GBinRoutine *); void g_binary_routine_set_name(GBinRoutine *, char *); /* Désignation humainement lisible ou NULL si non définie. */ -const char *g_binary_routine_get_name(const GBinRoutine *); +const char *g_binary_routine_get_name(GBinRoutine *); + +/* Fournit le nom long et humain d'une routine. */ +const char *g_binary_routine_get_long_name(GBinRoutine *); /* Définit de façon indirecte le nom humain d'une routine. */ void g_binary_routine_set_name_from_type(GBinRoutine *, GDataType *); diff --git a/src/format/format.c b/src/format/format.c index c7d95c4..79ef5dd 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -454,6 +454,50 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const char **label } +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* label = étiquette du symbole si trouvé. [OUT] * +* address = adresse à cibler, puis décallage final. [OUT] * +* * +* Description : Recherche une position dans une routine selon une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_format_resolve_relative_routine(const GBinFormat *format, const char **label, vmpa_t *address) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + vmpa_t addr; /* Adresse de symbole */ + off_t size; /* Taille du symole */ + + result = false; + + for (i = 0; i < format->routines_count && !result; i++) + { + addr = g_binary_routine_get_address(format->routines[i]); + size = g_binary_routine_get_size(format->routines[i]); + + if (addr <= *address && *address < (addr + size)) + { + *label = g_binary_routine_get_long_name(format->routines[i]); + *address -= addr; + + result = true; + + } + + } + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* MANIPULATION D'ENSEMBLE DE FORMATS */ diff --git a/src/format/format.h b/src/format/format.h index ef85fbb..fec03ea 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -84,6 +84,9 @@ void g_binary_format_decompile(const GBinFormat *, GCodeBuffer *, const char *fi /* Recherche le symbole correspondant à une adresse. */ bool g_binary_format_resolve_symbol(const GBinFormat *, const char **, SymbolType *, vmpa_t *); +/* Recherche une position dans une routine selon une adresse. */ +bool g_binary_format_resolve_relative_routine(const GBinFormat *, const char **, vmpa_t *); + /* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */ -- cgit v0.11.2-87-g4458