diff options
Diffstat (limited to 'plugins/pychrysa')
| -rw-r--r-- | plugins/pychrysa/Makefile.am | 16 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/Makefile.am | 19 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/binaries/file.c | 116 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/binaries/file.h | 7 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/binaries/module.c | 43 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/binaries/module.h | 2 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/binary.c | 102 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/binary.h | 3 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/module.c | 92 | ||||
| -rw-r--r-- | plugins/pychrysa/analysis/module.h | 6 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/Makefile.am | 10 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/archbase.h | 20 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/instruction.c | 2 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/module.c | 47 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/module.h | 6 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/vmpa.c | 325 | ||||
| -rw-r--r-- | plugins/pychrysa/arch/vmpa.h | 42 | ||||
| -rw-r--r-- | plugins/pychrysa/pychrysa.c | 179 | ||||
| -rw-r--r-- | plugins/pychrysa/pychrysa.h | 27 | ||||
| -rw-r--r-- | plugins/pychrysa/quirks.c | 2 | 
20 files changed, 980 insertions, 86 deletions
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am index 3032c0e..8664193 100644 --- a/plugins/pychrysa/Makefile.am +++ b/plugins/pychrysa/Makefile.am @@ -1,5 +1,5 @@ -pkglib_LTLIBRARIES = pychrysa.la +pkglib_LTLIBRARIES = pychrysa.la pychrysalide.la  pychrysa_la_SOURCES =					\  	helpers.h helpers.c					\ @@ -22,6 +22,20 @@ pychrysa_la_LDFLAGS = -module -avoid-version $(LIBGTK_LIBS) $(LIBXML_LIBS) $(LIB  	-L../../src/plugins/.libs -lplugins +pychrysalide_la_SOURCES =				\ +	pychrysa.h pychrysa.c + +pychrysalide_la_LIBADD =				\ +	analysis/libpychrysaanalysis.la		\ +	arch/libpychrysaarch.la + +pychrysalide_la_LDFLAGS = -module -avoid-version \ +	$(LIBPYTHON_LIBS) $(LIBSQLITE_LIBS) $(LIBARCHIVE_LIBS) \ +	-L../../src/.libs -lchrysadisass -lchrysagtkext \ +	-L../../src/plugins/.libs -lplugins + + +  AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \  	-I../../src diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am index f970d94..9b9ac18 100644 --- a/plugins/pychrysa/analysis/Makefile.am +++ b/plugins/pychrysa/analysis/Makefile.am @@ -3,14 +3,21 @@ noinst_LTLIBRARIES = libpychrysaanalysis.la  libpychrysaanalysis_la_SOURCES =		\  	binary.h binary.c					\ -	block.h block.c						\ -	module.h module.c					\ -	roptions.h roptions.c				\ -	routine.h routine.c +	module.h module.c  libpychrysaanalysis_la_LIBADD =			\ -	binaries/libpychrysaanalysisbinaries.la	\ -	blocks/libpychrysaanalysisblocks.la +	binaries/libpychrysaanalysisbinaries.la + +# libpychrysaanalysis_la_SOURCES =		\ +# 	binary.h binary.c					\ +# 	block.h block.c						\ +# 	module.h module.c					\ +# 	roptions.h roptions.c				\ +# 	routine.h routine.c + +# libpychrysaanalysis_la_LIBADD =			\ +# 	binaries/libpychrysaanalysisbinaries.la	\ +# 	blocks/libpychrysaanalysisblocks.la  libpychrysaanalysis_la_LDFLAGS =  diff --git a/plugins/pychrysa/analysis/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c index 2b2a460..28bfecb 100644 --- a/plugins/pychrysa/analysis/binaries/file.c +++ b/plugins/pychrysa/analysis/binaries/file.c @@ -25,20 +25,21 @@  #include "file.h" -  #include <pygobject.h>  #include <analysis/binaries/file.h> +#include "../binary.h" -/* Crée un nouvel objet Python de type 'FileBinary'. */ -static PyObject *py_file_binary_new(PyTypeObject *, PyObject *, PyObject *); - +/* Crée un nouvel objet Python de type 'BinaryFile'. */ +static PyObject *py_binary_file_new(PyTypeObject *, PyObject *, PyObject *); +/* Fournit le chemin d'accès au binaire représenté. */ +static PyObject *py_binary_file_get_filename(PyObject *, void *); @@ -48,7 +49,7 @@ static PyObject *py_file_binary_new(PyTypeObject *, PyObject *, PyObject *);  *                args = arguments fournis à l'appel.                          *  *                kwds = arguments de type key=val fournis.                    *  *                                                                             * -*  Description : Crée un nouvel objet Python de type 'FileBinary'.            * +*  Description : Crée un nouvel objet Python de type 'BinaryFile'.            *  *                                                                             *  *  Retour      : Instance Python mise en place.                               *  *                                                                             * @@ -56,7 +57,7 @@ static PyObject *py_file_binary_new(PyTypeObject *, PyObject *, PyObject *);  *                                                                             *  ******************************************************************************/ -static PyObject *py_file_binary_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static PyObject *py_binary_file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)  {      PyObject *result;                       /* Instance à retourner        */      char *filename;                         /* Nom du fichier à charger    */ @@ -69,74 +70,121 @@ static PyObject *py_file_binary_new(PyTypeObject *type, PyObject *args, PyObject      binary = g_file_binary_new_from_file(filename);      result = pygobject_new(G_OBJECT(binary)); -    //g_object_unref(binary); +    g_object_unref(binary);      return result;  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : self    = NULL car méthode statique.                         * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Fournit le chemin d'accès au binaire représenté.             * +*                                                                             * +*  Retour      : Chemin d'accès en Python.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +static PyObject *py_binary_file_get_filename(PyObject *self, void *closure) +{ +    const GFileBinary *file;                /* Fichier binaire concerné    */ +    const char *filename;                   /* Chemin d'accès à diffuser   */ + +    file = G_FILE_BINARY(pygobject_get(self)); +    filename = g_file_binary_get_filename(file, true); +    return PyUnicode_FromString(filename); + +}  /******************************************************************************  *                                                                             * -*  Paramètres  : module = module dont la définition est à compléter.          * +*  Paramètres  : -                                                            *  *                                                                             * -*  Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* +*  Description : Fournit un accès à une définition de type à diffuser.        *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : Définition d'objet pour Python.                              *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool register_python_file_binary(PyObject *module) +PyTypeObject *get_python_binary_file_type(void)  { -    PyObject *parent_mod;                   /* Module Python-LoadedBinary  */ -    int ret;                                /* Bilan d'un appel            */ - -    static PyMethodDef py_file_binary_methods[] = { +    static PyMethodDef py_binary_file_methods[] = {          { NULL }      }; -    static PyGetSetDef py_file_binary_getseters[] = { +    static PyGetSetDef py_binary_file_getseters[] = { +        { +            "filename", py_binary_file_get_filename, NULL, +            "Show the filename of the loaded binary file.", NULL +        },          { NULL }      }; -    static PyTypeObject py_file_binary_type = { +    static PyTypeObject py_binary_file_type = { -        PyObject_HEAD_INIT(NULL) +        PyVarObject_HEAD_INIT(NULL, 0) -        .tp_name        = "pychrysalide.analysis.binaries.FileBinary", +        .tp_name        = "pychrysalide.analysis.binaries.BinaryFile",          .tp_basicsize   = sizeof(PyGObject), -        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +        .tp_flags       = Py_TPFLAGS_DEFAULT, -        .tp_doc         = "PyChrysalide file binary", +        .tp_doc         = "PyChrysalide binary file", -        .tp_methods     = py_file_binary_methods, -        .tp_getset      = py_file_binary_getseters, -        .tp_new         = (newfunc)py_file_binary_new +        .tp_methods     = py_binary_file_methods, +        .tp_getset      = py_binary_file_getseters, +        .tp_new         = (newfunc)py_binary_file_new      }; -    parent_mod = PyImport_ImportModule("pychrysalide.analysis"); -    if (parent_mod == NULL) return false; +    return &py_binary_file_type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_binary_file(PyObject *module) +{ +    PyTypeObject *py_binary_file_type;      /* Type Python 'LoadedBinary'  */ +    int ret;                                /* Bilan d'un appel            */ +    PyObject *dict;                         /* Dictionnaire du module      */ + +    py_binary_file_type = get_python_binary_file_type(); -    py_file_binary_type.tp_base = (PyTypeObject *)PyObject_GetAttrString(parent_mod, "LoadedBinary"); -    Py_DECREF(parent_mod); +    py_binary_file_type->tp_base = get_python_loaded_binary_type(); +    py_binary_file_type->tp_basicsize = py_binary_file_type->tp_base->tp_basicsize; -    if (PyType_Ready(&py_file_binary_type) < 0) +    if (PyType_Ready(py_binary_file_type) < 0)          return false; -    Py_INCREF(&py_file_binary_type); -    ret = PyModule_AddObject(module, "FileBinary", (PyObject *)&py_file_binary_type); +    Py_INCREF(py_binary_file_type); +    ret = PyModule_AddObject(module, "BinaryFile", (PyObject *)py_binary_file_type); +    if (ret != 0) return false; -    pygobject_register_class(module, "GFileBinary", G_TYPE_FILE_BINARY, &py_file_binary_type, -                             Py_BuildValue("(O)", py_file_binary_type.tp_base)); +    dict = PyModule_GetDict(module); +    pygobject_register_class(dict, "BinaryFile", G_TYPE_FILE_BINARY, py_binary_file_type, +                             Py_BuildValue("(O)", py_binary_file_type->tp_base)); -    return (ret == 0); +    return true;  } diff --git a/plugins/pychrysa/analysis/binaries/file.h b/plugins/pychrysa/analysis/binaries/file.h index 2ba9ed0..b381379 100644 --- a/plugins/pychrysa/analysis/binaries/file.h +++ b/plugins/pychrysa/analysis/binaries/file.h @@ -31,8 +31,11 @@ -/* Prend en charge l'objet 'pychrysalide.analysis.binaries.FileBinary'. */ -bool register_python_file_binary(PyObject *); +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_binary_file_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.binaries.BinaryFile'. */ +bool register_python_binary_file(PyObject *); diff --git a/plugins/pychrysa/analysis/binaries/module.c b/plugins/pychrysa/analysis/binaries/module.c index aae0a33..c2adddf 100644 --- a/plugins/pychrysa/analysis/binaries/module.c +++ b/plugins/pychrysa/analysis/binaries/module.c @@ -41,25 +41,50 @@  *                                                                             *  ******************************************************************************/ -bool add_binaries_module_to_python_module(PyObject *super) +bool add_analysis_binaries_module_to_python_module(PyObject *super)  { -    bool result; -    PyObject *module; +    bool result;                            /* Bilan à retourner           */ +    PyObject *module;                       /* Sous-module mis en place    */      int ret;                                /* Bilan d'un appel            */ -    static PyMethodDef py_format_methods[] = { -        { NULL } +    static PyModuleDef py_chrysalide_arch_module = { + +        .m_base = PyModuleDef_HEAD_INIT, + +        .m_name = "pychrysalide.analysis.binaries", +        .m_doc = "Python module for Chrysalide.analysis.binaries", + +        .m_size = -1, +      }; -    module = Py_InitModule("pychrysalide.analysis.binaries", py_format_methods); +    result = false; + +    module = PyModule_Create(&py_chrysalide_arch_module);      if (module == NULL) return false; +    ret = PyState_AddModule(super, &py_chrysalide_arch_module); +    if (ret != 0) goto aabmtpm_exit; + +    ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.binaries"); +    if (ret != 0) goto aabmtpm_exit; +      Py_INCREF(module); -    ret = PyModule_AddObject(super, "pychrysalide.analysis.binaries", module); +    ret = PyModule_AddObject(super, "binaries", module); +    if (ret != 0) goto aabmtpm_exit; + +    result = true; + +    result &= register_python_binary_file(module); + + aabmtpm_exit: -    result = (ret == 0); +    if (!result) +    { +        printf("something went wrong in %s...\n", __FUNCTION__); +        /* ... */ -    result &= register_python_file_binary(module); +    }      return result; diff --git a/plugins/pychrysa/analysis/binaries/module.h b/plugins/pychrysa/analysis/binaries/module.h index 1fd62d0..653f7da 100644 --- a/plugins/pychrysa/analysis/binaries/module.h +++ b/plugins/pychrysa/analysis/binaries/module.h @@ -32,7 +32,7 @@  /* Ajoute le module 'binaries' au module Python. */ -bool add_binaries_module_to_python_module(PyObject *); +bool add_analysis_binaries_module_to_python_module(PyObject *); diff --git a/plugins/pychrysa/analysis/binary.c b/plugins/pychrysa/analysis/binary.c index c570cf9..807df7e 100644 --- a/plugins/pychrysa/analysis/binary.c +++ b/plugins/pychrysa/analysis/binary.c @@ -28,6 +28,105 @@  #include <pygobject.h> + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Fournit un accès à une définition de type à diffuser.        * +*                                                                             * +*  Retour      : Définition d'objet pour Python.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyTypeObject *get_python_loaded_binary_type(void) +{ +    static PyTypeObject py_loaded_binary_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name = "pychrysalide.analysis.LoadedBinary", + +        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + +        .tp_doc = "PyChrysalide loaded binary", + +    }; + +    return &py_loaded_binary_type; + +} + + + +#include <analysis/binary.h> + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.arch.loaded_binary'.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_loaded_binary(PyObject *module) +{ +    PyTypeObject *py_loaded_binary_type;    /* Type Python 'LoadedBinary'  */ +    int ret;                                /* Bilan d'un appel            */ +    PyObject *dict;                         /* Dictionnaire du module      */ + +    py_loaded_binary_type = get_python_loaded_binary_type(); + +    py_loaded_binary_type->tp_base = &PyGObject_Type; +    py_loaded_binary_type->tp_basicsize = py_loaded_binary_type->tp_base->tp_basicsize; + +    if (PyType_Ready(py_loaded_binary_type) != 0) +        return false; + +    Py_INCREF(py_loaded_binary_type); +    ret = PyModule_AddObject(module, "LoadedBinary", (PyObject *)py_loaded_binary_type); +    if (ret != 0) return false; + +    dict = PyModule_GetDict(module); +    pygobject_register_class(dict, "LoadedBinary", G_TYPE_LOADED_BINARY, py_loaded_binary_type, +                             Py_BuildValue("(O)", py_loaded_binary_type->tp_base)); + +    return true; + +} + + + + + + + + + + + + +#if 0 + + +#include <pygobject.h> + +  #include <analysis/binary.h> @@ -258,3 +357,6 @@ bool register_python_loaded_binary(PyObject *module)      return (ret == 0);  } + +#endif + diff --git a/plugins/pychrysa/analysis/binary.h b/plugins/pychrysa/analysis/binary.h index cb78024..83ea7c7 100644 --- a/plugins/pychrysa/analysis/binary.h +++ b/plugins/pychrysa/analysis/binary.h @@ -31,6 +31,9 @@ +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_loaded_binary_type(void); +  /* 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 54509a8..e13c8f8 100644 --- a/plugins/pychrysa/analysis/module.c +++ b/plugins/pychrysa/analysis/module.c @@ -26,6 +26,97 @@  #include "binary.h" +#include "binaries/module.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Ajoute le module 'analysis' au module Python.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool add_analysis_module_to_python_module(PyObject *super) +{ +    bool result;                            /* Bilan à retourner           */ +    PyObject *module;                       /* Sous-module mis en place    */ +    int ret;                                /* Bilan d'un appel            */ + +    static PyModuleDef py_chrysalide_arch_module = { + +        .m_base = PyModuleDef_HEAD_INIT, + +        .m_name = "pychrysalide.analysis", +        .m_doc = "Python module for Chrysalide.analysis", + +        .m_size = -1, + +    }; + +    result = false; + +    module = PyModule_Create(&py_chrysalide_arch_module); +    if (module == NULL) return false; + +    ret = PyState_AddModule(super, &py_chrysalide_arch_module); +    if (ret != 0) goto aamtpm_exit; + +    ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis"); +    if (ret != 0) goto aamtpm_exit; + +    Py_INCREF(module); +    ret = PyModule_AddObject(super, "analysis", module); +    if (ret != 0) goto aamtpm_exit; + +    result = true; + +    result &= register_python_loaded_binary(module); + +    result &= add_analysis_binaries_module_to_python_module(module); + + aamtpm_exit: + +    if (!result) +    { +        printf("something went wrong in %s...\n", __FUNCTION__); +        /* ... */ + +    } + +    return result; + +} + + + + + + + + + + + + + + + + + + + + + + + +#if 0 +#include "binary.h"  #include "block.h"  #include "routine.h"  #include "binaries/module.h" @@ -72,3 +163,4 @@ bool add_analysis_module_to_python_module(PyObject *super)      return result;  } +#endif diff --git a/plugins/pychrysa/analysis/module.h b/plugins/pychrysa/analysis/module.h index 0ff1167..bc4a65e 100644 --- a/plugins/pychrysa/analysis/module.h +++ b/plugins/pychrysa/analysis/module.h @@ -22,8 +22,8 @@   */ -#ifndef _PLUGINS_PYOIDA_ANALYSIS_MODULE_H -#define _PLUGINS_PYOIDA_ANALYSIS_MODULE_H +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_MODULE_H  #include <Python.h> @@ -36,4 +36,4 @@ bool add_analysis_module_to_python_module(PyObject *); -#endif  /* _PLUGINS_PYOIDA_ANALYSIS_MODULE_H */ +#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_MODULE_H */ diff --git a/plugins/pychrysa/arch/Makefile.am b/plugins/pychrysa/arch/Makefile.am index a01d570..54b9261 100644 --- a/plugins/pychrysa/arch/Makefile.am +++ b/plugins/pychrysa/arch/Makefile.am @@ -2,10 +2,14 @@  noinst_LTLIBRARIES = libpychrysaarch.la  libpychrysaarch_la_SOURCES =			\ -	archbase.h archbase.c				\ -	instruction.h instruction.c			\  	module.h module.c					\ -	processor.h processor.c +	vmpa.h vmpa.c + +# libpychrysaarch_la_SOURCES =			\ +# 	archbase.h archbase.c				\ +# 	instruction.h instruction.c			\ +# 	module.h module.c					\ +# 	processor.h processor.c  libpychrysaarch_la_LDFLAGS =  diff --git a/plugins/pychrysa/arch/archbase.h b/plugins/pychrysa/arch/archbase.h index 8721371..b5d9811 100644 --- a/plugins/pychrysa/arch/archbase.h +++ b/plugins/pychrysa/arch/archbase.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * archbase.h - prototypes pour l'équivalent Python du fichier "arch/archbase.h" + * vmpa.h - prototypes pour l'équivalent Python du fichier "arch/vmpa.h"   * - * Copyright (C) 2010-2012 Cyrille Bagard + * Copyright (C) 2014 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -22,11 +22,19 @@   */ -#ifndef _PLUGINS_PYOIDA_ARCH_ARCHBASE_H -#define _PLUGINS_PYOIDA_ARCH_ARCHBASE_H +#ifndef _PLUGINS_PYCHRYSA_ARCH_VMPA_H +#define _PLUGINS_PYCHRYSA_ARCH_VMPA_H +  #include <Python.h> + + + + + + +#if 0  #include <stdbool.h>  #include <arch/archbase.h> @@ -38,7 +46,9 @@ PyObject *py_vmpa_new_from_existing(vmpa_t);  /* Ajoute l'objet 'arch.vmpa' au module Python. */  bool add_arch_vmpa_to_python_module(PyObject *); +#endif + -#endif  /* _PLUGINS_PYOIDA_ARCH_ARCHBASE_H */ +#endif  /* _PLUGINS_PYCHRYSA_ARCH_VMPA_H */ diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c index 685d82f..efbdaa5 100644 --- a/plugins/pychrysa/arch/instruction.c +++ b/plugins/pychrysa/arch/instruction.c @@ -223,7 +223,7 @@ bool register_python_arch_instruction_iterator(PyObject *module)          .tp_dealloc     = (destructor)py_arch_instruction_iterator_dealloc, -        .tp_flags       = Py_TPFLAGS_HAVE_ITER | Py_TPFLAGS_HAVE_CLASS, +        //.tp_flags       = Py_TPFLAGS_HAVE_ITER | Py_TPFLAGS_HAVE_CLASS,          .tp_doc         = "PyChrysalide architecture instruction iterator", diff --git a/plugins/pychrysa/arch/module.c b/plugins/pychrysa/arch/module.c index 7e8fcb3..92172e0 100644 --- a/plugins/pychrysa/arch/module.c +++ b/plugins/pychrysa/arch/module.c @@ -25,9 +25,7 @@  #include "module.h" -#include "instruction.h" - - +#include "vmpa.h" @@ -45,28 +43,49 @@  bool add_arch_module_to_python_module(PyObject *super)  { -    bool result; -    PyObject *module; +    bool result;                            /* Bilan à retourner           */ +    PyObject *module;                       /* Sous-module mis en place    */      int ret;                                /* Bilan d'un appel            */ -    static PyMethodDef py_arch_methods[] = { -        { NULL } +    static PyModuleDef py_chrysalide_arch_module = { + +        .m_base = PyModuleDef_HEAD_INIT, + +        .m_name = "pychrysalide.arch", +        .m_doc = "Python module for Chrysalide.arch", + +        .m_size = -1, +      }; -    module = Py_InitModule("pychrysalide.arch", py_arch_methods); +    result = false; + +    module = PyModule_Create(&py_chrysalide_arch_module);      if (module == NULL) return false; +    ret = PyState_AddModule(super, &py_chrysalide_arch_module); +    if (ret != 0) goto aamtpm_exit; + +    ret = _PyImport_FixupBuiltin(module, "pychrysalide.arch"); +    if (ret != 0) goto aamtpm_exit;      Py_INCREF(module); -    ret = PyModule_AddObject(super, "pychrysalide.arch", module); +    ret = PyModule_AddObject(super, "arch", module); +    if (ret != 0) goto aamtpm_exit; + +    result = true; + +    result &= register_python_vmpa(module); -    result = (ret == 0); + aamtpm_exit: -    if (ret != 0) /* ... */; +    if (!result) +    { +        printf("something went wrong in %s...\n", __FUNCTION__); +        /* ... */ -    result &= register_python_arch_instruction(module); -    result &= register_python_arch_instruction_iterator(module); +    } -    return true; +    return result;  } diff --git a/plugins/pychrysa/arch/module.h b/plugins/pychrysa/arch/module.h index 8017f76..403ec8a 100644 --- a/plugins/pychrysa/arch/module.h +++ b/plugins/pychrysa/arch/module.h @@ -22,8 +22,8 @@   */ -#ifndef _PLUGINS_PYOIDA_ARCH_MODULE_H -#define _PLUGINS_PYOIDA_ARCH_MODULE_H +#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_MODULE_H  #include <Python.h> @@ -36,4 +36,4 @@ bool add_arch_module_to_python_module(PyObject *); -#endif  /* _PLUGINS_PYOIDA_ARCH_MODULE_H */ +#endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_MODULE_H */ diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c new file mode 100644 index 0000000..b429699 --- /dev/null +++ b/plugins/pychrysa/arch/vmpa.c @@ -0,0 +1,325 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * vmpa.c - équivalent Python du fichier "arch/vmpa.c" + * + * Copyright (C) 2014 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  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 "vmpa.h" + + +#include <src/arch/vmpa.h> + + + + + + + +typedef struct _py_vmpa_t +{ +    PyObject_HEAD + +    vmpa2_t addr; + +} py_vmpa_t; + + + + +/* Fournit une représentation d'une variable 'vmpa_t'. */ +static PyObject *py_vmpa_to_str(PyObject *); + + + + +/* Effectue une conversion d'un objet Python en type 'vmpa_t'. */ +static bool convert_pyobj_to_vmpa(PyObject *, vmpa2_t *); + +/* Effectue une opération de type 'add' avec le type 'vmpa'. */ +static PyObject *py_vmpa_nb_add(PyObject *, PyObject *); + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : obj = objet Python à traiter.                                * +*                                                                             * +*  Description : Fournit une représentation d'une variable 'vmpa_t'.          * +*                                                                             * +*  Retour      : Chaîne de caractère pour Python.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_vmpa_to_str(PyObject *obj) +{ +    vmpa2_t *addr; + +    addr = &((py_vmpa_t *)obj)->addr; + +    return PyUnicode_FromFormat("<phy=%d, virt=0x%08x>", addr->physical, addr->virtual); + +} + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : obj  = objet Python à tenter de convertir.                   * +*                addr = structure équivalente pour Chrysalide.                * +*                                                                             * +*  Description : Effectue une conversion d'un objet Python en type 'vmpa_t'.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool convert_pyobj_to_vmpa(PyObject *obj, vmpa2_t *addr) +{ +    bool result;                            /* Résulats à retourner        */ +    PyTypeObject *py_vmpa_type;             /* Type Python pour 'vmpa'     */ +    int ret;                                /* Bilan d'un appel            */ +    PY_LONG_LONG value;                     /* Valeur de type générique    */ +    int overflow;                           /* Détection d'une grosse val. */ + +    result = false; + +    py_vmpa_type = get_python_vmpa_type(); + +    ret = PyObject_IsInstance(obj, (PyObject *)py_vmpa_type); + +    /* S'il n'y a rien à faire... */ +    if (ret == 1) +    { +        *addr = ((py_vmpa_t *)obj)->addr; +        result = true; +    } + +    /* Sinon on demande à Python... */ +    else +    { +        value = PyLong_AsLongLongAndOverflow(obj, &overflow); + +        if (value == -1 && (overflow == 1 || PyErr_Occurred())) +            PyErr_Clear(); + +        else +        { +            init_vmpa(addr, value, value); +            result = true; +        } + +    } + +    return result; + +} + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : o1 = premier élément concerné par l'opération.               * +*                o2 = second élément concerné par l'opération.                * +*                                                                             * +*  Description : Effectue une opération de type 'add' avec le type 'vmpa'.    * +*                                                                             * +*  Retour      : Résultat de l'opération.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_vmpa_nb_add(PyObject *o1, PyObject *o2) +{ +    PyObject *result;                       /* Résultat à retourner        */ +    vmpa2_t addr1;                          /* Première adresse à traiter  */ +    vmpa2_t addr2;                          /* Seconde adresse à traiter   */ +    PyTypeObject *py_vmpa_type;             /* Type Python pour 'vmpa'     */ + +    if (!convert_pyobj_to_vmpa(o1, &addr1)) +        return NULL; + +    if (!convert_pyobj_to_vmpa(o2, &addr2)) +        return NULL; + +    py_vmpa_type = get_python_vmpa_type(); + +    result = PyObject_CallObject((PyObject *)py_vmpa_type, NULL); + +    init_vmpa(&((py_vmpa_t *)result)->addr, +              addr1.physical + addr2.physical, +              addr1.virtual + addr2.virtual); + +    return result; + +} + + + + +void log_simple_message(/*LogMessageType*/ int type, const char *msg) +{ + +} + + +void log_variadic_message(/*LogMessageType*/ int type, const char *fmt, ...) +{ + + +} + + +void change_editor_items_current_view_content(void/*GtkViewPanel*/ *view) +{ + + +} + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Fournit un accès à une définition de type à diffuser.        * +*                                                                             * +*  Retour      : Définition d'objet pour Python.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyTypeObject *get_python_vmpa_type(void) +{ +    static PyNumberMethods py_vmpa_nb_proto = { + +        .nb_add = py_vmpa_nb_add, + +        /* +     binaryfunc nb_add; +     binaryfunc nb_subtract; +     binaryfunc nb_multiply; +     binaryfunc nb_remainder; +     binaryfunc nb_divmod; +     ternaryfunc nb_power; +     unaryfunc nb_negative; +     unaryfunc nb_positive; +     unaryfunc nb_absolute; +     inquiry nb_bool; +     unaryfunc nb_invert; +     binaryfunc nb_lshift; +     binaryfunc nb_rshift; +     binaryfunc nb_and; +     binaryfunc nb_xor; +     binaryfunc nb_or; +     unaryfunc nb_int; +     void *nb_reserved; +     unaryfunc nb_float; + +     binaryfunc nb_inplace_add; +     binaryfunc nb_inplace_subtract; +     binaryfunc nb_inplace_multiply; +     binaryfunc nb_inplace_remainder; +     ternaryfunc nb_inplace_power; +     binaryfunc nb_inplace_lshift; +     binaryfunc nb_inplace_rshift; +     binaryfunc nb_inplace_and; +     binaryfunc nb_inplace_xor; +     binaryfunc nb_inplace_or; + +     binaryfunc nb_floor_divide; +     binaryfunc nb_true_divide; +     binaryfunc nb_inplace_floor_divide; +     binaryfunc nb_inplace_true_divide; + +     unaryfunc nb_index; + +        */ + +    }; + +    static PyTypeObject py_vmpa_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name = "pychrysalide.arch.vmpa", +        .tp_basicsize = sizeof(py_vmpa_t), + +        .tp_as_number = &py_vmpa_nb_proto, + +        .tp_str = py_vmpa_to_str, + +        .tp_flags = Py_TPFLAGS_DEFAULT, + +        .tp_doc = "Python object for vmpa_t" + +    }; + +    return &py_vmpa_type; + +} + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.arch.vmpa'.            * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_vmpa(PyObject *module) +{ +    PyTypeObject *py_vmpa_type;             /* Type Python pour 'vmpa'     */ +    int ret;                                /* Bilan d'un appel            */ + +    py_vmpa_type = get_python_vmpa_type(); + +    py_vmpa_type->tp_new = PyType_GenericNew; + +    if (PyType_Ready(py_vmpa_type) != 0) +        return false; + +    Py_INCREF(py_vmpa_type); +    ret = PyModule_AddObject(module, "vmpa", (PyObject *)py_vmpa_type); + +    return (ret == 0); + +} diff --git a/plugins/pychrysa/arch/vmpa.h b/plugins/pychrysa/arch/vmpa.h new file mode 100644 index 0000000..6ee00b2 --- /dev/null +++ b/plugins/pychrysa/arch/vmpa.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * vmpa.h - prototypes pour l'équivalent Python du fichier "arch/vmpa.h" + * + * Copyright (C) 2014 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  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_PYCHRYSALIDE_ARCH_VMPA_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_VMPA_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_vmpa_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.vmpa'. */ +bool register_python_vmpa(PyObject *); + + + +#endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_VMPA_H */ diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index f2dbf0f..865c0fc 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -24,10 +24,12 @@  #include "pychrysa.h" +#if 0 +  #include <dirent.h>  #include <pygobject.h>  #include <string.h> -#include <pygtk/pygtk.h> +//#include <pygtk/pygtk.h>  #include <config.h> @@ -252,8 +254,33 @@ PluginAction get_plugin_action(const GPluginModule *plugin)  *                                                                             *  ******************************************************************************/ -PyMODINIT_FUNC PyInit_pychrysa(void) +PyMODINIT_FUNC initpychrysa/*PyInit_pychrysa*/(void)  { +    PyObject *module; + +    //init_pygobject(); +    //init_pygtk(); + +    pychrysalide_init_quirks(); + +    module = Py_InitModule("pychrysalide", SpamMethods); + +    //add_analysis_roptions_to_python_module(module); +    add_analysis_module_to_python_module(module); +    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_gtkext_module_to_python_module(module); +    add_gui_module_to_python_module(module); + +    add_plugin_to_python_module(module); + + +    /* + + +      static struct PyModuleDef spammodule = {          PyModuleDef_HEAD_INIT,          "pychrysalide", @@ -264,6 +291,8 @@ PyMODINIT_FUNC PyInit_pychrysa(void)      PyModule_Create(&spammodule); +    */ +  }  #else @@ -305,3 +334,149 @@ PyMODINIT_FUNC initpychrysa(void)  }  #endif + + + +#endif + + + + + + + +#include <pygobject.h> + + +#include "../../revision.h" + + +#include "analysis/module.h" +#include "arch/module.h" + + + +// TODO : à bouger ? +#include "../../src/arch/processor.h" +#include "../../src/format/format.h" + + + +/* Fournit la version du programme global. */ +static PyObject *py_chrysalide_version(PyObject *, PyObject *); + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self = NULL car méthode statique.                            * +*                args = non utilisé ici.                                      * +*                                                                             * +*  Description : Fournit la version du programme global.                      * +*                                                                             * +*  Retour      : Numéro de révision.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_chrysalide_version(PyObject *self, PyObject *args) +{ +    char version[16]; +    int major; +    int minor; +    int revision; + +    major = REVISION / 1000; +    minor = (REVISION - (major * 1000)) / 100; +    revision = REVISION % 100; + +    snprintf(version, sizeof(version), "%d.%d.%d", major, minor, revision); + +    return PyUnicode_FromString(version); + +} + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Point d'entrée pour l'initialisation de Python.              * +*                                                                             * +*  Retour      : ?                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +PyMODINIT_FUNC PyInit_pychrysalide(void) +{ +    PyObject *result;                       /* Module Python à retourner   */ +    PyObject *pygobj_mod;                   /* Module Python-GObject       */ +    bool status;                            /* Bilan des inclusions        */ + +    static PyMethodDef py_chrysalide_methods[] = { + +        { "version", py_chrysalide_version, +          METH_NOARGS, +          "Provide the revision number of Chrysalide." +        }, +        { "python", py_chrysalide_version, +          METH_NOARGS, +          "Provide the revision number of Chrysalide module for Python." +        }, +        { NULL } + +    }; + +    static PyModuleDef py_chrysalide_module = { + +        .m_base = PyModuleDef_HEAD_INIT, + +        .m_name = "pychrysalide", +        .m_doc = "Python module for Chrysalide", + +        .m_size = -1, + +        .m_methods = py_chrysalide_methods + +    }; + + +    // TODO : à bouger ! +    init_all_processors(); +    init_all_formats(); + + +    if (pygobject_init(-1, -1, -1) == NULL) +        return NULL; + +    /** +     * Pour une raison non identifiée, si le module n'est pas préchargé, +     * le flot d'exécution plante dans la fonction insertdict() de Objects/dictobject.c:818. +     */ +    pygobj_mod = PyImport_ImportModule("gi.repository.GObject"); +    if (pygobj_mod == NULL) +        return NULL; + +    result = PyModule_Create(&py_chrysalide_module); + +    status = true; + +    status &= add_analysis_module_to_python_module(result); +    status &= add_arch_module_to_python_module(result); + +    printf("status :: %d\n", status); + +    /* TODO : if !status... */ + +    return result; + +} diff --git a/plugins/pychrysa/pychrysa.h b/plugins/pychrysa/pychrysa.h index 5897abe..0fdc074 100644 --- a/plugins/pychrysa/pychrysa.h +++ b/plugins/pychrysa/pychrysa.h @@ -25,7 +25,23 @@  #define _PLUGINS_PYCHRYSA_H +/** + * Note: + * Since Python may define some pre-processor definitions which affect the standard headers + * on some systems, you must include Python.h before any standard headers are included. + * + * cf. https://docs.python.org/3.4/c-api/intro.html + */  #include <Python.h> + + + + + + +#if 0 + +  #include <glib-object.h>  #include <stdbool.h> @@ -50,7 +66,8 @@ PluginAction get_plugin_action(const GPluginModule *);  #if PY_VERSION_HEX >= 0x03000000  /* Point d'entrée pour l'initialisation de Python. */ -PyMODINIT_FUNC PyInit_pychrysa(void); +//PyMODINIT_FUNC PyInit_pychrysa(void); +PyMODINIT_FUNC initpychrysa(void);  #else @@ -59,6 +76,14 @@ PyMODINIT_FUNC initpychrysa(void);  #endif +#endif + + + + +/* Point d'entrée pour l'initialisation de Python. */ +PyMODINIT_FUNC PyInit_pychrysalide(void); +  #endif  /* _PLUGINS_PYCHRYSA_H */ diff --git a/plugins/pychrysa/quirks.c b/plugins/pychrysa/quirks.c index 64d7bf2..4aa8536 100644 --- a/plugins/pychrysa/quirks.c +++ b/plugins/pychrysa/quirks.c @@ -26,7 +26,7 @@ -#include <pyglib.h> +//#include <pyglib.h>  #include <pygobject.h>  | 
