diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/pychrysa/Makefile.am | 5 | ||||
-rw-r--r-- | plugins/pychrysa/analysis/binary.c | 106 | ||||
-rw-r--r-- | plugins/pychrysa/analysis/binary.h | 2 | ||||
-rw-r--r-- | plugins/pychrysa/arch/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/pychrysa/arch/instruction.c | 418 | ||||
-rw-r--r-- | plugins/pychrysa/arch/instruction.h | 55 | ||||
-rw-r--r-- | plugins/pychrysa/arch/module.c | 14 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/Makefile.am | 18 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/bufferline.c | 155 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/bufferline.h | 44 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/codebuffer.c | 159 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/codebuffer.h | 44 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/module.c | 68 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/module.h | 39 | ||||
-rw-r--r-- | plugins/pychrysa/plugin.c | 48 | ||||
-rw-r--r-- | plugins/pychrysa/pychrysa.c | 2 | ||||
-rw-r--r-- | plugins/python/androperms/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/python/androperms/androperms.py | 30 | ||||
-rw-r--r-- | plugins/python/androperms/panel.py | 89 |
19 files changed, 1287 insertions, 21 deletions
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am index a339dab..f8c08db 100644 --- a/plugins/pychrysa/Makefile.am +++ b/plugins/pychrysa/Makefile.am @@ -11,7 +11,8 @@ pychrysa_la_LIBADD = \ analysis/libpychrysaanalysis.la \ arch/libpychrysaarch.la \ debug/libpychrysadebug.la \ - format/libpychrysaformat.la + format/libpychrysaformat.la \ + glibext/libpychrysaglibext.la pychrysa_la_LDFLAGS = -module -avoid-version $(LIBGTK_LIBS) $(LIBXML_LIBS) $(LIBPYTHON_LIBS) \ $(LIBPYGOBJECT_LIBS) \ @@ -25,4 +26,4 @@ AM_CPPFLAGS = AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = analysis arch debug format +SUBDIRS = analysis arch debug format glibext diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c index 4cfb615..44721b5 100644 --- a/plugins/pychrysa/analysis/binary.c +++ b/plugins/pychrysa/analysis/binary.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * binary.c - équivalent Python du fichier "analysis/binary.h" * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -29,6 +29,8 @@ #include "../quirks.h" +#include "../arch/instruction.h" +#include "../glibext/codebuffer.h" @@ -38,6 +40,15 @@ 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); +/* Fournit les instructions issues du désassemblage. */ +static PyObject *py_loaded_binary_get_instructions(PyObject *, PyObject *); + + + +/* Fournit le tampon associé au contenu assembleur d'un binaire. */ +static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *, void *); + + /****************************************************************************** @@ -92,7 +103,7 @@ PyObject *py_loaded_binary_from_c(GOpenidaBinary *binary) PyTypeObject *type; /* Type Python correspondant */ module = PyImport_ImportModule("pychrysalide.analysis"); - type = (PyTypeObject*)PyObject_GetAttrString(module, "LoadedBinary"); + type = (PyTypeObject *)PyObject_GetAttrString(module, "LoadedBinary"); Py_DECREF(module); pychrysalide_set_instance_data(G_OBJECT(binary), type); @@ -102,14 +113,9 @@ PyObject *py_loaded_binary_from_c(GOpenidaBinary *binary) } - - - - - /****************************************************************************** * * -* Paramètres : self = classe représentant un débogueur. * +* Paramètres : self = classe représentant un binaire. * * args = arguments fournis à l'appel. * * * * Description : Fournit le fichier correspondant à l'élément binaire. * @@ -137,6 +143,73 @@ static PyObject *py_loaded_binary_get_filename(PyObject *self, PyObject *args) } +/****************************************************************************** +* * +* Paramètres : self = classe représentant un binaire. * +* args = arguments fournis à l'appel. * +* * +* Description : Fournit les instructions issues du désassemblage. * +* * +* Retour : Instructions issues du désassemblage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_loaded_binary_get_instructions(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + GOpenidaBinary *binary; /* Version native */ + GArchInstruction *instr; /* Première instruction */ + + binary = G_OPENIDA_BINARY(pygobject_get(self)); + + instr = g_openida_binary_get_instructions(binary); + + result = py_arch_instruction_from_c(instr); + + return result; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une instruction. * +* closure = adresse non utilisée ici. * +* * +* Description : Fournit le tampon associé au contenu assembleur d'un binaire.* +* * +* Retour : Valeur associée à la propriété consultée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_loaded_binary_get_disassembled_buffer(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GOpenidaBinary *binary; /* Version native */ + GCodeBuffer *buffer; /* Tampon à récupérer */ + + binary = G_OPENIDA_BINARY(pygobject_get(self)); + buffer = g_openida_binary_get_disassembled_buffer(binary); + + result = py_code_buffer_from_c(buffer); + + return result; + +} + + + + + + + /****************************************************************************** @@ -145,7 +218,7 @@ static PyObject *py_loaded_binary_get_filename(PyObject *self, PyObject *args) * * * Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * @@ -162,6 +235,20 @@ bool register_python_loaded_binary(PyObject *module) METH_NOARGS, "Provide the filename of the loaded binary." }, + { + "get_instructions", (PyCFunction)py_loaded_binary_get_instructions, + METH_NOARGS, + "Give access to all disassembled instructions." + }, + + { NULL } + }; + + static PyGetSetDef py_loaded_binary_getseters[] = { + { + "disassembled_buffer", (getter)py_loaded_binary_get_disassembled_buffer, (setter)NULL, + "Give access to the disassembled code buffer.", NULL + }, { NULL } }; @@ -177,6 +264,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 }; diff --git a/plugins/pychrysa/analysis/binary.h b/plugins/pychrysa/analysis/binary.h index cc96a5b..89e5e59 100644 --- a/plugins/pychrysa/analysis/binary.h +++ b/plugins/pychrysa/analysis/binary.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * binary.h - prototypes pour l'équivalent Python du fichier "analysis/binary.h" * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard * * This file is part of OpenIDA. * diff --git a/plugins/pychrysa/arch/Makefile.am b/plugins/pychrysa/arch/Makefile.am index 6ab3332..fd7c862 100644 --- a/plugins/pychrysa/arch/Makefile.am +++ b/plugins/pychrysa/arch/Makefile.am @@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libpychrysaarch.la libpychrysaarch_la_SOURCES = \ archbase.h archbase.c \ + instruction.h instruction.c \ module.h module.c \ processor.h processor.c @@ -10,7 +11,8 @@ libpychrysaarch_la_SOURCES = \ libpychrysaarch_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) -I../../../src +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../src AM_CPPFLAGS = diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c new file mode 100644 index 0000000..80cc4ee --- /dev/null +++ b/plugins/pychrysa/arch/instruction.c @@ -0,0 +1,418 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction.c - équivalent Python du fichier "arch/instruction.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 + */ + + +#include "instruction.h" + + +#include <pygobject.h> +#include <stdbool.h> +#include <string.h> + + +#include "../quirks.h" + + + +/* --------------------- ITERATEUR POUR BOUCLE SUR INSTRUCTIONS --------------------- */ + + +/* Itérateur pour les instructions */ +typedef struct _PyArchInstructionIter +{ + PyObject_HEAD /* A laisser en premier */ + + GArchInstruction *head; /* Ancrage supposé */ + PyObject *current; /* Départ, puis parcours... */ + bool started; /* Démarrage effectué ? */ + +} PyArchInstructionIter; + + +/* Prépare l'itérateur pour un parcours d'instructions. */ +static PyObject *py_arch_instruction_iterator_create(PyObject *); + +/* Libère la mémoire d'un itérateur de 'ArchInstruction'. */ +static void py_arch_instruction_iterator_dealloc(PyArchInstructionIter *); + +/* Fournit l'élément suivant dans un parcours d'instructions. */ +static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *); + + + +/* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */ + + +/* Crée un nouvel objet Python de type 'ArchInstruction'. */ +static PyObject *py_arch_instruction_new(PyTypeObject *, PyObject *, PyObject *); + +/* Prépare un parcours d'instructions. */ +static PyObject *py_arch_instruction_get_iter(PyObject *); + +/* Fournit la valeur associée à une propriété donnée. */ +static PyObject *py_arch_instruction_get_location(PyObject *, char *); + + + +/* ---------------------------------------------------------------------------------- */ +/* ITERATEUR POUR BOUCLE SUR INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : origin = élément à l'origine du parcours. * +* * +* Description : Prépare l'itérateur pour un parcours d'instructions. * +* * +* Retour : Instance d'itérateur prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_iterator_create(PyObject *origin) +{ + PyArchInstructionIter *result; /* Nouvelle instance à renvoyer*/ + PyObject *module; /* Module d'appartenance */ + PyTypeObject *type; /* Type d'objet à créer */ + + module = PyImport_ImportModule("pychrysalide.arch"); + type = (PyTypeObject *)PyObject_GetAttrString(module, "ArchInstructionIterator"); + Py_DECREF(module); + + result = (PyArchInstructionIter *)type->tp_alloc(type, 0); + + if (result != NULL) + { + result->head = G_ARCH_INSTRUCTION(pygobject_get(origin)); + g_object_ref(G_OBJECT(result->head)); + + Py_INCREF(origin); + result->current = origin; + } + + return (PyObject *)result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = instance d'objet à supprimer. * +* * +* Description : Libère la mémoire d'un itérateur de 'ArchInstruction'. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_arch_instruction_iterator_dealloc(PyArchInstructionIter *self) +{ + g_object_unref(G_OBJECT(self->head)); + Py_DECREF(self->current); + +#if PY_VERSION_HEX < 0x03000000 + self->ob_type->tp_free((PyObject *)self); +#else + Py_TYPE(self)->tp_free((PyObject *)self); +#endif + +} + + +/****************************************************************************** +* * +* Paramètres : self = instance manipulée à traiter. * +* * +* Description : Fournit l'élément suivant dans un parcours d'instructions. * +* * +* Retour : Point suivant du parcours ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *self) +{ + PyObject *result; /* Elément à retourner */ + GArchInstruction *next; /* Elément réel suivant */ + + if (!self->started) + { + self->started = true; + result = self->current; + } + else + { + next = G_ARCH_INSTRUCTION(pygobject_get(self->current)); + next = g_arch_instruction_get_next_iter(self->head, next, VMPA_MAX); + + if (next != NULL) + { + result = py_arch_instruction_from_c(next); + + Py_INCREF(result); + Py_DECREF(self->current); + self->current = result; + + } + else result = NULL; + + } + + return (PyObject *)result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Permet une itération de 'pychrysalide.arch.ArchInstruction'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_arch_instruction_iterator(PyObject *module) +{ + int ret; /* Bilan d'un appel */ + + static PyTypeObject py_arch_instruction_iterator_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.arch.ArchInstructionIterator", + .tp_basicsize = sizeof(PyArchInstructionIter), + + .tp_dealloc = (destructor)py_arch_instruction_iterator_dealloc, + + .tp_flags = Py_TPFLAGS_HAVE_ITER | Py_TPFLAGS_HAVE_CLASS, + + .tp_doc = "PyChrysalide architecture instruction iterator", + + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)py_arch_instruction_iterator_next + + }; + + if (PyType_Ready(&py_arch_instruction_iterator_type) < 0) + return false; + + Py_INCREF(&py_arch_instruction_iterator_type); + ret = PyModule_AddObject(module, "ArchInstructionIterator", (PyObject *)&py_arch_instruction_iterator_type); + + return (ret == 0); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INSTRUCTIONS D'ARCHITECTURES EN PYTHON */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* 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 'ArchInstruction'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +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)); + +} + + +/****************************************************************************** +* * +* Paramètres : self = instance manipulée à traiter. * +* * +* Description : Prépare un parcours d'instructions. * +* * +* Retour : Point de départ d'un parcours. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_get_iter(PyObject *self) +{ + return py_arch_instruction_iterator_create(self); + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une instruction. * +* name = nom de la propriété à lire. * +* * +* Description : Fournit la valeur associée à une propriété donnée. * +* * +* Retour : Valeur associée à la propriété consultée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_get_location(PyObject *self, char *name) +{ + PyObject *result; /* Trouvailles à retourner */ + GArchInstruction *instr; /* Version native */ + off_t offset; /* Position dans le fichier */ + off_t length; /* Taille de l'instruction */ + vmpa_t address; /* Position en mémoire */ + + instr = G_ARCH_INSTRUCTION(pygobject_get(self)); + g_arch_instruction_get_location(instr, &offset, &length, &address); + + if (strcmp(name, "offset") == 0) + result = PyLong_FromLong(offset); + + else if (strcmp(name, "") == 0) + result = PyLong_FromLong(length); + + else /*if (strcmp(name, "") == 0)*/ + result = PyLong_FromLongLong(address); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_arch_instruction(PyObject *module) +{ + PyObject *pygobj_mod; /* Module Python-GObject */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_arch_instruction_methods[] = { + { NULL } + }; + + static PyGetSetDef py_arch_instruction_getseters[] = { + { + "offset", (getter)py_arch_instruction_get_location, (setter)NULL, + "Provide the location of the instruction in the binary file.", "offset" + }, + { + "length", (getter)py_arch_instruction_get_location, (setter)NULL, + "Provide the length of the instruction.", "length" + }, + { + "address", (getter)py_arch_instruction_get_location, (setter)NULL, + "Provide the location of the instruction in memory.", "address" + }, + { NULL } + }; + + static PyTypeObject py_arch_instruction_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.arch.ArchInstruction", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide architecture instruction", + + .tp_methods = py_arch_instruction_methods, + .tp_getset = py_arch_instruction_getseters, + .tp_new = (newfunc)py_arch_instruction_new, + + .tp_iter = (getiterfunc)py_arch_instruction_get_iter + + }; + + pygobj_mod = PyImport_ImportModule("gobject"); + if (pygobj_mod == NULL) return false; + + py_arch_instruction_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); + Py_DECREF(pygobj_mod); + + if (PyType_Ready(&py_arch_instruction_type) < 0) + return false; + + Py_INCREF(&py_arch_instruction_type); + ret = PyModule_AddObject(module, "ArchInstruction", (PyObject *)&py_arch_instruction_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/arch/instruction.h b/plugins/pychrysa/arch/instruction.h new file mode 100644 index 0000000..545d88e --- /dev/null +++ b/plugins/pychrysa/arch/instruction.h @@ -0,0 +1,55 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction.h - prototypes pour l'équivalent Python du fichier "arch/instruction.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_PYOIDA_ARCH_INSTRUCTION_H +#define _PLUGINS_PYOIDA_ARCH_INSTRUCTION_H + + +#include <Python.h> +#include <stdbool.h> + +#include <arch/instruction.h> + + + +/* --------------------- ITERATEUR POUR BOUCLE SUR INSTRUCTIONS --------------------- */ + + +/* Permet une itération de 'pychrysalide.arch.ArchInstruction'. */ +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 *); + + + +#endif /* _PLUGINS_PYOIDA_ARCH_INSTRUCTION_H */ diff --git a/plugins/pychrysa/arch/module.c b/plugins/pychrysa/arch/module.c index 59b0c2c..8092b6b 100644 --- a/plugins/pychrysa/arch/module.c +++ b/plugins/pychrysa/arch/module.c @@ -25,8 +25,7 @@ #include "module.h" -#include "archbase.h" -#include "processor.h" +#include "instruction.h" @@ -54,18 +53,19 @@ bool add_arch_module_to_python_module(PyObject *super) { NULL } }; - module = Py_InitModule("pyoida.arch", py_arch_methods); + module = Py_InitModule("pychrysalide.arch", py_arch_methods); if (module == NULL) return false; Py_INCREF(module); - ret = PyModule_AddObject(super, "pyoida.arch", module); + ret = PyModule_AddObject(super, "pychrysalide.arch", module); - if (ret != 0) /* ... */; + result = (ret != 0); - result = add_arch_vmpa_to_python_module(module); - result = add_arch_processor_to_python_module(module); + if (ret != 0) /* ... */; + result &= register_python_arch_instruction(module); + result &= register_python_arch_instruction_iterator(module); return true; diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am new file mode 100644 index 0000000..da33fb6 --- /dev/null +++ b/plugins/pychrysa/glibext/Makefile.am @@ -0,0 +1,18 @@ + +noinst_LTLIBRARIES = libpychrysaglibext.la + +libpychrysaglibext_la_SOURCES = \ + bufferline.h bufferline.c \ + codebuffer.h codebuffer.c \ + module.h module.c + + +libpychrysaglibext_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/glibext/bufferline.c b/plugins/pychrysa/glibext/bufferline.c new file mode 100644 index 0000000..1e3b611 --- /dev/null +++ b/plugins/pychrysa/glibext/bufferline.c @@ -0,0 +1,155 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * bufferline.c - équivalent Python du fichier "glibext/gbufferline.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 + */ + + +#include "bufferline.h" + + +#include <malloc.h> +#include <pygobject.h> + + +#include "../quirks.h" + + + +/* Reconstruit et fournit le texte présent sur une ligne tampon. */ +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. * +* * +* Description : Reconstruit et fournit le texte présent sur une ligne tampon.* +* * +* Retour : Texte reconstruit pour l'occasion. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_line_get_text(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + GBufferLine *line; /* Version native */ + char *text; /* Texte reconstruit à libérer */ + + line = G_BUFFER_LINE(pygobject_get(self)); + text = g_buffer_line_get_text(line); + + result = PyString_FromString(text); + + free(text); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.BufferLine'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_buffer_line(PyObject *module) +{ + PyObject *pygobj_mod; /* Module Python-GObject */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_buffer_line_methods[] = { + { + "get_text", (PyCFunction)py_buffer_line_get_text, + METH_NOARGS, + "Rebuild and provide the text of a buffer line." + }, + { NULL } + }; + + static PyTypeObject py_buffer_line_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.glibext.BufferLine", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide buffer line", + + .tp_methods = py_buffer_line_methods + + }; + + pygobj_mod = PyImport_ImportModule("gobject"); + if (pygobj_mod == NULL) return false; + + py_buffer_line_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); + Py_DECREF(pygobj_mod); + + if (PyType_Ready(&py_buffer_line_type) < 0) + return false; + + Py_INCREF(&py_buffer_line_type); + ret = PyModule_AddObject(module, "BufferLine", (PyObject *)&py_buffer_line_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/glibext/bufferline.h b/plugins/pychrysa/glibext/bufferline.h new file mode 100644 index 0000000..d15928f --- /dev/null +++ b/plugins/pychrysa/glibext/bufferline.h @@ -0,0 +1,44 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * bufferline.h - prototypes pour l'équivalent Python du fichier "glibext/bufferline.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_GLIBEXT_BUFFERLINE_H +#define _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERLINE_H + + +#include <Python.h> +#include <stdbool.h> + +#include <glibext/gbufferline.h> + + + +/* 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 *); + + + +#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_BUFFERLINE_H */ diff --git a/plugins/pychrysa/glibext/codebuffer.c b/plugins/pychrysa/glibext/codebuffer.c new file mode 100644 index 0000000..a090e27 --- /dev/null +++ b/plugins/pychrysa/glibext/codebuffer.c @@ -0,0 +1,159 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * codebuffer.c - équivalent Python du fichier "glibext/gcodebuffer.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 + */ + + +#include "codebuffer.h" + + +#include <pygobject.h> + + +#include "../quirks.h" + + + +/* Retrouve une ligne au sein d'un tampon avec une adresse. */ +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. * +* * +* Description : Retrouve une ligne au sein d'un tampon avec une adresse. * +* * +* Retour : Instance de la ligne trouvée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + GCodeBuffer *buffer; /* Version native */ + vmpa_t addr; /* Adresse visée par l'opérat° */ + int ret; /* Bilan de lecture des args. */ + GBufferLine *line; /* Ligne trouvée */ + + buffer = G_CODE_BUFFER(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "K", &addr); + if (!ret) return Py_None; + + line = g_code_buffer_find_line_by_addr(buffer, addr); + if (line == NULL) return Py_None; + + result = py_buffer_line_from_c(line); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.Codebuffer'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_code_buffer(PyObject *module) +{ + PyObject *pygobj_mod; /* Module Python-GObject */ + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_code_buffer_methods[] = { + { + "find_line_by_addr", (PyCFunction)py_code_buffer_find_line_by_addr, + METH_VARARGS, + "Find a buffer line with a given address." + }, + { NULL } + }; + + static PyTypeObject py_code_buffer_type = { + + PyObject_HEAD_INIT(NULL) + + .tp_name = "pychrysalide.glibext.CodeBuffer", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide code buffer", + + .tp_methods = py_code_buffer_methods + + }; + + pygobj_mod = PyImport_ImportModule("gobject"); + if (pygobj_mod == NULL) return false; + + py_code_buffer_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(pygobj_mod, "GObject"); + Py_DECREF(pygobj_mod); + + if (PyType_Ready(&py_code_buffer_type) < 0) + return false; + + Py_INCREF(&py_code_buffer_type); + ret = PyModule_AddObject(module, "CodeBuffer", (PyObject *)&py_code_buffer_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/glibext/codebuffer.h b/plugins/pychrysa/glibext/codebuffer.h new file mode 100644 index 0000000..ba53fda --- /dev/null +++ b/plugins/pychrysa/glibext/codebuffer.h @@ -0,0 +1,44 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * codebuffer.h - prototypes pour l'équivalent Python du fichier "glibext/codebuffer.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_GLIBEXT_CODEBUFFER_H +#define _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H + + +#include <Python.h> +#include <stdbool.h> + +#include <glibext/gcodebuffer.h> + + + +/* 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 *); + + + +#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_CODEBUFFER_H */ diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c new file mode 100644 index 0000000..b2ba4ab --- /dev/null +++ b/plugins/pychrysa/glibext/module.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire glibext 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 "bufferline.h" +#include "codebuffer.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'glibext' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_glibext_module_to_python_module(PyObject *super) +{ + bool result; + PyObject *module; + int ret; /* Bilan d'un appel */ + + static PyMethodDef py_glibext_methods[] = { + { NULL } + }; + + module = Py_InitModule("pychrysalide.glibext", py_glibext_methods); + if (module == NULL) return false; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "pychrysalide.glibext", module); + + result = (ret != 0); + + result &= register_python_buffer_line(module); + result &= register_python_code_buffer(module); + + return result; + +} diff --git a/plugins/pychrysa/glibext/module.h b/plugins/pychrysa/glibext/module.h new file mode 100644 index 0000000..a68ecb8 --- /dev/null +++ b/plugins/pychrysa/glibext/module.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire glibext 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_PYOIDA_GLIBEXT_MODULE_H +#define _PLUGINS_PYOIDA_GLIBEXT_MODULE_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Ajoute le module 'glibext' au module Python. */ +bool add_glibext_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_GLIBEXT_MODULE_H */ diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c index 9dc0c29..6d8a494 100644 --- a/plugins/pychrysa/plugin.c +++ b/plugins/pychrysa/plugin.c @@ -482,7 +482,6 @@ static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *plu - /****************************************************************************** * * * Paramètres : plugin = greffon de prise en charge à utiliser. * @@ -749,6 +748,50 @@ static PyObject *pychrysa_plugin_run(PyObject *self, PyObject *args) +#include <pygtk-2.0/pygobject.h> + +static int convert_to_w(PyGObject *obj, void **out) +{ + + //if (!pygobject_check(obj, + + *out = pygobject_get(obj); + + return (1); + +} + + +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; + +} + + + + + + /****************************************************************************** * * @@ -780,6 +823,9 @@ static PyMethodDef pychrysa_plugin_methods[] = { { "run", (PyCFunction)pychrysa_plugin_run, 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 7bb1e00..8b9fc50 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -37,6 +37,7 @@ #include "arch/module.h" #include "debug/module.h" #include "format/module.h" +#include "glibext/module.h" /* #include "analysis/py_binary.h" @@ -265,6 +266,7 @@ PyMODINIT_FUNC initpychrysa(void) add_arch_module_to_python_module(module); add_debug_module_to_python_module(module); add_format_module_to_python_module(module); + add_glibext_module_to_python_module(module); add_log_to_python_module(module); add_plugin_to_python_module(module); diff --git a/plugins/python/androperms/Makefile.am b/plugins/python/androperms/Makefile.am index 3d1755c..f44be3c 100644 --- a/plugins/python/androperms/Makefile.am +++ b/plugins/python/androperms/Makefile.am @@ -3,10 +3,18 @@ andropermsdir = $(datadir)/openida/plugins/python/androperms androperms_DATA = \ __init__.py \ + androperms.db \ androperms.py \ defs.py \ manifest.py \ + panel.py \ parser.py \ reader.py \ stack.py \ string.py + +androperms.db: + @tmpzip=`tempfile` ; \ + wget http://www.android-permissions.org/permissionmap.zip -O $$tmpzip ; \ + unzip -p $$tmpzip permissionmap/APICalls.txt | tail -n +2 - > androperms.db ; \ + rm $$tmpzip diff --git a/plugins/python/androperms/androperms.py b/plugins/python/androperms/androperms.py index f85d402..0d70edc 100644 --- a/plugins/python/androperms/androperms.py +++ b/plugins/python/androperms/androperms.py @@ -3,8 +3,10 @@ from pychrysalide import Plugin from manifest import AndroidManifest +from panel import PermsPanel from xml.dom import minidom +import gtk import zipfile @@ -35,7 +37,35 @@ class AndroPerms(Plugin): print "-------------" print + plist = [] + for p in xml.getElementsByTagName("uses-permission"): + plist.append(p.getAttribute("android:name")) print p.getAttribute("android:name") print + + button = gtk.Button("Hello World") + button.show() + + treestore = gtk.TreeStore(str, str, str) + + + panel = PermsPanel() + + + panel.filter_permissions(plist) + + #self.add_wgt(panel.get_widget()) + + instrs = binary.get_instructions() + + for i in instrs: + # print i, " :: 0x%08lx" % i.address + + line = binary.disassembled_buffer.find_line_by_addr(i.address) + text = line.get_text() + + if text.startswith("invoke"): + #print "[0x%08lx] " % i.address, text + pass diff --git a/plugins/python/androperms/panel.py b/plugins/python/androperms/panel.py new file mode 100644 index 0000000..b852049 --- /dev/null +++ b/plugins/python/androperms/panel.py @@ -0,0 +1,89 @@ + +import gtk +import os + + +class PermsPanel: + """Display all permissions found in the Manifest.""" + + def __init__(self): + + + tree = gtk.TreeView() + + languages = gtk.TreeViewColumn() + languages.set_title("Programming languages") + + cell = gtk.CellRendererText() + languages.pack_start(cell, True) + languages.add_attribute(cell, "text", 0) + + treestore = gtk.TreeStore(str) + + it = treestore.append(None, ["Scripting languages"]) + treestore.append(it, ["Python"]) + treestore.append(it, ["PHP"]) + treestore.append(it, ["Perl"]) + treestore.append(it, ["Ruby"]) + + it = treestore.append(None, ["Compiling languages"]) + treestore.append(it, ["C#"]) + treestore.append(it, ["C++"]) + treestore.append(it, ["C"]) + treestore.append(it, ["Java"]) + + tree.append_column(languages) + tree.set_model(treestore) + + tree.show() + + self._view = tree + + self._perms = { } + + self._load_all_definitions() + + + def get_widget(self): + + return self._view + + + + + + def _load_all_definitions(self): + """Load the database in memory.""" + + with open(os.path.dirname(__file__) + '/androperms.db', 'r') as f: + + for line in f.readlines(): + + perm = line.strip("\n").split("\t") + + for p in perm[1].split(" "): + + if not p.startswith("android.permission."): + continue + + if p not in self._perms: + self._perms[p] = [] + + self._perms[p].append(perm[0]) + + + def filter_permissions(self, used): + """Forget all permissions which are not used.""" + + keep = {} + + for p in self._perms: + if p in used: + keep[p] = self._perms[p] + + self._perms = keep + + # for p in self._perms: + # print p + # for v in self._perms[p]: + # print " - ", v |