diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-02-04 12:23:04 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-02-04 12:23:04 (GMT) |
commit | ec0f07c0b9468d6798befd887b02d9668faf806b (patch) | |
tree | f8b243f9b08006a4206b29b9af5b73a5d25361c7 /plugins/pychrysalide/arch | |
parent | 296b4ed15fd074f80266e1d22ef4ade7ee11905e (diff) |
Created a new interface for renamed operands.
Diffstat (limited to 'plugins/pychrysalide/arch')
-rw-r--r-- | plugins/pychrysalide/arch/operands/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/operands/immediate.c | 253 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/operands/immediate.h | 20 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/operands/module.c | 4 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/operands/rename.c | 314 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/operands/rename.h | 56 | ||||
-rw-r--r-- | plugins/pychrysalide/arch/operands/targetable.c | 5 |
7 files changed, 648 insertions, 5 deletions
diff --git a/plugins/pychrysalide/arch/operands/Makefile.am b/plugins/pychrysalide/arch/operands/Makefile.am index 7974c42..7938320 100644 --- a/plugins/pychrysalide/arch/operands/Makefile.am +++ b/plugins/pychrysalide/arch/operands/Makefile.am @@ -6,6 +6,7 @@ libpychrysaarchoperands_la_SOURCES = \ immediate.h immediate.c \ module.h module.c \ register.h register.c \ + rename.h rename.c \ targetable.h targetable.c libpychrysaarchoperands_la_LIBADD = diff --git a/plugins/pychrysalide/arch/operands/immediate.c b/plugins/pychrysalide/arch/operands/immediate.c index ab9e16c..6353655 100644 --- a/plugins/pychrysalide/arch/operands/immediate.c +++ b/plugins/pychrysalide/arch/operands/immediate.c @@ -36,6 +36,7 @@ #include "constants.h" +#include "rename.h" #include "targetable.h" #include "../operand.h" #include "../../access.h" @@ -44,6 +45,9 @@ +/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ + + /* Crée un nouvel objet Python de type 'ImmOperand'. */ static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *); @@ -79,6 +83,19 @@ static int py_imm_operand_set_display(PyObject *, PyObject *, void *); +/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */ + + +/* Crée un nouvel objet Python de type 'KnownImmOperand'. */ +static PyObject *py_known_imm_operand_new(PyTypeObject *, PyObject *, PyObject *); + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDE POUR VALEUR IMMEDIATE */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * * Paramètres : type = type de l'objet à instancier. * @@ -610,7 +627,7 @@ PyTypeObject *get_python_imm_operand_type(void) .tp_name = "pychrysalide.arch.operands.ImmOperand", .tp_basicsize = sizeof(PyGObject), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = IMM_OPERAND_DOC, @@ -657,6 +674,9 @@ bool ensure_python_imm_operand_is_registered(void) if (!ensure_python_targetable_operand_is_registered()) return false; + if (!ensure_python_renameable_operand_is_registered()) + return false; + if (!register_class_for_pygobject(dict, G_TYPE_IMM_OPERAND, type, get_python_arch_operand_type())) return false; @@ -668,3 +688,234 @@ bool ensure_python_imm_operand_is_registered(void) return true; } + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en opérande de valeur immédiate. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_imm_operand(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_imm_operand_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to immediate operand"); + break; + + case 1: + *((GImmOperand **)dst) = G_IMM_OPERAND(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* REMPLACEMENT DE VALEURS IMMEDIATES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* 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 'KnownImmOperand'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_known_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + GImmOperand *imm; /* Opérande à remplacer */ + const char *alt; /* Impression alternative */ + int ret; /* Bilan de lecture des args. */ + GArchOperand *operand; /* Création GLib à transmettre */ + +#define KNOWN_IMM_OPERAND_DOC \ + "The KnownImmOperand provides replacement of" \ + " pychrysalide.arch.operands.ImmOperand instances by an alternative" \ + " text.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " KnownImmOperand(imm, alt)" \ + "\n" \ + "Where imm is an operand of type pychrysalide.arch.operands.ImmOperand" \ + " and alt is a string providing the text to be rendered at object" \ + " display." + + ret = PyArg_ParseTuple(args, "O&s", convert_to_imm_operand, &imm, &alt); + if (!ret) return NULL; + + operand = g_known_imm_operand_new(imm, alt); + + result = pygobject_new(G_OBJECT(operand)); + + g_object_unref(operand); + + 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_known_imm_operand_type(void) +{ + static PyMethodDef py_known_imm_operand_methods[] = { + { NULL } + }; + + static PyGetSetDef py_known_imm_operand_getseters[] = { + { NULL } + }; + + static PyTypeObject py_known_imm_operand_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.operands.KnownImmOperand", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = KNOWN_IMM_OPERAND_DOC, + + .tp_methods = py_known_imm_operand_methods, + .tp_getset = py_known_imm_operand_getseters, + .tp_new = py_known_imm_operand_new + + }; + + return &py_known_imm_operand_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.arch.KnownImmOperand'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_known_imm_operand_is_registered(void) +{ + PyTypeObject *type; /* Type Python 'ImmOperand' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_known_imm_operand_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.arch.operands"); + + dict = PyModule_GetDict(module); + + if (!ensure_python_imm_operand_is_registered()) + return false; + + if (!ensure_python_renamed_operand_is_registered()) + return false; + + if (!register_class_for_pygobject(dict, G_TYPE_KNOWN_IMM_OPERAND, type, get_python_imm_operand_type())) + return false; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en remplaçant d'opérande d'immédiat. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_known_imm_operand(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_known_imm_operand_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to known immediate operand"); + break; + + case 1: + *((GKnownImmOperand **)dst) = G_KNOWN_IMM_OPERAND(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/arch/operands/immediate.h b/plugins/pychrysalide/arch/operands/immediate.h index 9f32758..fe5d4a9 100644 --- a/plugins/pychrysalide/arch/operands/immediate.h +++ b/plugins/pychrysalide/arch/operands/immediate.h @@ -31,12 +31,32 @@ +/* ------------------------- OPERANDE POUR VALEUR IMMEDIATE ------------------------- */ + + /* Fournit un accès à une définition de type à diffuser. */ PyTypeObject *get_python_imm_operand_type(void); /* Prend en charge l'objet 'pychrysalide.arch.ImmOperand'. */ bool ensure_python_imm_operand_is_registered(void); +/* Tente de convertir en opérande de valeur immédiate. */ +int convert_to_imm_operand(PyObject *, void *); + + + +/* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_known_imm_operand_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.KnownImmOperand'. */ +bool ensure_python_known_imm_operand_is_registered(void); + +/* Tente de convertir en remplaçant d'opérande d'immédiat. */ +int convert_to_known_imm_operand(PyObject *, void *); + #endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_IMMEDIATE_H */ diff --git a/plugins/pychrysalide/arch/operands/module.c b/plugins/pychrysalide/arch/operands/module.c index f800e38..34614b3 100644 --- a/plugins/pychrysalide/arch/operands/module.c +++ b/plugins/pychrysalide/arch/operands/module.c @@ -30,6 +30,7 @@ #include "immediate.h" #include "register.h" +#include "rename.h" #include "targetable.h" #include "../../helpers.h" @@ -97,7 +98,10 @@ bool populate_arch_operands_module(void) result = true; if (result) result = ensure_python_imm_operand_is_registered(); + if (result) result = ensure_python_known_imm_operand_is_registered(); if (result) result = ensure_python_register_operand_is_registered(); + if (result) result = ensure_python_renamed_operand_is_registered(); + if (result) result = ensure_python_renameable_operand_is_registered(); if (result) result = ensure_python_targetable_operand_is_registered(); assert(result); diff --git a/plugins/pychrysalide/arch/operands/rename.c b/plugins/pychrysalide/arch/operands/rename.c new file mode 100644 index 0000000..da1543b --- /dev/null +++ b/plugins/pychrysalide/arch/operands/rename.c @@ -0,0 +1,314 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * rename.c - prototypes pour l'équivalent Python du fichier "arch/operands/rename.c" + * + * Copyright (C) 2020 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 "rename.h" + + +#include <pygobject.h> + + +#include <arch/operands/rename.h> + + +#include "../../access.h" +#include "../../helpers.h" + + + +/* ------------------------ INTERFACE POUR OPERANDE RENOMMEE ------------------------ */ + + +#define RENAMED_OPERAND_DOC \ + "The RenamedOperand interface depicts operands renamed with an" \ + " alternative text." + + +/* Fournit un texte comme représentation alternative d'opérande. */ +static PyObject *py_renamed_operand_get_text(PyObject *, void *); + + + +/* ----------------------- INTERFACE POUR OPERANDE RENOMMABLE ----------------------- */ + + +#define RENAMEABLE_OPERAND_DOC \ + "The RenameableOperand interface depicts operands which can get" \ + " renamed with an alternative text." \ + + +/* Construit un opérande de représentation alternative. */ +static PyObject *py_renameable_operand_build(PyObject *, PyObject *); + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE POUR OPERANDE RENOMMEE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit un texte comme représentation alternative d'opérande.* +* * +* Retour : Chaîne de caractère de représentation alternative. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_renamed_operand_get_text(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GRenamedOperand *operand; /* Elément à consulter */ + const char *text; /* Texte alternatif de rendu */ + +#define RENAMED_OPERAND_TEXT_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + text, py_renamed_operand, \ + "Alternative text for the operand rendering." \ +) + + operand = G_RENAMED_OPERAND(pygobject_get(self)); + text = g_renamed_operand_get_text(operand); + + result = PyUnicode_FromString(text); + + 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_renamed_operand_type(void) +{ + static PyMethodDef py_renamed_operand_methods[] = { + { NULL } + }; + + static PyGetSetDef py_renamed_operand_getseters[] = { + RENAMED_OPERAND_TEXT_ATTRIB, + { NULL } + }; + + static PyTypeObject py_renamed_operand_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.operands.RenamedOperand", + .tp_basicsize = sizeof(PyObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = RENAMED_OPERAND_DOC, + + .tp_methods = py_renamed_operand_methods, + .tp_getset = py_renamed_operand_getseters + + }; + + return &py_renamed_operand_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....RenamedOperand'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_renamed_operand_is_registered(void) +{ + PyTypeObject *type; /* Type 'RenamedOperand' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_renamed_operand_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.arch.operands"); + + dict = PyModule_GetDict(module); + + if (!register_interface_for_pygobject(dict, G_TYPE_RENAMED_OPERAND, type)) + return false; + + } + + return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE POUR OPERANDE RENOMMABLE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : self = contenu binaire à manipuler. * +* args = argument accompagnant l'appel. * +* * +* Description : Construit un opérande de représentation alternative. * +* * +* Retour : Nouvel opérande, en version renommée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_renameable_operand_build(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + const char *text; /* Texte alternatif à utiliser */ + int ret; /* Bilan de lecture des args. */ + GRenameableOperand *operand; /* Instance à manipuler */ + GRenamedOperand *renamed; /* Instance nouvelle */ + +#define RENAMEABLE_OPERAND_BUILD_METHOD PYTHON_METHOD_DEF \ +( \ + build, "$self, text", \ + METH_VARARGS, py_renameable_operand, \ + "Build a new operand with an alternative text as rendering." \ + "\n" \ + "The result of the call is an object implementing the" \ + " pychrysalide.arch.operands.RenamedOperand interface." \ +) + + ret = PyArg_ParseTuple(args, "s", &text); + if (!ret) return NULL; + + operand = G_RENAMEABLE_OPERAND(pygobject_get(self)); + + renamed = g_renameable_operand_build(operand, text); + + result = pygobject_new(G_OBJECT(renamed)); + g_object_unref(G_OBJECT(renamed)); + + 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_renameable_operand_type(void) +{ + static PyMethodDef py_renameable_operand_methods[] = { + RENAMEABLE_OPERAND_BUILD_METHOD, + { NULL } + }; + + static PyGetSetDef py_renameable_operand_getseters[] = { + { NULL } + }; + + static PyTypeObject py_renameable_operand_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.operands.RenameableOperand", + .tp_basicsize = sizeof(PyObject), + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = RENAMEABLE_OPERAND_DOC, + + .tp_methods = py_renameable_operand_methods, + .tp_getset = py_renameable_operand_getseters + + }; + + return &py_renameable_operand_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....RenameableOperand'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_renameable_operand_is_registered(void) +{ + PyTypeObject *type; /* Type 'RenameableOperand' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_renameable_operand_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.arch.operands"); + + dict = PyModule_GetDict(module); + + if (!register_interface_for_pygobject(dict, G_TYPE_RENAMEABLE_OPERAND, type)) + return false; + + } + + return true; + +} diff --git a/plugins/pychrysalide/arch/operands/rename.h b/plugins/pychrysalide/arch/operands/rename.h new file mode 100644 index 0000000..a7f9233 --- /dev/null +++ b/plugins/pychrysalide/arch/operands/rename.h @@ -0,0 +1,56 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * rename.h - prototypes pour l'équivalent Python du fichier "arch/operands/rename.h" + * + * Copyright (C) 2020 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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_OPERANDS_RENAME_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_RENAME_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* ------------------------ INTERFACE POUR OPERANDE RENOMMEE ------------------------ */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_renamed_operand_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.RenamedOperand'. */ +bool ensure_python_renamed_operand_is_registered(void); + + + +/* ----------------------- INTERFACE POUR OPERANDE RENOMMABLE ----------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_renameable_operand_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.RenameableOperand'. */ +bool ensure_python_renameable_operand_is_registered(void); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_RENAME_H */ diff --git a/plugins/pychrysalide/arch/operands/targetable.c b/plugins/pychrysalide/arch/operands/targetable.c index a633b82..00647cc 100644 --- a/plugins/pychrysalide/arch/operands/targetable.c +++ b/plugins/pychrysalide/arch/operands/targetable.c @@ -28,9 +28,6 @@ #include <pygobject.h> -#include <i18n.h> - - #include <arch/operands/targetable.h> @@ -59,7 +56,7 @@ static PyObject *py_targetable_operand_get_addr(PyObject *, PyObject *); /****************************************************************************** * * * Paramètres : self = contenu binaire à manipuler. * -* args = non utilisé ici. * +* args = arguments accompagnant l'appel. * * * * Description : Obtient l'adresse de la cible visée par un opérande. * * * |