diff options
Diffstat (limited to 'plugins/pychrysa/arch')
22 files changed, 2262 insertions, 170 deletions
diff --git a/plugins/pychrysa/arch/Makefile.am b/plugins/pychrysa/arch/Makefile.am index 54b9261..7607ed8 100644 --- a/plugins/pychrysa/arch/Makefile.am +++ b/plugins/pychrysa/arch/Makefile.am @@ -2,9 +2,14 @@ noinst_LTLIBRARIES = libpychrysaarch.la libpychrysaarch_la_SOURCES = \ + instruction.h instruction.c \ module.h module.c \ + processor.h processor.c \ vmpa.h vmpa.c +libpychrysaarch_la_LIBADD = \ + arm/libpychrysaarcharm.la + # libpychrysaarch_la_SOURCES = \ # archbase.h archbase.c \ # instruction.h instruction.c \ @@ -19,3 +24,5 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE -I../../../src AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = arm diff --git a/plugins/pychrysa/arch/arm/Makefile.am b/plugins/pychrysa/arch/arm/Makefile.am new file mode 100644 index 0000000..b081061 --- /dev/null +++ b/plugins/pychrysa/arch/arm/Makefile.am @@ -0,0 +1,20 @@ + +noinst_LTLIBRARIES = libpychrysaarcharm.la + +libpychrysaarcharm_la_SOURCES = \ + instruction.h instruction.c \ + module.h module.c \ + processor.h processor.c + +libpychrysaarcharm_la_LIBADD = \ + v7/libpychrysaarcharmv7.la + +libpychrysaarcharm_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = v7 diff --git a/plugins/pychrysa/arch/arm/instruction.c b/plugins/pychrysa/arch/arm/instruction.c new file mode 100644 index 0000000..ed53386 --- /dev/null +++ b/plugins/pychrysa/arch/arm/instruction.c @@ -0,0 +1,120 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * instruction.c - équivalent Python du fichier "arch/arm/instruction.c" + * + * Copyright (C) 2015 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 "instruction.h" + + +#include <pygobject.h> + + +#include <arch/arm/instruction.h> + + +#include "../instruction.h" +#include "../../helpers.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_arm_instruction_type(void) +{ + static PyMethodDef py_arm_instruction_methods[] = { + { NULL } + }; + + static PyGetSetDef py_arm_instruction_getseters[] = { + { NULL } + }; + + static PyTypeObject py_arm_instruction_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.arm.ArmInstruction", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide instruction for an ARM architecture.", + + .tp_methods = py_arm_instruction_methods, + .tp_getset = py_arm_instruction_getseters, + + }; + + return &py_arm_instruction_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide....arm.ArmInstruction'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_arm_instruction(PyObject *module) +{ + PyTypeObject *py_arm_instruction_type; /* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_arm_instruction_type = get_python_arm_instruction_type(); + + py_arm_instruction_type->tp_base = get_python_arch_instruction_type(); + py_arm_instruction_type->tp_basicsize = py_arm_instruction_type->tp_base->tp_basicsize; + + APPLY_ABSTRACT_FLAG(py_arm_instruction_type); + + if (PyType_Ready(py_arm_instruction_type) != 0) + return false; + + Py_INCREF(py_arm_instruction_type); + ret = PyModule_AddObject(module, "ArmInstruction", (PyObject *)py_arm_instruction_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ArmInstruction", G_TYPE_ARM_INSTRUCTION, py_arm_instruction_type, + Py_BuildValue("(O)", py_arm_instruction_type->tp_base)); + + return true; + +} diff --git a/plugins/pychrysa/arch/arm/instruction.h b/plugins/pychrysa/arch/arm/instruction.h new file mode 100644 index 0000000..daec429 --- /dev/null +++ b/plugins/pychrysa/arch/arm/instruction.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * instruction.h - prototypes pour l'équivalent Python du fichier "arch/arm/instruction.h" + * + * Copyright (C) 2015 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_ARM_INSTRUCTION_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_ARM_INSTRUCTION_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_arm_instruction_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.arm.ArmInstruction'. */ +bool register_python_arm_instruction(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_ARM_INSTRUCTION_H */ diff --git a/plugins/pychrysa/arch/arm/module.c b/plugins/pychrysa/arch/arm/module.c new file mode 100644 index 0000000..d1d7adc --- /dev/null +++ b/plugins/pychrysa/arch/arm/module.c @@ -0,0 +1,96 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire arm en tant que module + * + * Copyright (C) 2015 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 "module.h" + + +#include "instruction.h" +#include "processor.h" +#include "v7/module.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'arm' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_arch_arm_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_arm_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.arch.arm", + .m_doc = "Python module for Chrysalide.arch.arm", + + .m_size = -1, + + }; + + result = false; + + module = PyModule_Create(&py_chrysalide_arm_module); + if (module == NULL) return false; + + ret = PyState_AddModule(super, &py_chrysalide_arm_module); + if (ret != 0) goto aaamtpm_exit; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.arch.arm"); + if (ret != 0) goto aaamtpm_exit; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "arm", module); + if (ret != 0) goto aaamtpm_exit; + + result = true; + + result &= register_python_arm_instruction(module); + result &= register_python_arm_processor(module); + + result &= add_arch_arm_v7_module_to_python_module(module); + + aaamtpm_exit: + + if (!result) + { + printf("something went wrong in %s...\n", __FUNCTION__); + /* ... */ + + } + + return result; + +} diff --git a/plugins/pychrysa/arch/arm/module.h b/plugins/pychrysa/arch/arm/module.h new file mode 100644 index 0000000..eed753f --- /dev/null +++ b/plugins/pychrysa/arch/arm/module.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire arm en tant que module + * + * Copyright (C) 2015 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_ARM_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_ARM_MODULE_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Ajoute le module 'arm' au module Python. */ +bool add_arch_arm_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_ARM_MODULE_H */ diff --git a/plugins/pychrysa/arch/arm/processor.c b/plugins/pychrysa/arch/arm/processor.c new file mode 100644 index 0000000..049dcb3 --- /dev/null +++ b/plugins/pychrysa/arch/arm/processor.c @@ -0,0 +1,120 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * processor.c - équivalent Python du fichier "arch/arm/processor.c" + * + * Copyright (C) 2015 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 "processor.h" + + +#include <pygobject.h> + + +#include <arch/arm/processor.h> + + +#include "../processor.h" +#include "../../helpers.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_arm_processor_type(void) +{ + static PyMethodDef py_arm_processor_methods[] = { + { NULL } + }; + + static PyGetSetDef py_arm_processor_getseters[] = { + { NULL } + }; + + static PyTypeObject py_arm_processor_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.arm.ArmProcessor", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide processor for an ARM architecture.", + + .tp_methods = py_arm_processor_methods, + .tp_getset = py_arm_processor_getseters, + + }; + + return &py_arm_processor_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.arch.arm.ArmProcessor'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_arm_processor(PyObject *module) +{ + PyTypeObject *py_arm_processor_type; /* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_arm_processor_type = get_python_arm_processor_type(); + + py_arm_processor_type->tp_base = get_python_arch_processor_type(); + py_arm_processor_type->tp_basicsize = py_arm_processor_type->tp_base->tp_basicsize; + + APPLY_ABSTRACT_FLAG(py_arm_processor_type); + + if (PyType_Ready(py_arm_processor_type) != 0) + return false; + + Py_INCREF(py_arm_processor_type); + ret = PyModule_AddObject(module, "ArmProcessor", (PyObject *)py_arm_processor_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ArmProcessor", G_TYPE_ARM_PROCESSOR, py_arm_processor_type, + Py_BuildValue("(O)", py_arm_processor_type->tp_base)); + + return true; + +} diff --git a/plugins/pychrysa/arch/arm/processor.h b/plugins/pychrysa/arch/arm/processor.h new file mode 100644 index 0000000..594f0e6 --- /dev/null +++ b/plugins/pychrysa/arch/arm/processor.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * processor.h - prototypes pour l'équivalent Python du fichier "arch/arm/processor.h" + * + * Copyright (C) 2015 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_ARM_PROCESSOR_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_ARM_PROCESSOR_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_arm_processor_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.arm.ArmProcessor'. */ +bool register_python_arm_processor(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_ARM_PROCESSOR_H */ diff --git a/plugins/pychrysa/arch/arm/v7/Makefile.am b/plugins/pychrysa/arch/arm/v7/Makefile.am new file mode 100644 index 0000000..d95aff3 --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/Makefile.am @@ -0,0 +1,16 @@ + +noinst_LTLIBRARIES = libpychrysaarcharmv7.la + +libpychrysaarcharmv7_la_SOURCES = \ + instruction.h instruction.c \ + module.h module.c \ + processor.h processor.c + + +libpychrysaarcharmv7_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pychrysa/arch/arm/v7/instruction.c b/plugins/pychrysa/arch/arm/v7/instruction.c new file mode 100644 index 0000000..8a19259 --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/instruction.c @@ -0,0 +1,117 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * instruction.c - équivalent Python du fichier "arch/arm/v7/instruction.c" + * + * Copyright (C) 2015 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 "instruction.h" + + +#include <pygobject.h> + + +#include <arch/arm/v7/instruction.h> + + +#include "../instruction.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_armv7_instruction_type(void) +{ + static PyMethodDef py_armv7_instruction_methods[] = { + { NULL } + }; + + static PyGetSetDef py_armv7_instruction_getseters[] = { + { NULL } + }; + + static PyTypeObject py_armv7_instruction_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.arm.v7.ArmV7Instruction", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide instruction for an ARMv7 architecture.", + + .tp_methods = py_armv7_instruction_methods, + .tp_getset = py_armv7_instruction_getseters, + + }; + + return &py_armv7_instruction_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide....arm.ArmInstruction'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_armv7_instruction(PyObject *module) +{ + PyTypeObject *py_armv7_instruction_type;/* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_armv7_instruction_type = get_python_armv7_instruction_type(); + + py_armv7_instruction_type->tp_base = get_python_arm_instruction_type(); + py_armv7_instruction_type->tp_basicsize = py_armv7_instruction_type->tp_base->tp_basicsize; + + if (PyType_Ready(py_armv7_instruction_type) != 0) + return false; + + Py_INCREF(py_armv7_instruction_type); + ret = PyModule_AddObject(module, "ArmV7Instruction", (PyObject *)py_armv7_instruction_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ArmV7Instruction", G_TYPE_ARMV7_INSTRUCTION, py_armv7_instruction_type, + Py_BuildValue("(O)", py_armv7_instruction_type->tp_base)); + + return true; + +} diff --git a/plugins/pychrysa/arch/arm/v7/instruction.h b/plugins/pychrysa/arch/arm/v7/instruction.h new file mode 100644 index 0000000..9eac361 --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/instruction.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * instruction.h - prototypes pour l'équivalent Python du fichier "arch/arm/v7/instruction.h" + * + * Copyright (C) 2015 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_ARM_V7_INSTRUCTION_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_ARM_V7_INSTRUCTION_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_armv7_instruction_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.arm.v7.ArmV7Instruction'. */ +bool register_python_armv7_instruction(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_ARM_V7_INSTRUCTION_H */ diff --git a/plugins/pychrysa/arch/arm/v7/module.c b/plugins/pychrysa/arch/arm/v7/module.c new file mode 100644 index 0000000..7c0aabf --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/module.c @@ -0,0 +1,93 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire v7 en tant que module + * + * Copyright (C) 2015 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 "module.h" + + +#include "instruction.h" +#include "processor.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'arm' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_arch_arm_v7_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_v7_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.arch.arm.v7", + .m_doc = "Python module for Chrysalide.arch.arm.v7", + + .m_size = -1, + + }; + + result = false; + + module = PyModule_Create(&py_chrysalide_v7_module); + if (module == NULL) return false; + + ret = PyState_AddModule(super, &py_chrysalide_v7_module); + if (ret != 0) goto aaamtpm_exit; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.arch.arm.v7"); + if (ret != 0) goto aaamtpm_exit; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "v7", module); + if (ret != 0) goto aaamtpm_exit; + + result = true; + + result &= register_python_armv7_instruction(module); + result &= register_python_armv7_processor(module); + + aaamtpm_exit: + + if (!result) + { + printf("something went wrong in %s...\n", __FUNCTION__); + /* ... */ + + } + + return result; + +} diff --git a/plugins/pychrysa/arch/arm/v7/module.h b/plugins/pychrysa/arch/arm/v7/module.h new file mode 100644 index 0000000..61ad126 --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/module.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire v7 en tant que module + * + * Copyright (C) 2015 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_ARM_V7_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_ARM_V7_MODULE_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Ajoute le module 'arm' au module Python. */ +bool add_arch_arm_v7_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_ARM_V7_MODULE_H */ diff --git a/plugins/pychrysa/arch/arm/v7/processor.c b/plugins/pychrysa/arch/arm/v7/processor.c new file mode 100644 index 0000000..1844066 --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/processor.c @@ -0,0 +1,117 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * processor.c - équivalent Python du fichier "arch/arm/v7/processor.c" + * + * Copyright (C) 2015 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 "processor.h" + + +#include <pygobject.h> + + +#include <arch/arm/v7/processor.h> + + +#include "../processor.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_armv7_processor_type(void) +{ + static PyMethodDef py_armv7_processor_methods[] = { + { NULL } + }; + + static PyGetSetDef py_armv7_processor_getseters[] = { + { NULL } + }; + + static PyTypeObject py_armv7_processor_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.arm.v7.ArmV7Processor", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide processor for an ARMv7 architecture.", + + .tp_methods = py_armv7_processor_methods, + .tp_getset = py_armv7_processor_getseters, + + }; + + return &py_armv7_processor_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.arch.arm.ArmProcessor'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_armv7_processor(PyObject *module) +{ + PyTypeObject *py_armv7_processor_type; /* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_armv7_processor_type = get_python_armv7_processor_type(); + + py_armv7_processor_type->tp_base = get_python_arm_processor_type(); + py_armv7_processor_type->tp_basicsize = py_armv7_processor_type->tp_base->tp_basicsize; + + if (PyType_Ready(py_armv7_processor_type) != 0) + return false; + + Py_INCREF(py_armv7_processor_type); + ret = PyModule_AddObject(module, "ArmV7Processor", (PyObject *)py_armv7_processor_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ArmV7Processor", G_TYPE_ARMV7_PROCESSOR, py_armv7_processor_type, + Py_BuildValue("(O)", py_armv7_processor_type->tp_base)); + + return true; + +} diff --git a/plugins/pychrysa/arch/arm/v7/processor.h b/plugins/pychrysa/arch/arm/v7/processor.h new file mode 100644 index 0000000..268a025 --- /dev/null +++ b/plugins/pychrysa/arch/arm/v7/processor.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * processor.h - prototypes pour l'équivalent Python du fichier "arch/arm/v7/processor.h" + * + * Copyright (C) 2015 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_ARM_V7_PROCESSOR_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_ARM_V7_PROCESSOR_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_armv7_processor_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.arm.v7.ArmV7Processor'. */ +bool register_python_armv7_processor(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_ARM_V7_PROCESSOR_H */ diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c index efbdaa5..d675226 100644 --- a/plugins/pychrysa/arch/instruction.c +++ b/plugins/pychrysa/arch/instruction.c @@ -25,6 +25,384 @@ #include "instruction.h" +#include <assert.h> +#include <pygobject.h> + + +#include <arch/instruction.h> + + +#include "vmpa.h" +#include "../helpers.h" + + + + +/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */ + + + + + +/* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */ + + + +/* Fournit la place mémoire d'une instruction. */ +static PyObject *py_arch_instruction_get_range(PyObject *, void *); + +/* Définit la localisation d'une instruction. */ +static int py_arch_instruction_set_range(PyObject *, PyObject *, void *); + + + +/* Fournit le nom humain de l'instruction manipulée. */ +static PyObject *py_arch_instruction_get_keyword(PyObject *, void *); + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + + + +/* Fournit les origines d'une instruction donnée. */ +static PyObject *py_arch_instruction_get_sources(PyObject *, PyObject *); + +/* Fournit les destinations d'une instruction donnée. */ +static PyObject *py_arch_instruction_get_destinations(PyObject *, PyObject *); + + + + +/****************************************************************************** +* * +* Paramètres : self = instruction d'architecture à manipuler. * +* args = liste d'arguments non utilisée ici. * +* * +* Description : Fournit les origines d'une instruction donnée. * +* * +* Retour : Nombre de ces origines. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_get_sources(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GArchInstruction *instr; /* Version native */ + GArchInstruction **dests; /* Destination des liens */ + InstructionLinkType *types; /* Nature de ces liens */ + size_t count; /* Nombre de liens présents */ + size_t i; /* Boucle de parcours */ + PyObject *dest; /* Destination de lien Python */ + PyObject *type; /* Nature du lien en Python */ + int ret; /* Bilan d'une écriture d'arg. */ + + instr = G_ARCH_INSTRUCTION(pygobject_get(self)); + + count = g_arch_instruction_get_sources(instr, &dests, &types); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + dest = pygobject_new(G_OBJECT(dests[i])); + type = PyLong_FromLong(types[i]); + + ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", dest, type)); + assert(ret == 0); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = instruction d'architecture à manipuler. * +* args = liste d'arguments non utilisée ici. * +* * +* Description : Fournit les destinations d'une instruction donnée. * +* * +* Retour : Nombre de ces destinations. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_get_destinations(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GArchInstruction *instr; /* Version native */ + GArchInstruction **dests; /* Destination des liens */ + InstructionLinkType *types; /* Nature de ces liens */ + size_t count; /* Nombre de liens présents */ + size_t i; /* Boucle de parcours */ + PyObject *dest; /* Destination de lien Python */ + PyObject *type; /* Nature du lien en Python */ + int ret; /* Bilan d'une écriture d'arg. */ + + instr = G_ARCH_INSTRUCTION(pygobject_get(self)); + + count = g_arch_instruction_get_destinations(instr, &dests, &types, NULL); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + dest = pygobject_new(G_OBJECT(dests[i])); + type = PyLong_FromLong(types[i]); + + ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", dest, type)); + assert(ret == 0); + + } + + return result; + +} + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une instruction. * +* closure = adresse non utilisée ici. * +* * +* Description : Fournit la place mémoire d'une instruction. * +* * +* Retour : Valeur associée à la propriété consultée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_get_range(PyObject *self, void *closure) +{ + PyObject *result; /* Conversion à retourner */ + GArchInstruction *instr; /* Version native */ + const mrange_t *range; /* Espace mémoire à exporter */ + + instr = G_ARCH_INSTRUCTION(pygobject_get(self)); + range = g_arch_instruction_get_range(instr); + + result = build_from_internal_mrange(range); + + return result; + +} + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = adresse non utilisée ici. * +* * +* Description : Définit la localisation d'une instruction. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_arch_instruction_set_range(PyObject *self, PyObject *value, void *closure) +{ + int ret; /* Bilan d'analyse */ + mrange_t *range; /* Espace mémoire à manipuler */ + GArchInstruction *instr; /* Version native */ + + ret = PyObject_IsInstance(value, (PyObject *)get_python_mrange_type()); + if (!ret) return -1; + + range = get_internal_mrange(value); + + instr = G_ARCH_INSTRUCTION(pygobject_get(self)); + g_arch_instruction_set_range(instr, range); + + return 0; + +} + + + + + + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une instruction. * +* unused = adresse non utilisée ici. * +* * +* Description : Fournit le nom humain de l'instruction manipulée. * +* * +* Retour : Valeur associée à la propriété consultée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused) +{ + PyObject *result; /* Trouvailles à retourner */ + GArchInstruction *instr; /* Version native */ + const char *kw; /* Valeur récupérée */ + + instr = G_ARCH_INSTRUCTION(pygobject_get(self)); + kw = g_arch_instruction_get_keyword(instr, 0/* FIXME*/); + + result = PyUnicode_FromString(kw); + + return result; + +} + + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_arch_instruction_type(void) +{ + static PyMethodDef py_arch_instruction_methods[] = { + { "get_sources", py_arch_instruction_get_sources, + METH_NOARGS, + "get_sources(, /)\n--\n\nProvide the instructions list driving to the current instruction." + }, + { "get_destinations", py_arch_instruction_get_destinations, + METH_NOARGS, + "get_destinations(, /)\n--\n\nProvide the instructions list following the current instruction." + }, + { NULL } + }; + + static PyGetSetDef py_arch_instruction_getseters[] = { + { + "range", py_arch_instruction_get_range, py_arch_instruction_set_range, + "Give access to the memory range covered by the current instruction.", NULL + }, + { + "keyword", (getter)py_arch_instruction_get_keyword, (setter)NULL, + "Give le name of the assembly instruction.", NULL + }, + { NULL } + }; + + static PyTypeObject py_arch_instruction_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.ArchInstruction", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide instruction for a given architecture.", + + .tp_methods = py_arch_instruction_methods, + .tp_getset = py_arch_instruction_getseters, + + }; + + return &py_arch_instruction_type; + +} + + +/****************************************************************************** +* * +* 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) +{ + PyTypeObject *py_arch_instruction_type; /* Type Python 'BinContent' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_arch_instruction_type = get_python_arch_instruction_type(); + + py_arch_instruction_type->tp_base = &PyGObject_Type; + py_arch_instruction_type->tp_basicsize = py_arch_instruction_type->tp_base->tp_basicsize; + + APPLY_ABSTRACT_FLAG(py_arch_instruction_type); + + 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); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ArchInstruction", G_TYPE_ARCH_INSTRUCTION, py_arch_instruction_type, + Py_BuildValue("(O)", py_arch_instruction_type->tp_base)); + + return true; + +} + + + + + + + +#if 0 + + #include <pygobject.h> #include <stdbool.h> #include <string.h> @@ -330,34 +708,6 @@ static PyObject *py_arch_instruction_get_location(PyObject *self, char *name) } -/****************************************************************************** -* * -* Paramètres : self = classe représentant une instruction. * -* unused = adresse non utilisée ici. * -* * -* Description : Fournit le nom humain de l'instruction manipulée. * -* * -* Retour : Valeur associée à la propriété consultée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_arch_instruction_get_keyword(PyObject *self, void *unused) -{ - PyObject *result; /* Trouvailles à retourner */ - GArchInstruction *instr; /* Version native */ - const char *kw; /* Valeur récupérée */ - - instr = G_ARCH_INSTRUCTION(pygobject_get(self)); - kw = g_arch_instruction_get_keyword(instr); - - result = PyString_FromString(kw); - - return result; - -} - /****************************************************************************** * * @@ -438,3 +788,6 @@ bool register_python_arch_instruction(PyObject *module) return (ret == 0); } + + +#endif diff --git a/plugins/pychrysa/arch/instruction.h b/plugins/pychrysa/arch/instruction.h index 7b81d65..c3f8bd9 100644 --- a/plugins/pychrysa/arch/instruction.h +++ b/plugins/pychrysa/arch/instruction.h @@ -31,16 +31,8 @@ -/* --------------------- 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 --------------------- */ - +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_arch_instruction_type(void); /* Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. */ bool register_python_arch_instruction(PyObject *); diff --git a/plugins/pychrysa/arch/module.c b/plugins/pychrysa/arch/module.c index 92172e0..6df56a9 100644 --- a/plugins/pychrysa/arch/module.c +++ b/plugins/pychrysa/arch/module.c @@ -25,7 +25,13 @@ #include "module.h" +#include <assert.h> + + +#include "instruction.h" +#include "processor.h" #include "vmpa.h" +#include "arm/module.h" @@ -64,27 +70,27 @@ bool add_arch_module_to_python_module(PyObject *super) if (module == NULL) return false; ret = PyState_AddModule(super, &py_chrysalide_arch_module); - if (ret != 0) goto aamtpm_exit; + if (ret != 0) goto loading_failed; ret = _PyImport_FixupBuiltin(module, "pychrysalide.arch"); - if (ret != 0) goto aamtpm_exit; + if (ret != 0) goto loading_failed; Py_INCREF(module); ret = PyModule_AddObject(super, "arch", module); - if (ret != 0) goto aamtpm_exit; + if (ret != 0) goto loading_failed; result = true; + result &= register_python_arch_instruction(module); + result &= register_python_arch_processor(module); result &= register_python_vmpa(module); + result &= register_python_mrange(module); - aamtpm_exit: + result &= add_arch_arm_module_to_python_module(module); - if (!result) - { - printf("something went wrong in %s...\n", __FUNCTION__); - /* ... */ + loading_failed: - } + assert(result); return result; diff --git a/plugins/pychrysa/arch/processor.c b/plugins/pychrysa/arch/processor.c index 6a275d4..0a9ae3a 100644 --- a/plugins/pychrysa/arch/processor.c +++ b/plugins/pychrysa/arch/processor.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * processor.h - prototypes pour l'équivalent Python du fichier "arch/processor.h" + * processor.c - équivalent Python du fichier "arch/processor.c" * - * Copyright (C) 2010-2013 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -25,22 +25,21 @@ #include "processor.h" -#include "../../../src/arch/processor.h" +#include <pygobject.h> +#include <i18n.h> -/* ------------------------- TYPAGE DES ENUMERATIONS PYTHON ------------------------- */ +#include <arch/processor.h> -/* Définit les constantes pour les types de processeur. */ -bool py_arch_processor_type_define_constants(PyObject *); -/* Ajoute l'objet 'arch.processor.ArchProcessorType' au module. */ -bool add_arch_processor_type_to_python_module(PyObject *); +#include "instruction.h" +#include "vmpa.h" +#include "../helpers.h" -/* ------------------------- PARTIE STATIQUE DE PROCESSEURS ------------------------- */ @@ -48,12 +47,7 @@ bool add_arch_processor_type_to_python_module(PyObject *); -/* Classe 'analysis.roptions' pour Python */ -typedef struct _py_processor -{ - PyObject_HEAD -} py_processor; @@ -63,120 +57,246 @@ typedef struct _py_processor +/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ + + + +/* Fournit les instructions désassemblées pour une architecture. */ +static PyObject *py_arch_processor_get_disass_instrs(PyObject *, void *); + +/* Recherche une instruction d'après son adresse. */ +static PyObject *py_arch_processor_find_instr_by_addr(PyObject *, PyObject *); + +/* Fournit l'instruction qui en précède une autre. */ +static PyObject *py_arch_processor_get_prev_instr(PyObject *, PyObject *); + +/* Fournit l'instruction qui en suit une autre. */ +static PyObject *py_arch_processor_get_next_instr(PyObject *, PyObject *); + + + + /* ---------------------------------------------------------------------------------- */ -/* TYPAGE DES ENUMERATIONS PYTHON */ +/* MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : dict = dictionnaire à compléter. * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * * * -* Description : Définit les constantes pour les types de processeur. * +* Description : Fournit les instructions désassemblées pour une architecture.* * * -* Retour : - * +* Retour : Liste des instructions désassemblées ou None si aucune. * * * * Remarques : - * * * ******************************************************************************/ -bool py_arch_processor_type_define_constants(PyObject *dict) +static PyObject *py_arch_processor_get_disass_instrs(PyObject *self, void *closure) { - int ret; /* Bilan d'un ajout */ + PyObject *result; /* Instance Python à retourner */ + GArchProcessor *proc; /* Architecture visée */ + GArchInstruction *instrs; /* Série d'instructions liées */ - ret = PyDict_SetItemString(dict, "APT_JVM", PyInt_FromLong(APT_JVM)); - if (ret == -1) return false; + proc = G_ARCH_PROCESSOR(pygobject_get(self)); + instrs = g_arch_processor_get_disassembled_instructions(proc); - ret = PyDict_SetItemString(dict, "APT_MIPS", PyInt_FromLong(APT_MIPS)); - if (ret == -1) return false; + if (instrs != NULL) + result = pygobject_new(G_OBJECT(instrs)); + else + { + result = Py_None; + Py_INCREF(result); + } - ret = PyDict_SetItemString(dict, "APT_386", PyInt_FromLong(APT_386)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "APT_COUNT", PyInt_FromLong(APT_COUNT)); - if (ret == -1) return false; - - return true; + return result; } -PyObject *__test; + /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * * * -* Description : Ajoute l'objet 'arch.processor.ArchProcessorType' au module. * +* Description : Note les instructions désassemblées avec une architecture. * * * -* Retour : - * +* Retour : Bilan de l'opération pour Python. * * * * Remarques : - * * * ******************************************************************************/ -bool add_arch_processor_type_to_python_module(PyObject *module) +static int py_arch_processor_set_disass_instrs(PyObject *self, PyObject *value, void *closure) { - int ret; /* Bilan d'un appel */ + GArchProcessor *proc; /* Architecture visée */ + GArchInstruction *instrs; /* Série d'instructions liées */ - static PyTypeObject py_arch_processor_type_type = { + if (!PyObject_TypeCheck(value, get_python_arch_instruction_type())) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be an instruction.")); + return -1; + } - PyObject_HEAD_INIT(NULL) + proc = G_ARCH_PROCESSOR(pygobject_get(self)); + instrs = G_ARCH_INSTRUCTION(pygobject_get(value)); - .tp_name = "pyoida.arch.processor.ArchProcessorType", + g_arch_processor_set_disassembled_instructions(proc, instrs); - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + return 0; - .tp_doc = "PyOIDA version of the ArchProcessorType enumeration", +} - }; - if (PyType_Ready(&py_arch_processor_type_type) < 0) - return false; +/****************************************************************************** +* * +* Paramètres : self = processeur d'architecture à manipuler. * +* args = instruction représentant le point de départ. * +* * +* Description : Recherche une instruction d'après son adresse. * +* * +* Retour : Instruction trouvée à l'adresse donnée, None si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_arch_processor_find_instr_by_addr(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + PyObject *addr_obj; /* Objet pour une localisation */ + int ret; /* Bilan de lecture des args. */ + GArchProcessor *proc; /* Processeur manipulé */ + vmpa2t *addr; /* Localisation à retrouver */ + GArchInstruction *found; /* Instruction liée trouvée */ + + ret = PyArg_ParseTuple(args, "O", &addr_obj); + if (!ret) return NULL; + + ret = PyObject_IsInstance(addr_obj, (PyObject *)get_python_vmpa_type()); + if (!ret) return NULL; + + proc = G_ARCH_PROCESSOR(pygobject_get(self)); + addr = get_internal_vmpa(addr_obj); - py_arch_processor_type_define_constants(py_arch_processor_type_type.tp_dict); + found = g_arch_processor_find_instr_by_address(proc, addr); - Py_INCREF(&py_arch_processor_type_type); - ret = PyModule_AddObject(module, "ArchProcessorType", (PyObject *)&py_arch_processor_type_type); + if (found != NULL) + result = pygobject_new(G_OBJECT(found)); - __test = (PyObject *)&py_arch_processor_type_type; + else + { + result = Py_None; + Py_INCREF(result); + } - return (ret == 0); + return result; } +/****************************************************************************** +* * +* Paramètres : self = processeur d'architecture à manipuler. * +* args = instruction représentant le point de départ. * +* * +* Description : Fournit l'instruction qui en précède une autre. * +* * +* Retour : Instruction précédente trouvée, ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ -/* ---------------------------------------------------------------------------------- */ -/* PARTIE STATIQUE DE PROCESSEURS */ -/* ---------------------------------------------------------------------------------- */ +static PyObject *py_arch_processor_get_prev_instr(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + PyObject *instr_obj; /* Objet pour une instruction */ + int ret; /* Bilan de lecture des args. */ + GArchProcessor *proc; /* Processeur manipulé */ + GArchInstruction *instr; /* Instruction de référence */ + GArchInstruction *found; /* Instruction liée trouvée */ + ret = PyArg_ParseTuple(args, "O", &instr_obj); + if (!ret) return NULL; + ret = PyObject_IsInstance(instr_obj, (PyObject *)get_python_arch_instruction_type()); + if (!ret) return NULL; + proc = G_ARCH_PROCESSOR(pygobject_get(self)); + instr = G_ARCH_INSTRUCTION(pygobject_get(instr_obj)); + found = g_arch_processor_get_prev_instr(proc, instr); + if (found != NULL) + result = pygobject_new(G_OBJECT(found)); + else + { + result = Py_None; + Py_INCREF(result); + } + return result; +} +/****************************************************************************** +* * +* Paramètres : self = processeur d'architecture à manipuler. * +* args = instruction représentant le point de départ. * +* * +* Description : Fournit l'instruction qui en suit une autre. * +* * +* Retour : Instruction suivante trouvée, ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ +static PyObject *py_arch_processor_get_next_instr(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + PyObject *instr_obj; /* Objet pour une instruction */ + int ret; /* Bilan de lecture des args. */ + GArchProcessor *proc; /* Processeur manipulé */ + GArchInstruction *instr; /* Instruction de référence */ + GArchInstruction *found; /* Instruction liée trouvée */ + ret = PyArg_ParseTuple(args, "O", &instr_obj); + if (!ret) return NULL; + ret = PyObject_IsInstance(instr_obj, (PyObject *)get_python_arch_instruction_type()); + if (!ret) return NULL; + proc = G_ARCH_PROCESSOR(pygobject_get(self)); + instr = G_ARCH_INSTRUCTION(pygobject_get(instr_obj)); + found = g_arch_processor_get_next_instr(proc, instr); + if (found != NULL) + result = pygobject_new(G_OBJECT(found)); + else + { + result = Py_None; + Py_INCREF(result); + } + return result; +} -/* ---------------------------------------------------------------------------------- */ -/* PARTIE GRAPHIQUE DES [DE]CHARGEMENTS */ -/* ---------------------------------------------------------------------------------- */ @@ -186,103 +306,107 @@ bool add_arch_processor_type_to_python_module(PyObject *module) -/* Crée un nouvel objet Python de type 'py_processor'. */ -static PyObject *py_processor_new(PyTypeObject *, PyObject *, PyObject *); /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * +* Paramètres : - * * * -* Description : Crée un nouvel objet Python de type 'py_processor'. * +* Description : Fournit un accès à une définition de type à diffuser. * * * -* Retour : - * +* Retour : Définition d'objet pour Python. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_processor_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyTypeObject *get_python_arch_processor_type(void) { - py_processor *result; /* Instance à retourner */ - - result = (py_processor *)type->tp_alloc(type, 0); - - return (PyObject *)result; - -} - - + static PyMethodDef py_arch_processor_methods[] = { + { + "find_instr_by_addr", py_arch_processor_find_instr_by_addr, + METH_VARARGS, + "find_instr_by_addr($self, addr, /)\n--\n\nLook for an instruction located at a given address." + }, + { + "get_prev_instr", py_arch_processor_get_prev_instr, + METH_VARARGS, + "get_prev_instr($self, instr, /)\n--\n\nProvide the instruction preceding a given instruction." + }, + { + "get_next_instr", py_arch_processor_get_next_instr, + METH_VARARGS, + "get_next_instr($self, instr, /)\n--\n\nProvide the instruction following a given instruction." + }, + { NULL } + }; + static PyGetSetDef py_arch_processor_getseters[] = { + { + "disass_instrs", py_arch_processor_get_disass_instrs, py_arch_processor_set_disass_instrs, + "Give access to the disassembled instructions run by the current processor.", NULL + }, + { NULL } + }; + static PyTypeObject py_arch_processor_type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "pychrysalide.arch.ArchProcessor", + .tp_basicsize = sizeof(PyGObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE, + .tp_doc = "PyChrysalide processor for a given architecture.", + .tp_methods = py_arch_processor_methods, + .tp_getset = py_arch_processor_getseters, + }; + return &py_arch_processor_type; +} /****************************************************************************** * * * Paramètres : module = module dont la définition est à compléter. * * * -* Description : Ajoute l'objet 'analysis.roptions' au module Python. * +* Description : Prend en charge l'objet 'pychrysalide.arch.ArchProcessor'. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool add_arch_processor_to_python_module(PyObject *module) +bool register_python_arch_processor(PyObject *module) { - bool result; /* Bilan à retourner */ + PyTypeObject *py_arch_processor_type; /* Type Python 'BinContent' */ int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ - static PyMethodDef py_processor_methods[] = { - { NULL } - }; - - static PyGetSetDef py_processor_getset[] = { - { NULL } - }; - - static PyTypeObject py_processor_type = { + py_arch_processor_type = get_python_arch_processor_type(); - PyObject_HEAD_INIT(NULL) + py_arch_processor_type->tp_base = &PyGObject_Type; + py_arch_processor_type->tp_basicsize = py_arch_processor_type->tp_base->tp_basicsize; - .tp_name = "pyoida.arch.Processor", - .tp_basicsize = sizeof(py_processor), + APPLY_ABSTRACT_FLAG(py_arch_processor_type); - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - - .tp_doc = "PyOIDA processor for a given architecture", - - .tp_methods = py_processor_methods, - .tp_getset = py_processor_getset, - .tp_new = (newfunc)py_processor_new - - }; - - if (PyType_Ready(&py_processor_type) < 0) + if (PyType_Ready(py_arch_processor_type) != 0) return false; - //printf("ret import = %p\n", PyImport_ImportModule("pyoida.arch.processor.ArchProcessorType")); + Py_INCREF(py_arch_processor_type); + ret = PyModule_AddObject(module, "ArchProcessor", (PyObject *)py_arch_processor_type); + if (ret != 0) return false; + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ArchProcessor", G_TYPE_ARCH_PROCESSOR, py_arch_processor_type, + Py_BuildValue("(O)", py_arch_processor_type->tp_base)); - - Py_INCREF(&py_processor_type); - ret = PyModule_AddObject(module, "Processor", (PyObject *)&py_processor_type); - - result = add_arch_processor_type_to_python_module(module); - - - return (ret == 0 && result); + return true; } diff --git a/plugins/pychrysa/arch/processor.h b/plugins/pychrysa/arch/processor.h index 6a74176..26837cb 100644 --- a/plugins/pychrysa/arch/processor.h +++ b/plugins/pychrysa/arch/processor.h @@ -22,8 +22,8 @@ */ -#ifndef _PLUGINS_PYOIDA_ARCH_PROCESSOR_H -#define _PLUGINS_PYOIDA_ARCH_PROCESSOR_H +#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_PROCESSOR_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_PROCESSOR_H #include <Python.h> @@ -31,9 +31,12 @@ -/* Ajoute l'objet 'arch.processor' au module Python. */ -bool add_arch_processor_to_python_module(PyObject *); +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_arch_processor_type(void); +/* Prend en charge l'objet 'pychrysalide.arch.ArchProcessor'. */ +bool register_python_arch_processor(PyObject *); -#endif /* _PLUGINS_PYOIDA_ARCH_PROCESSOR_H */ + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_PROCESSOR_H */ diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c index 43131b5..350f61b 100644 --- a/plugins/pychrysa/arch/vmpa.c +++ b/plugins/pychrysa/arch/vmpa.c @@ -28,11 +28,14 @@ #include <string.h> +#include "../helpers.h" +/* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */ + typedef struct _py_vmpa_t @@ -49,7 +52,7 @@ typedef struct _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'. */ +/* Effectue une comparaison avec un objet Python 'vmpa_t'. */ static PyObject *py_vmpa_richcompare(PyObject *, PyObject *, int); /* Fournit une partie du contenu de la position représentée. */ @@ -67,12 +70,74 @@ static bool convert_pyobj_to_vmpa(PyObject *, vmpa2t *); /* Effectue une opération de type 'add' avec le type 'vmpa'. */ static PyObject *py_vmpa_nb_add(PyObject *, PyObject *); +/* Définit les constantes pour les localisations. */ +static bool py_vmpa_define_constants(PyTypeObject *); + + + +/* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ + + +/* Couverture mémoire */ +typedef struct _py_mrange_t +{ + PyObject_HEAD /* Préambule Python */ + + mrange_t range; /* Informations internes */ + +} py_mrange_t; + + +/* Fournit une représentation d'une variable 'mrange_t'. */ +static PyObject *py_mrange_to_str(PyObject *); + + + +/* Effectue une comparaison avec un objet Python 'mrange_t'. */ +static PyObject *py_mrange_richcompare(PyObject *, PyObject *, int); + + + +/* Indique si une zone en contient une autre ou non. */ +static PyObject *py_mrange_contains(PyObject *, PyObject *); + + + + +/* Fournit la position de départ de la zone mémoire représentée. */ +static PyObject *py_mrange_get_addr(PyObject *, void *); + +/* Définit la position de départ de la zone mémoire représentée. */ +static int py_mrange_set_addr(PyObject *, PyObject *, void *); + +/* Fournit la taille de la zone mémoire représentée. */ +static PyObject *py_mrange_get_length(PyObject *, void *); + +/* Définit la taille de la zone mémoire représentée. */ +static int py_mrange_set_length(PyObject *, PyObject *, void *); + +/* Calcule la position extérieure finale d'une couverture. */ +static PyObject *py_mrange_get_end_addr(PyObject *, void *); + + + +/* Crée un nouvel objet Python de type 'mrange'. */ +static PyObject *py_mrange_new(PyTypeObject *, PyObject *, PyObject *); + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UNE POSITION EN MEMOIRE */ +/* ---------------------------------------------------------------------------------- */ + + + + /****************************************************************************** * * * Paramètres : obj = objet Python à traiter. * @@ -119,7 +184,7 @@ static PyObject *py_vmpa_to_str(PyObject *obj) * 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'. * +* Description : Effectue une comparaison avec un objet Python 'vmpa_t'. * * * * Retour : Bilan de l'opération. * * * @@ -184,7 +249,7 @@ static PyObject *py_vmpa_get_value(PyObject *self, void *closure) key = (char *)closure; - if (strcmp(key, "phy") == 0) + if (strcmp(key, "phys") == 0) { if (get_phy_addr(&vmpa->addr) == VMPA_NO_PHYSICAL) { @@ -236,7 +301,7 @@ static int py_vmpa_set_value(PyObject *self, PyObject *value, void *closure) key = (char *)closure; - if (strcmp(key, "phy") == 0) + if (strcmp(key, "phys") == 0) { if (value == Py_None) init_vmpa(&vmpa->addr, VMPA_NO_PHYSICAL, get_virt_addr(&vmpa->addr)); @@ -296,7 +361,7 @@ static int py_vmpa_set_value(PyObject *self, PyObject *value, void *closure) static PyObject *py_vmpa_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - py_vmpa_t *result; /* Instance à retourner */ + py_vmpa_t *result; /* Instance à retourner */ unsigned long long phy; /* Position physique */ unsigned long long virt; /* Adresse en mémoire virtuelle*/ int ret; /* Bilan de lecture des args. */ @@ -442,6 +507,32 @@ void change_editor_items_current_view_content(void/*GtkViewPanel*/ *view) /****************************************************************************** * * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes pour les localisations. * +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_vmpa_define_constants(PyTypeObject *obj_type) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= PyDict_AddIntMacro(obj_type, VMPA_NO_PHYSICAL); + result &= PyDict_AddIntMacro(obj_type, VMPA_NO_VIRTUAL); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -504,13 +595,13 @@ PyTypeObject *get_python_vmpa_type(void) static PyGetSetDef py_vmpa_getseters[] = { { - "phy", py_vmpa_get_value, py_vmpa_set_value, - "Give access to the physical offset of the location", "phy" + "phys", py_vmpa_get_value, py_vmpa_set_value, + "Give access to the physical offset of the location.", "phys" }, { "virt", py_vmpa_get_value, py_vmpa_set_value, - "Give access to the virtual address of the location", "virt" + "Give access to the virtual address of the location.", "virt" }, { NULL } @@ -529,7 +620,7 @@ PyTypeObject *get_python_vmpa_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "Python object for vmpa_t", + .tp_doc = "Python object for vmpa_t.", .tp_richcompare = py_vmpa_richcompare, @@ -565,6 +656,9 @@ bool register_python_vmpa(PyObject *module) if (PyType_Ready(py_vmpa_type) != 0) return false; + if (!py_vmpa_define_constants(py_vmpa_type)) + return false; + Py_INCREF(py_vmpa_type); ret = PyModule_AddObject(module, "vmpa", (PyObject *)py_vmpa_type); @@ -595,3 +689,551 @@ vmpa2t *get_internal_vmpa(PyObject *obj) return &((py_vmpa_t *)obj)->addr; } + + +/****************************************************************************** +* * +* Paramètres : addr = structure interne à copier en objet Python. * +* * +* Description : Convertit une structure de type 'vmpa2t' en objet Python. * +* * +* Retour : Object Python résultant de la conversion opérée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *build_from_internal_vmpa(const vmpa2t *addr) +{ + py_vmpa_t *result; /* Instance à retourner */ + PyTypeObject *type; /* Type à instancier */ + + type = get_python_vmpa_type(); + + result = (py_vmpa_t *)type->tp_alloc(type, 0); + + copy_vmpa(&result->addr, addr); + + return (PyObject *)result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UNE ZONE EN MEMOIRE */ +/* ---------------------------------------------------------------------------------- */ + + + + + + + +/****************************************************************************** +* * +* Paramètres : obj = objet Python à traiter. * +* * +* Description : Fournit une représentation d'une variable 'mrange_t'. * +* * +* Retour : Chaîne de caractère pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_to_str(PyObject *obj) +{ + PyObject *result; /* Chaîne à retourner */ + + result = PyUnicode_FromFormat("<TODO!>"); + + return result; + +} + + + + +/****************************************************************************** +* * +* Paramètres : obj = objet Python à tenter de convertir. * +* addr = structure équivalente pour Chrysalide. * +* * +* Description : Effectue une comparaison avec un objet Python 'mrange_t'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_richcompare(PyObject *a, PyObject *b, int op) +{ + PyObject *result; /* Chaîne à retourner */ + mrange_t *range_a; /* Premier espace à traiter */ + mrange_t *range_b; /* Second espace à traiter */ + int status; /* Résultat d'une comparaison */ + + range_a = get_internal_mrange(a); + + range_b = get_internal_mrange(b); + if (range_b == NULL) return NULL; + + status = cmp_mrange(range_a, range_b); + + switch (op) + { + case Py_LT: + result = status < 0 ? Py_True : Py_False; + break; + + case Py_LE: + result = status <= 0 ? Py_True : Py_False; + break; + + case Py_EQ: + result = status == 0 ? Py_True : Py_False; + break; + + case Py_NE: + result = status != 0 ? Py_True : Py_False; + break; + + case Py_GT: + result = status > 0 ? Py_True : Py_False; + break; + + case Py_GE: + result = status >= 0 ? Py_True : Py_False; + break; + + default: + result = Py_NotImplemented; + break; + + } + + Py_INCREF(result); + + return result; + +} + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : self = contenu binaire à manipuler. * +* args = non utilisé ici. * +* * +* Description : Indique si une zone en contient une autre ou non. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_contains(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à faire remonter */ + int ret; /* Bilan de lecture des args. */ + PyObject *range_obj; /* Objet pour un intervale */ + mrange_t *range; /* Région mémoire de contenance*/ + mrange_t *sub; /* Région mémoire contenue ? */ + + ret = PyArg_ParseTuple(args, "O", &range_obj); + if (!ret) return NULL; + + ret = PyObject_IsInstance(range_obj, (PyObject *)get_python_mrange_type()); + if (!ret) return NULL; + + range = get_internal_mrange(self); + sub = get_internal_mrange(range_obj); + + result = (mrange_contains_mrange(range, sub) ? Py_True : Py_False); + + Py_INCREF(result); + + return result; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : self = définition de l'espace visé par la procédure. * +* closure = élément non utilisé ici. * +* * +* Description : Fournit la position de départ de la zone mémoire représentée.* +* * +* Retour : Nouvelle objet mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_get_addr(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + mrange_t *range; /* Espace mémoire à manipuler */ + + range = get_internal_mrange(self); + + result = build_from_internal_vmpa(get_mrange_addr(range)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = définition de l'espace visé par la procédure. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = élément non utilisé ici. * +* * +* Description : Définit la position de départ de la zone mémoire représentée.* +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_mrange_set_addr(PyObject *self, PyObject *value, void *closure) +{ + int result; /* Bilan à faire remonter */ + vmpa2t *addr; /* Localisation version C */ + mrange_t *range; /* Espace mémoire à manipuler */ + + result = 0; + + addr = get_internal_vmpa(value); + if (addr == NULL) return -1; + + range = get_internal_mrange(self); + + init_mrange(range, addr, get_mrange_length(range)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = définition de l'espace visé par la procédure. * +* closure = élément non utilisé ici. * +* * +* Description : Fournit la taille de la zone mémoire représentée. * +* * +* Retour : Nouvelle objet mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_get_length(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + mrange_t *range; /* Espace mémoire à manipuler */ + + range = get_internal_mrange(self); + + result = Py_BuildValue("K", get_mrange_length(range)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = définition de l'espace visé par la procédure. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = élément non utilisé ici. * +* * +* Description : Définit la taille de la zone mémoire représentée. * +* * +* Retour : Bilan de l'opération pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_mrange_set_length(PyObject *self, PyObject *value, void *closure) +{ + int result; /* Bilan à faire remonter */ + mrange_t *range; /* Espace mémoire à manipuler */ + PY_LONG_LONG val; /* Valeur traduite génériquemt */ + int overflow; /* Détection d'une grosse val. */ + vmpa2t tmp; /* Copie pour recopie */ + + result = 0; + + range = get_internal_mrange(self); + + val = PyLong_AsLongLongAndOverflow(value, &overflow); + + if (val == -1 && (overflow == 1 || PyErr_Occurred())) + { + result = -1; + PyErr_Clear(); + } + else + { + copy_vmpa(&tmp, get_mrange_addr(range)); + init_mrange(range, &tmp, val); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = définition de l'espace visé par la procédure. * +* closure = élément non utilisé ici. * +* * +* Description : Calcule la position extérieure finale d'une couverture. * +* * +* Retour : Nouvelle objet mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_get_end_addr(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + mrange_t *range; /* Espace mémoire à manipuler */ + vmpa2t end; /* Adresse à reproduire */ + + range = get_internal_mrange(self); + compute_mrange_end_addr(range, &end); + + result = build_from_internal_vmpa(&end); + + return result; + +} + + + + + + + + + +/****************************************************************************** +* * +* 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 'mrange'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_mrange_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + py_mrange_t *result; /* Instance à retourner */ + PyObject *py_vmpa; /* Localisation version Python */ + unsigned long long length; /* Taille physique */ + int ret; /* Bilan de lecture des args. */ + vmpa2t *addr; /* Localisation version C */ + + ret = PyArg_ParseTuple(args, "OK", &py_vmpa, &length); + if (!ret) return NULL; + + ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type()); + if (!ret) return NULL; + + addr = get_internal_vmpa(py_vmpa); + if (addr == NULL) return NULL; + + result = (py_mrange_t *)type->tp_alloc(type, 0); + + init_mrange(&result->range, addr, length); + + return (PyObject *)result; + +} + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_mrange_type(void) +{ + static PyMethodDef py_mrange_methods[] = { + { "contains", py_mrange_contains, + METH_VARARGS, + "contains($self, other, /)\n--\nTell if the current range contains another given range or address." + }, +#if 0 + { "read_u8", py_arch_instruction_read_u8, + METH_VARARGS, + "read_u8($self, addr, /)\n--\n\nRead an unsigned byte from a given position." + }, +#endif + { NULL } + }; + + static PyGetSetDef py_mrange_getseters[] = { + { + "addr", py_mrange_get_addr, py_mrange_set_addr, + "Give access to the start location of the memory range.", NULL + }, + { + "length", py_mrange_get_length, py_mrange_set_length, + "Give access to the length of the memory range.", NULL + }, + { + "end", py_mrange_get_end_addr, NULL, + "Provide the final external point of the memory range.", NULL + }, + { NULL } + }; + + static PyTypeObject py_mrange_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.mrange", + .tp_basicsize = sizeof(py_mrange_t), + + .tp_str = py_mrange_to_str, + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "Python object for mrange_t.", + + .tp_richcompare = py_mrange_richcompare, + + .tp_methods = py_mrange_methods, + .tp_getset = py_mrange_getseters, + .tp_new = (newfunc)py_mrange_new + + }; + + return &py_mrange_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.arch.mrange'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_mrange(PyObject *module) +{ + PyTypeObject *py_mrange_type; /* Type Python pour 'mrange' */ + int ret; /* Bilan d'un appel */ + + py_mrange_type = get_python_mrange_type(); + + if (PyType_Ready(py_mrange_type) != 0) + return false; + + Py_INCREF(py_mrange_type); + ret = PyModule_AddObject(module, "mrange", (PyObject *)py_mrange_type); + + return (ret == 0); + +} + + +/****************************************************************************** +* * +* Paramètres : obj = objet Python à traiter. * +* * +* Description : Donne accès au coeur d'un objet 'pychrysalide.arch.mrange'. * +* * +* Retour : Localistion réelle ou NULL en cas de mauvaise conversion. * +* * +* Remarques : - * +* * +******************************************************************************/ + +mrange_t *get_internal_mrange(PyObject *obj) +{ + int ret; /* Bilan d'analyse */ + + ret = PyObject_IsInstance(obj, (PyObject *)get_python_mrange_type()); + if (!ret) return NULL; + + return &((py_mrange_t *)obj)->range; + +} + + +/****************************************************************************** +* * +* Paramètres : range = structure interne à copier en objet Python. * +* * +* Description : Convertit une structure de type 'mrange_t' en objet Python. * +* * +* Retour : Object Python résultant de la conversion opérée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *build_from_internal_mrange(const mrange_t *range) +{ + py_mrange_t *result; /* Instance à retourner */ + PyTypeObject *type; /* Type à instancier */ + + type = get_python_mrange_type(); + + result = (py_mrange_t *)type->tp_alloc(type, 0); + + copy_mrange(&result->range, range); + + return (PyObject *)result; + +} diff --git a/plugins/pychrysa/arch/vmpa.h b/plugins/pychrysa/arch/vmpa.h index 8635b51..6c51d3e 100644 --- a/plugins/pychrysa/arch/vmpa.h +++ b/plugins/pychrysa/arch/vmpa.h @@ -43,6 +43,26 @@ bool register_python_vmpa(PyObject *); /* Donne accès au coeur d'un objet 'pychrysalide.arch.vmpa'. */ vmpa2t *get_internal_vmpa(PyObject *); +/* Convertit une structure de type 'vmpa2t' en objet Python. */ +PyObject *build_from_internal_vmpa(const vmpa2t *); + + + +/* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_mrange_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.mrange'. */ +bool register_python_mrange(PyObject *); + +/* Donne accès au coeur d'un objet 'pychrysalide.arch.mrange'. */ +mrange_t *get_internal_mrange(PyObject *); + +/* Convertit une structure de type 'mrange_t' en objet Python. */ +PyObject *build_from_internal_mrange(const mrange_t *); + #endif /* _PLUGINS_PYCHRYSALIDE_ARCH_VMPA_H */ |