From 411f03130cf45194689bc344f19a3b77c33a31ae Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 23 Nov 2024 16:59:19 +0100 Subject: Restore more features for formats. --- plugins/dex/format.c | 30 - plugins/pychrysalide/arch/vmpa.c | 18 +- plugins/pychrysalide/core.c | 2 +- plugins/pychrysalide/format/executable.c | 392 +++++++++++-- plugins/pychrysalide/format/flat.c | 8 +- plugins/pychrysalide/format/known.c | 173 +----- plugins/pychrysalide/format/program.c | 188 +++++- plugins/pychrysalide/glibext/Makefile.am | 4 +- plugins/pychrysalide/glibext/constants.c | 10 +- plugins/pychrysalide/glibext/constants.h | 4 + plugins/pychrysalide/glibext/module.c | 4 +- plugins/pychrysalide/glibext/portion.c | 195 +++---- plugins/pychrysalide/glibext/portion.h | 12 +- src/format/executable-int.c | 155 ----- src/format/executable-int.h | 48 +- src/format/executable.c | 402 +++++-------- src/format/executable.h | 74 +-- src/format/flat-int.h | 2 +- src/format/flat.c | 38 +- src/format/known-int.h | 10 +- src/format/known.c | 48 +- src/format/known.h | 11 +- src/format/program-int.h | 6 + src/format/program.c | 52 ++ src/format/program.h | 8 +- src/glibext/Makefile.am | 4 +- src/glibext/portion-int.h | 37 +- src/glibext/portion.c | 963 ++++--------------------------- src/glibext/portion.h | 141 ++--- tests/format/executable.py | 59 ++ tests/glibext/portion.py | 17 + 31 files changed, 1139 insertions(+), 1976 deletions(-) delete mode 100644 src/format/executable-int.c create mode 100644 tests/format/executable.py create mode 100644 tests/glibext/portion.py diff --git a/plugins/dex/format.c b/plugins/dex/format.c index ccf21a8..f9a2410 100644 --- a/plugins/dex/format.c +++ b/plugins/dex/format.c @@ -70,9 +70,6 @@ static const char *g_dex_format_get_target_machine(const GDexFormat *); /* Etend la définition des portions au sein d'un binaire. */ static void g_dex_format_refine_portions(GDexFormat *); -/* Fournit l'emplacement d'une section donnée. */ -static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const char *, mrange_t *); - @@ -166,8 +163,6 @@ static void g_dex_format_class_init(GDexFormatClass *klass) exe->translate_phys = (translate_phys_fc)g_exe_format_without_virt_translate_offset_into_vmpa; exe->translate_virt = (translate_virt_fc)g_exe_format_without_virt_translate_address_into_vmpa; - exe->get_range_by_name = (get_range_by_name_fc)g_dex_format_get_section_range_by_name; - } @@ -515,31 +510,6 @@ static void g_dex_format_refine_portions(GDexFormat *format) } -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* name = nom de la section recherchée. * -* range = emplacement en mémoire à renseigner. [OUT] * -* * -* Description : Fournit l'emplacement d'une section donnée. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_dex_format_get_section_range_by_name(const GDexFormat *format, const char *name, mrange_t *range) -{ - bool result; /* Bilan à retourner */ - - result = false; - - return result; - -} - - diff --git a/plugins/pychrysalide/arch/vmpa.c b/plugins/pychrysalide/arch/vmpa.c index 20784cd..5162fac 100644 --- a/plugins/pychrysalide/arch/vmpa.c +++ b/plugins/pychrysalide/arch/vmpa.c @@ -824,13 +824,23 @@ PyObject *build_from_internal_vmpa(const vmpa2t *addr) PyTypeObject *type; /* Type à instancier */ PyObject *args; /* Liste des arguments d'appel */ - type = get_python_vmpa_type(); + if (get_phy_addr(addr) == VMPA_NO_PHYSICAL && get_virt_addr(addr) == VMPA_NO_VIRTUAL) + { + result = Py_None; + Py_INCREF(result); + } + + else + { + type = get_python_vmpa_type(); - args = Py_BuildValue("KK", get_phy_addr(addr), get_virt_addr(addr)); + args = Py_BuildValue("KK", get_phy_addr(addr), get_virt_addr(addr)); - result = PyObject_CallObject((PyObject *)type, args); + result = PyObject_CallObject((PyObject *)type, args); - Py_DECREF(args); + Py_DECREF(args); + + } return result; diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index c76fae4..8d69933 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -661,8 +661,8 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) /* if (status) status = ensure_python_string_enum_is_registered(); - if (status) status = ensure_python_py_struct_is_registered(); */ + if (status) status = ensure_python_py_struct_is_registered(); if (status) status = define_data_types_constants(result); diff --git a/plugins/pychrysalide/format/executable.c b/plugins/pychrysalide/format/executable.c index d886e9a..7d05578 100644 --- a/plugins/pychrysalide/format/executable.c +++ b/plugins/pychrysalide/format/executable.c @@ -36,9 +36,10 @@ #include "program.h" #include "../access.h" #include "../helpers.h" +#include "../analysis/content.h" //#include "../arch/processor.h" -//#include "../arch/vmpa.h" -//#include "../glibext/binportion.h" +#include "../arch/vmpa.h" +#include "../glibext/portion.h" @@ -56,23 +57,35 @@ static int py_executable_format_init(PyObject *, PyObject *, PyObject *); /* Indique le type d'architecture visée par le format. */ static char *py_executable_format_get_target_machine_wrapper(const GExecutableFormat *); +/* Fournit l'adresse principale associée à un format. */ +static bool py_executable_format_get_main_address_wrapper(GExecutableFormat *, vmpa2t *); + +/* Etend la définition des portions au sein d'un binaire. */ +static bool py_executable_format_refine_portions_wrapper(GExecutableFormat *); + /* ------------------------ DECLARATION DE FORMAT EXECUTABLE ------------------------ */ -/* Enregistre une portion artificielle pour le format. */ -//static PyObject *py_executable_format_register_user_portion(PyObject *, PyObject *); +/* Procède à l'enregistrement d'une portion dans un format. */ +static PyObject *py_executable_format_include_portion(PyObject *, PyObject *); /* Fournit l'emplacement correspondant à une position physique. */ -//static PyObject *py_executable_format_translate_offset_into_vmpa(PyObject *, PyObject *); +static PyObject *py_executable_format_translate_offset_into_vmpa(PyObject *, PyObject *); /* Fournit l'emplacement correspondant à une adresse virtuelle. */ -//static PyObject *py_executable_format_translate_address_into_vmpa(PyObject *, PyObject *); +static PyObject *py_executable_format_translate_address_into_vmpa(PyObject *, PyObject *); /* Indique le type d'architecture visée par le format. */ static PyObject *py_executable_format_get_target_machine(PyObject *, void *); +/* Fournit l'adresse principale associée à un format. */ +static PyObject *py_executable_format_get_main_address(PyObject *, void *); + +/* Indique le type d'architecture visée par le format. */ +static PyObject *py_executable_format_get_portions(PyObject *, void *); + /* ---------------------------------------------------------------------------------- */ @@ -97,6 +110,9 @@ static void py_executable_format_init_gclass(GExecutableFormatClass *class, gpoi { class->get_machine = py_executable_format_get_target_machine_wrapper; + class->get_main_addr = py_executable_format_get_main_address_wrapper; + class->refine_portions = py_executable_format_refine_portions_wrapper; + } @@ -116,24 +132,42 @@ static void py_executable_format_init_gclass(GExecutableFormatClass *class, gpoi static int py_executable_format_init(PyObject *self, PyObject *args, PyObject *kwds) { + GBinContent *content; /* Contenu à intégrer au format*/ int ret; /* Bilan de lecture des args. */ + GExecutableFormat *format; /* Format à manipuler */ #define EXECUTABLE_FORMAT_DOC \ "The ExecutableFormat class provides support for formats containing"\ " code to run.\n" \ "\n" \ - "The following method has to be defined for new classes:\n" \ + "The following methods have to be defined for new classes:\n" \ "* pychrysalide.format.ExecutableFormat._get_target_machine();\n" \ + "* pychrysalide.format.ExecutableFormat._get_main_address().\n" \ "\n" \ + "The following method may be defined for new classes:\n" \ + "* pychrysalide.format.ExecutableFormat._refine_portions().\n" \ "\n" \ "Calls to the *__init__* constructor of this abstract object expect"\ - " no particular argument." + " only one argument: a binary content, provided as a" \ + " pychrysalide.analysis.BinContent instance." + + /* Récupération des paramètres */ + + ret = PyArg_ParseTuple(args, "O&", convert_to_binary_content, &content); + if (!ret) return -1; /* Initialisation d'un objet GLib */ ret = forward_pygobjet_init(self); if (ret == -1) return -1; + /* Eléments de base */ + + format = G_EXECUTABLE_FORMAT(pygobject_get(self)); + + if (!g_executable_format_create(format, content)) + return -1; + return 0; } @@ -203,41 +237,221 @@ static char *py_executable_format_get_target_machine_wrapper(const GExecutableFo } +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse principale trouvée si possible. [OUT] * +* * +* Description : Fournit l'adresse principale associée à un format. * +* * +* Retour : Validité de l'adresse transmise. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_executable_format_get_main_address_wrapper(GExecutableFormat *format, vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyret; /* Valeur retournée */ + vmpa2t *tmp; /* Zone de stockage Python */ + int ret; /* Bilan d'une conversion */ + +#define EXECUTABLE_FORMAT_GET_MAIN_ADDRESS_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _get_main_address, "$self", \ + METH_NOARGS, \ + "Abstract method used to provide the main address of code for" \ + " the executable format.\n" \ + "\n" \ + "The return value has to be a pychrysalide.arch.vmpa instance or" \ + " *None* in case of failure." \ + ) + + result = false; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(format)); + + if (has_python_method(pyobj, "_get_main_address")) + { + pyret = run_python_method(pyobj, "_get_main_address", NULL); + + if (pyret != NULL) + { + if (pyret == Py_None) + { + init_vmpa(addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); + result = true; + } + + else + { + ret = convert_any_to_vmpa(pyret, &tmp); + + result = (ret == 1 || ret == Py_CLEANUP_SUPPORTED); + + if (result) + { + copy_vmpa(addr, tmp); + + if (ret == Py_CLEANUP_SUPPORTED) + clean_vmpa_arg(tmp); + + } + + else + { + /** + * L'erreur Python peut être effacée. + * + * Elle sera remontée : + * - au code C via le retour (false) : + * - à Python lors de l'accès à la propriétée. + */ + PyErr_Clear(); + + } + + } + + Py_DECREF(pyret); + + } + + } + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Etend la définition des portions au sein d'un binaire. * +* * +* Retour : Bilan des définitions de portions. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_executable_format_refine_portions_wrapper(GExecutableFormat *format) +{ + bool result; /* Bilan à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyret; /* Valeur retournée */ + +#define EXECUTABLE_FORMAT_REFINE_PORTIONS_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _refine_portions, "$self", \ + METH_NOARGS, \ + "Abstract method used to extend the definition of the format" \ + " with binary portions.\n" \ + "\n" \ + "Extra portions should be included with calls to" \ + " pychrysalide.format.ExecutableFormat.include_portion().\n" \ + "\n" \ + "The return value has to be a boolean value: *True* in case of" \ + " success, *False* in case of failure." \ +) + + result = true; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(format)); + + if (has_python_method(pyobj, "_refine_portions")) + { + pyret = run_python_method(pyobj, "_refine_portions", NULL); + + if (pyret != NULL) + { + result = (pyret == Py_True); + Py_DECREF(pyret); + } + + } + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* DECLARATION DE FORMAT EXECUTABLE */ /* ---------------------------------------------------------------------------------- */ -#if 0 /****************************************************************************** * * * Paramètres : self = description de l'exécutable à consulter. * * args = arguments accompagnant l'appel. * * * -* Description : Enregistre une portion artificielle pour le format. * +* Description : Procède à l'enregistrement d'une portion dans un format. * * * -* Retour : - * +* Retour : Bilan de l'opération : True si inclusion, False sinon. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_executable_format_register_user_portion(PyObject *self, PyObject *args) +static PyObject *py_executable_format_include_portion(PyObject *self, PyObject *args) { - GBinPortion *portion; /* Portion binaire à conserver */ + PyObject *result; /* Bilan à retourner */ + GBinaryPortion *portion; /* Portion binaire à conserver */ + vmpa2t *origin; /* Source de l'inclusion */ int ret; /* Bilan de lecture des args. */ GExecutableFormat *format; /* Version GLib du format */ + bool status; /* Bilan de l'inclusion */ + +#define EXECUTABLE_FORMAT_INCLUDE_PORTION_METHOD PYTHON_METHOD_DEF \ +( \ + include_portion, "$self, portion, /, origin=None", \ + METH_VARARGS, py_executable_format, \ + "Register a new portion inside the content of an executable format.\n" \ + "\n" \ + "The *portion* argument is a pychrysalide.glibext.BinaryPortion" \ + " instance. The optional *origin* arguement specifies the source of the"\ + " operation, as a pychrysalide.arch.vmpa definition, which may be used" \ + " for tracking errors.\n" \ + "\n" \ + "The return value is a boolean value: *True* in case of success," \ + " *False* in case of failure." \ +) + + origin = NULL; - ret = PyArg_ParseTuple(args, "O&", convert_to_binary_portion, &portion); + ret = PyArg_ParseTuple(args, "O&|O&", convert_to_binary_portion, &portion, convert_any_to_vmpa, &origin); if (!ret) return NULL; format = G_EXECUTABLE_FORMAT(pygobject_get(self)); - g_object_ref(G_OBJECT(portion)); - g_exe_format_register_user_portion(format, portion); + status = g_executable_format_include_portion(format, portion, origin); + + result = status ? Py_True : Py_False; + Py_INCREF(result); - Py_RETURN_NONE; + if (origin != NULL) + clean_vmpa_arg(origin); + + return result; } @@ -264,13 +478,24 @@ static PyObject *py_executable_format_translate_offset_into_vmpa(PyObject *self, vmpa2t pos; /* Position complète déterminée*/ bool status; /* Bilan de l'opération */ - format = G_EXECUTABLE_FORMAT(pygobject_get(self)); - assert(format != NULL); +#define EXECUTABLE_FORMAT_TRANSLATE_OFFSET_INTO_VMPA_METHOD PYTHON_METHOD_DEF \ +( \ + translate_offset_into_vmpa, "$self, addr", \ + METH_VARARGS, py_executable_format, \ + "Translate a physical offset to a full location.\n" \ + "\n" \ + "The *off* argument is a physical offset provided as an integer value.\n" \ + "\n" \ + "The returned position is a pychrysalide.arch.vmpa instance or *None* in" \ + " case of failure." \ +) ret = PyArg_ParseTuple(args, "K", &off); if (!ret) return NULL; - status = g_exe_format_translate_offset_into_vmpa(format, off, &pos); + format = G_EXECUTABLE_FORMAT(pygobject_get(self)); + + status = g_executable_format_translate_offset_into_vmpa(format, off, &pos); if (status) result = build_from_internal_vmpa(&pos); @@ -308,13 +533,24 @@ static PyObject *py_executable_format_translate_address_into_vmpa(PyObject *self vmpa2t pos; /* Position complète déterminée*/ bool status; /* Bilan de l'opération */ - format = G_EXECUTABLE_FORMAT(pygobject_get(self)); - assert(format != NULL); +#define EXECUTABLE_FORMAT_TRANSLATE_ADDRESS_INTO_VMPA_METHOD PYTHON_METHOD_DEF \ +( \ + translate_address_into_vmpa, "$self, addr", \ + METH_VARARGS, py_executable_format, \ + "Translate a virtual address to a full location.\n" \ + "\n" \ + "The *addr* argument is a virtual address provided as an integer value.\n" \ + "\n" \ + "The returned position is a pychrysalide.arch.vmpa instance or *None* in" \ + " case of failure." \ +) ret = PyArg_ParseTuple(args, "K", &addr); if (!ret) return NULL; - status = g_exe_format_translate_address_into_vmpa(format, addr, &pos); + format = G_EXECUTABLE_FORMAT(pygobject_get(self)); + + status = g_executable_format_translate_address_into_vmpa(format, addr, &pos); if (status) result = build_from_internal_vmpa(&pos); @@ -328,7 +564,6 @@ static PyObject *py_executable_format_translate_address_into_vmpa(PyObject *self return result; } -#endif /****************************************************************************** @@ -382,6 +617,91 @@ static PyObject *py_executable_format_get_target_machine(PyObject *self, void *c /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit l'adresse principale associée à un format. * +* * +* Retour : Validité de l'adresse transmise. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_executable_format_get_main_address(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GExecutableFormat *format; /* Format exécutable manipulé */ + vmpa2t addr; /* Point d'entrée principal */ + bool status; /* Validité de l'adresse */ + +#define EXECUTABLE_FORMAT_MAIN_ADDRESS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + main_address, py_executable_format, \ + "Main address of code for the executable format.\n" \ + "\n" \ + "This property provide a pychrysalide.arch.vmpa instance or" \ + " *None* in case of failure." \ +) + + format = G_EXECUTABLE_FORMAT(pygobject_get(self)); + + status = g_executable_format_get_main_address(format, &addr); + + if (status) + result = build_from_internal_vmpa(&addr); + + else + { + PyErr_SetString(PyExc_AttributeError, _("unable to define a value for the main address")); + result = NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique le type d'architecture visée par le format. * +* * +* Retour : Identifiant de l'architecture ciblée par le format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_executable_format_get_portions(PyObject *self, void *closure) +{ + PyObject *result; /* Trouvailles à retourner */ + GExecutableFormat *format; /* Format exécutable manipulé */ + GBinaryPortion *portions; /* Portion principale du format*/ + +#define EXECUTABLE_FORMAT_PORTIONS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + portions, py_executable_format, \ + "Root portion of the executable format, provided as a" \ + " pychrysalide.glibext.BinaryPortion instance." \ +) + + format = G_EXECUTABLE_FORMAT(pygobject_get(self)); + + portions = g_executable_format_get_portions(format); + + result = pygobject_new(G_OBJECT(portions)); + unref_object(portions); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -396,28 +716,18 @@ PyTypeObject *get_python_executable_format_type(void) { static PyMethodDef py_executable_format_methods[] = { EXECUTABLE_FORMAT_GET_TARGET_MACHINE_WRAPPER, -#if 0 - { - "register_user_portion", py_executable_format_register_user_portion, - METH_VARARGS, - "register_user_portion($self, portion, /)\n--\n\nRemember a given user-defined binary portion as part of the executable format content." - }, - { - "translate_offset_into_vmpa", py_executable_format_translate_offset_into_vmpa, - METH_VARARGS, - "translate_offset_into_vmpa($self, off, /)\n--\n\nTranslate a physical offset to a full location." - }, - { - "translate_address_into_vmpa", py_executable_format_translate_address_into_vmpa, - METH_VARARGS, - "translate_address_into_vmpa($self, addr, /)\n--\n\nTranslate a physical offset to a full location." - }, -#endif + EXECUTABLE_FORMAT_GET_MAIN_ADDRESS_WRAPPER, + EXECUTABLE_FORMAT_REFINE_PORTIONS_WRAPPER, + EXECUTABLE_FORMAT_INCLUDE_PORTION_METHOD, + EXECUTABLE_FORMAT_TRANSLATE_OFFSET_INTO_VMPA_METHOD, + EXECUTABLE_FORMAT_TRANSLATE_ADDRESS_INTO_VMPA_METHOD, { NULL } }; static PyGetSetDef py_executable_format_getseters[] = { EXECUTABLE_FORMAT_TARGET_MACHINE_ATTRIB, + EXECUTABLE_FORMAT_MAIN_ADDRESS_ATTRIB, + EXECUTABLE_FORMAT_PORTIONS_ATTRIB, { NULL } }; diff --git a/plugins/pychrysalide/format/flat.c b/plugins/pychrysalide/format/flat.c index a115c57..81f0dba 100644 --- a/plugins/pychrysalide/format/flat.c +++ b/plugins/pychrysalide/format/flat.c @@ -41,7 +41,6 @@ CREATE_DYN_CONSTRUCTOR(flat_format, G_TYPE_FLAT_FORMAT); - /* Initialise une instance sur la base du dérivé de GObject. */ static int py_flat_format_init(PyObject *, PyObject *, PyObject *); @@ -77,9 +76,10 @@ static int py_flat_format_init(PyObject *self, PyObject *args, PyObject *kwds) "\n" \ " FlatFormat(content, machine, endian)" \ "\n" \ - "Where content is a pychrysalide.analysis.BinContent object, machine" \ - " defines the target architecture as a string value and endian provides"\ - " the right endianness of the data, as pychrysalide.SourceEndian value." + "Where *content* is a pychrysalide.analysis.BinContent object," \ + " *machine* defines the target architecture as a string value and" \ + " *endian* provides the right endianness of the data, as a" \ + " pychrysalide.SourceEndian value." /* Récupération des paramètres */ diff --git a/plugins/pychrysalide/format/known.c b/plugins/pychrysalide/format/known.c index e38c975..5df2a8f 100644 --- a/plugins/pychrysalide/format/known.c +++ b/plugins/pychrysalide/format/known.c @@ -55,13 +55,8 @@ static char *py_known_format_get_key_wrapper(const GKnownFormat *); /* Fournit une description humaine du format. */ static char *py_known_format_get_description_wrapper(const GKnownFormat *); -#if 0 /* Assure l'interprétation d'un format en différé. */ -static bool py_known_format_analyze_wrapper(GKnownFormat *, wgroup_id_t, GtkStatusStack *); - -/* Réalise un traitement post-désassemblage. */ -static void py_known_format_complete_analysis_wrapper(GKnownFormat *, wgroup_id_t, GtkStatusStack *); -#endif +static bool py_known_format_analyze_wrapper(GKnownFormat *); @@ -69,10 +64,7 @@ static void py_known_format_complete_analysis_wrapper(GKnownFormat *, wgroup_id_ /* Assure l'interprétation d'un format en différé. */ -//static PyObject *py_known_format_analyze(PyObject *, PyObject *); - -/* Réalise un traitement post-désassemblage. */ -//static PyObject *py_known_format_complete_analysis(PyObject *, PyObject *); +static PyObject *py_known_format_analyze(PyObject *, PyObject *); /* Indique la désignation interne du format. */ static PyObject *py_known_format_get_key(PyObject *, void *); @@ -108,8 +100,7 @@ static void py_known_format_init_gclass(GKnownFormatClass *class, gpointer unuse class->get_key = py_known_format_get_key_wrapper; class->get_desc = py_known_format_get_description_wrapper; - //class->analyze = py_known_format_analyze_wrapper; - //class->complete = py_known_format_complete_analysis_wrapper; + class->analyze = py_known_format_analyze_wrapper; } @@ -143,9 +134,6 @@ static int py_known_format_init(PyObject *self, PyObject *args, PyObject *kwds) "* pychrysalide.format.KnownFormat._get_description();\n" \ "* pychrysalide.format.KnownFormat._analyze().\n" \ "\n" \ - "The following method may also be defined for new classes too:\n" \ - "* pychrysalide.format.KnownFormat._complete_analysis().\n" \ - "\n" \ "Calls to the *__init__* constructor of this abstract object expect"\ " only one argument: a binary content, provided as a" \ " pychrysalide.analysis.BinContent instance." @@ -298,12 +286,10 @@ static char *py_known_format_get_description_wrapper(const GKnownFormat *format) } -#if 0 + /****************************************************************************** * * * Paramètres : format = format chargé dont l'analyse est lancée. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * * * * Description : Assure l'interprétation d'un format en différé. * * * @@ -313,12 +299,11 @@ static char *py_known_format_get_description_wrapper(const GKnownFormat *format) * * ******************************************************************************/ -static bool py_known_format_analyze_wrapper(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status) +static bool py_known_format_analyze_wrapper(GKnownFormat *format) { bool result; /* Bilan à retourner */ PyGILState_STATE gstate; /* Sauvegarde d'environnement */ PyObject *pyobj; /* Objet Python concerné */ - PyObject *args; /* Arguments pour l'appel */ PyObject *pyret; /* Bilan d'exécution */ #define KNOWN_FORMAT_ANALYZE_WRAPPER PYTHON_WRAPPER_DEF \ @@ -328,12 +313,8 @@ static bool py_known_format_analyze_wrapper(GKnownFormat *format, wgroup_id_t gi "Abstract method used to start the analysis of the known" \ " format and return its status.\n" \ "\n" \ - "The identifier refers to the working queue used to process" \ - " the analysis. A reference to the main status bar may also be" \ - " provided, as a pychrysalide.gtkext.StatusStack instance if" \ - " running in graphical mode or None otherwise.\n" \ - "\n" \ - "The expected result of the call is a boolean." \ + "The expected result of the call is a boolean value: *True* in" \ + " case of success, *False* in case of failure." \ ) result = false; @@ -344,16 +325,10 @@ static bool py_known_format_analyze_wrapper(GKnownFormat *format, wgroup_id_t gi if (has_python_method(pyobj, "_analyze")) { - args = PyTuple_New(2); - - PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(gid)); - PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(status))); - - pyret = run_python_method(pyobj, "_analyze", args); + pyret = run_python_method(pyobj, "_analyze", NULL); result = (pyret == Py_True); - Py_DECREF(args); Py_XDECREF(pyret); } @@ -367,71 +342,12 @@ static bool py_known_format_analyze_wrapper(GKnownFormat *format, wgroup_id_t gi } -/****************************************************************************** -* * -* Paramètres : format = format chargé dont l'analyse est lancée. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * -* * -* Description : Réalise un traitement post-désassemblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_known_format_complete_analysis_wrapper(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status) -{ - PyGILState_STATE gstate; /* Sauvegarde d'environnement */ - PyObject *pyobj; /* Objet Python concerné */ - PyObject *args; /* Arguments pour l'appel */ - PyObject *pyret; /* Bilan d'exécution */ - -#define KNOWN_FORMAT_COMPLETE_ANALYSIS_WRAPPER PYTHON_VOID_WRAPPER_DEF \ -( \ - _complete_analysis, "$self, gid, status, /", \ - METH_VARARGS, \ - "Abstract method used to complete an analysis of a known format.\n" \ - "\n" \ - "The identifier refers to the working queue used to process the" \ - " analysis. A reference to the main status bar may also be" \ - " provided, as a pychrysalide.gtkext.StatusStack instance if" \ - " running in graphical mode or None otherwise.\n" \ -) - - gstate = PyGILState_Ensure(); - - pyobj = pygobject_new(G_OBJECT(format)); - - if (has_python_method(pyobj, "_complete_analysis")) - { - args = PyTuple_New(2); - - PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(gid)); - PyTuple_SetItem(args, 1, pygobject_new(G_OBJECT(status))); - - pyret = run_python_method(pyobj, "_complete_analysis", args); - - Py_DECREF(args); - Py_XDECREF(pyret); - - } - - Py_DECREF(pyobj); - - PyGILState_Release(gstate); - -} -#endif - /* ---------------------------------------------------------------------------------- */ /* DEFINITION DU FORMAT CONNU */ /* ---------------------------------------------------------------------------------- */ -#if 0 /****************************************************************************** * * * Paramètres : self = objet représentant un format connu. * @@ -448,33 +364,24 @@ static void py_known_format_complete_analysis_wrapper(GKnownFormat *format, wgro static PyObject *py_known_format_analyze(PyObject *self, PyObject *args) { PyObject *result; /* Bilan à retourner */ - int ret; /* Bilan de lecture des args. */ GKnownFormat *format; /* Format connu manipulé */ bool status; /* Bilan de l'opération */ #define KNOWN_FORMAT_ANALYZE_METHOD PYTHON_METHOD_DEF \ ( \ - analyze, "$self, gid, status, /", \ - METH_VARARGS, py_known_format, \ + analyze, "$self", \ + METH_NOARGS, py_known_format, \ "Start the analysis of the known format and return its status." \ "\n" \ "Once this analysis is done, a few early symbols and the" \ " mapped sections are expected to be defined, if any.\n" \ "\n" \ - "The identifier refers to the working queue used to process" \ - " the analysis. A reference to the main status bar may also be" \ - " provided, as a pychrysalide.gtkext.StatusStack instance if" \ - " running in graphical mode or None otherwise.\n" \ - "\n" \ "The return value is a boolean status of the operation." \ ) - ret = PyArg_ParseTuple(args, "");//|KO!", &gid, &status); - if (!ret) return NULL; - format = G_KNOWN_FORMAT(pygobject_get(self)); - status = g_known_format_analyze(format, 0, NULL); + status = g_known_format_analyze(format); result = status ? Py_True : Py_False; Py_INCREF(result); @@ -486,58 +393,6 @@ static PyObject *py_known_format_analyze(PyObject *self, PyObject *args) /****************************************************************************** * * -* Paramètres : self = objet représentant un format connu. * -* args = arguments fournis pour l'opération. * -* * -* Description : Réalise un traitement post-désassemblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_known_format_complete_analysis(PyObject *self, PyObject *args) -{ - PyObject *result; /* Bilan à retourner */ - int ret; /* Bilan de lecture des args. */ - GKnownFormat *format; /* Format connu manipulé */ - -#define KNOWN_FORMAT_COMPLETE_ANALYSIS_METHOD PYTHON_METHOD_DEF \ -( \ - complete_analysis, "$self, gid, status, /", \ - METH_VARARGS, py_known_format, \ - "Complete an analysis of a known format.\n" \ - "\n" \ - "This process is usually done once the disassembling process" \ - " is completed.\n" \ - "\n" \ - "The identifier refers to the working queue used to process" \ - " the analysis. A reference to the main status bar may also be" \ - " provided, as a pychrysalide.gtkext.StatusStack instance if" \ - " running in graphical mode or None otherwise.\n" \ - "\n" \ - "The return value is a boolean status of the operation." \ -) - - ret = PyArg_ParseTuple(args, "");//|KO!", &gid, &status); - if (!ret) return NULL; - - format = G_KNOWN_FORMAT(pygobject_get(self)); - - g_known_format_complete_analysis(format, 0, NULL); - - result = Py_None; - Py_INCREF(result); - - return result; - -} -#endif - - -/****************************************************************************** -* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -718,10 +573,8 @@ PyTypeObject *get_python_known_format_type(void) static PyMethodDef py_known_format_methods[] = { KNOWN_FORMAT_GET_KEY_WRAPPER, KNOWN_FORMAT_GET_DESCRIPTION_WRAPPER, - //KNOWN_FORMAT_ANALYZE_WRAPPER, - //KNOWN_FORMAT_COMPLETE_ANALYSIS_WRAPPER, - //KNOWN_FORMAT_ANALYZE_METHOD, - //KNOWN_FORMAT_COMPLETE_ANALYSIS_METHOD, + KNOWN_FORMAT_ANALYZE_WRAPPER, + KNOWN_FORMAT_ANALYZE_METHOD, { NULL } }; diff --git a/plugins/pychrysalide/format/program.c b/plugins/pychrysalide/format/program.c index d96c2db..28c1540 100644 --- a/plugins/pychrysalide/format/program.c +++ b/plugins/pychrysalide/format/program.c @@ -35,6 +35,8 @@ #include "../access.h" #include "../constants.h" #include "../helpers.h" +#include "../analysis/content.h" +#include "../arch/vmpa.h" /* @@ -44,7 +46,6 @@ #include "symiter.h" #include "../analysis/constants.h" #include "../analysis/content.h" -#include "../arch/vmpa.h" #include "../arch/constants.h" */ @@ -64,6 +65,9 @@ static int py_program_format_init(PyObject *, PyObject *, PyObject *); /* Indique le boutisme employé par le format binaire analysé. */ static SourceEndian py_program_format_get_endianness_wrapper(const GProgramFormat *); +/* Fournit l'emplacement d'une section donnée. */ +static bool py_program_format_get_section_range_by_name_wrapper(const GProgramFormat *, const char *, mrange_t *); + /* ---------------------------- FORMAT BINAIRE GENERIQUE ---------------------------- */ @@ -78,7 +82,14 @@ static PyObject *py_program_format_unset_flag(PyObject *, PyObject *); /* Détermine si un format possède un fanion particulier. */ static PyObject *py_program_format_has_flag(PyObject *, PyObject *); +#endif + + +/* Fournit l'emplacement d'une section donnée. */ +static PyObject *py_program_format_get_section_range_by_name(PyObject *, PyObject *); + +#if 0 /* Enregistre une adresse comme début d'une zone de code. */ static PyObject *py_program_format_register_code_point(PyObject *, PyObject *); @@ -143,6 +154,7 @@ static PyObject *py_program_format_get_errors(PyObject *, void *); static void py_program_format_init_gclass(GProgramFormatClass *class, gpointer unused) { class->get_endian = py_program_format_get_endianness_wrapper; + class->get_range_by_name = py_program_format_get_section_range_by_name_wrapper; } @@ -163,25 +175,42 @@ static void py_program_format_init_gclass(GProgramFormatClass *class, gpointer u static int py_program_format_init(PyObject *self, PyObject *args, PyObject *kwds) { + GBinContent *content; /* Contenu à intégrer au format*/ int ret; /* Bilan de lecture des args. */ - -#define PROGRAM_FORMAT_DOC \ - "The ProgramFormat class is the major part of binary format" \ - " support. It is the core class used by loading most of the binary" \ - " files.\n" \ - "\n" \ - "\n" \ - "The following method has to be defined for new classes:\n" \ - "* pychrysalide.format.ProgramFormat._get_endianness().\n" \ - "\n" \ - "Calls to the *__init__* constructor of this abstract object expect"\ - " no particular argument." + GProgramFormat *format; /* Format à manipuler */ + +#define PROGRAM_FORMAT_DOC \ + "The ProgramFormat class is the major part of binary format" \ + " support. It is the core class used by loading most of the binary" \ + " files.\n" \ + "\n" \ + "The following method has to be defined for new classes:\n" \ + "* pychrysalide.format.ProgramFormat._get_endianness().\n" \ + "\n" \ + "Other optional method may be defined for new classes:\n" \ + "* pychrysalide.format.ProgramFormat._get_section_range_by_name().\n" \ + "\n" \ + "Calls to the *__init__* constructor of this abstract object expect" \ + " only one argument: a binary content, provided as a" \ + " pychrysalide.analysis.BinContent instance." + + /* Récupération des paramètres */ + + ret = PyArg_ParseTuple(args, "O&", convert_to_binary_content, &content); + if (!ret) return -1; /* Initialisation d'un objet GLib */ ret = forward_pygobjet_init(self); if (ret == -1) return -1; + /* Eléments de base */ + + format = G_PROGRAM_FORMAT(pygobject_get(self)); + + if (!g_program_format_create(format, content)) + return -1; + return 0; } @@ -252,11 +281,84 @@ static SourceEndian py_program_format_get_endianness_wrapper(const GProgramForma } +/****************************************************************************** +* * +* Paramètres : format = description du programme à consulter. * +* name = nom de la section recherchée. * +* range = emplacement en mémoire à renseigner. [OUT] * +* * +* Description : Fournit l'emplacement d'une section donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_program_format_get_section_range_by_name_wrapper(const GProgramFormat *format, const char *name, mrange_t *range) +{ + bool result; /* Bilan à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyret; /* Valeur retournée */ + int ret; /* Bilan d'une conversion */ + +#define PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _get_section_range_by_name_wrapper, "$self, name", \ + METH_VARARGS, \ + "Abstract method used to compute the area of a section identified by" \ + " its name.\n" \ + "\n" \ + "The expected returned value is a pychrysalide.arch.mrange instance or" \ + " *None* in case of failure." \ +) + + result = false; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(format)); + + if (has_python_method(pyobj, "_get_section_range_by_name")) + { + pyret = run_python_method(pyobj, "_get_section_range_by_name", NULL); + + if (pyret != NULL) + { + if (pyret == Py_None) + result = false; + + else + { + ret = convert_any_to_mrange(pyret, range); + + result = (ret == 1); + + if (!result) + PyErr_Clear(); + + } + + Py_DECREF(pyret); + + } + + } + + Py_DECREF(pyobj); + + PyGILState_Release(gstate); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* FORMAT BINAIRE GENERIQUE */ /* ---------------------------------------------------------------------------------- */ - #if 0 /****************************************************************************** * * @@ -402,10 +504,66 @@ static PyObject *py_program_format_has_flag(PyObject *self, PyObject *args) return result; } +#endif /****************************************************************************** * * +* Paramètres : self = serveur à manipuler. * +* args = arguments d'appel non utilisés ici. * +* * +* Description : Fournit l'emplacement d'une section donnée. * +* * +* Retour : Emplacement ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_program_format_get_section_range_by_name(PyObject *self, PyObject *args) +{ + PyObject *result; /* Emplacement à retourner */ + const char *name; /* Nom de section ciblée */ + int ret; /* Bilan de lecture des args. */ + GProgramFormat *format; /* Elément à manipuler */ + mrange_t range; /* Emplacement obtenu ? */ + bool status; /* Bilan de l'opération */ + +#define PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_METHOD PYTHON_METHOD_DEF \ +( \ + get_section_range_by_name, "$self, name, /", \ + METH_VARARGS, py_program_format, \ + "Compute the area of a section identified by its name.\n" \ + "\n" \ + "The *name* argument is a string value.\n" \ + "\n" \ + "The returned value is a pychrysalide.arch.mrange instance or" \ + " *None* in case of failure." \ +) + + ret = PyArg_ParseTuple(args, "s", &name); + if (!ret) return NULL; + + format = G_PROGRAM_FORMAT(pygobject_get(self)); + + status = g_program_format_get_section_range_by_name(format, name, &range); + + if (status) + result = build_from_internal_mrange(&range); + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + +#if 0 +/****************************************************************************** +* * * Paramètres : self = classe représentant un format. * * args = arguments fournis à l'appel. * * * @@ -1036,6 +1194,8 @@ PyTypeObject *get_python_program_format_type(void) { static PyMethodDef py_program_format_methods[] = { PROGRAM_FORMAT_GET_ENDIANNESS_WRAPPER, + PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_WRAPPER, + PROGRAM_FORMAT_GET_SECTION_RANGE_BY_NAME_METHOD, /* PROGRAM_FORMAT_SET_FLAG_METHOD, PROGRAM_FORMAT_UNSET_FLAG_METHOD, diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am index e9c3756..8b021bb 100644 --- a/plugins/pychrysalide/glibext/Makefile.am +++ b/plugins/pychrysalide/glibext/Makefile.am @@ -2,9 +2,7 @@ noinst_LTLIBRARIES = libpychrysaglibext.la # libpychrysaglibext_la_SOURCES = \ -# constants.h constants.c \ # binarycursor.h binarycursor.c \ -# binportion.h binportion.c \ # buffercache.h buffercache.c \ # bufferline.h bufferline.c \ # comparison.h comparison.c \ @@ -24,7 +22,9 @@ noinst_LTLIBRARIES = libpychrysaglibext.la # endif libpychrysaglibext_la_SOURCES = \ + constants.h constants.c \ module.h module.c \ + portion.h portion.c \ work.h work.c \ workqueue.h workqueue.c diff --git a/plugins/pychrysalide/glibext/constants.c b/plugins/pychrysalide/glibext/constants.c index 169ffa2..90ce8cd 100644 --- a/plugins/pychrysalide/glibext/constants.c +++ b/plugins/pychrysalide/glibext/constants.c @@ -25,16 +25,18 @@ #include "constants.h" +#include + +/* #include #include #include #include #include -#include #ifdef INCLUDE_GTK_SUPPORT # include #endif - +*/ #include "../helpers.h" @@ -58,6 +60,7 @@ bool define_binary_portion_constants(PyTypeObject *type) PyObject *strdict; /* Groupe de chaînes constantes*/ PyObject *values; /* Groupe de valeurs à établir */ + /* result = create_string_constants_group_to_type(type, "BinaryPortionCode", "Selector names for the CSS rendering.", &strdict); @@ -69,6 +72,7 @@ bool define_binary_portion_constants(PyTypeObject *type) if (!result) goto exit; + */ values = PyDict_New(); @@ -150,6 +154,7 @@ int convert_to_portion_access_rights(PyObject *arg, void *dst) } +#if 0 /****************************************************************************** * * * Paramètres : type = type dont le dictionnaire est à compléter. * @@ -617,3 +622,4 @@ int convert_to_scroll_position_tweak(PyObject *arg, void *dst) #endif +#endif diff --git a/plugins/pychrysalide/glibext/constants.h b/plugins/pychrysalide/glibext/constants.h index 4a4f6da..a950125 100644 --- a/plugins/pychrysalide/glibext/constants.h +++ b/plugins/pychrysalide/glibext/constants.h @@ -37,6 +37,8 @@ bool define_binary_portion_constants(PyTypeObject *); /* Tente de convertir en constante PortionAccessRights. */ int convert_to_portion_access_rights(PyObject *, void *); +#if 0 + /* Définit les constantes relatives aux lignes de tampon. */ bool define_buffer_line_constants(PyTypeObject *); @@ -68,6 +70,8 @@ int convert_to_scroll_position_tweak(PyObject *, void *); #endif +#endif + #endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_H */ diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c index 23e7a7d..e62d587 100644 --- a/plugins/pychrysalide/glibext/module.c +++ b/plugins/pychrysalide/glibext/module.c @@ -30,7 +30,6 @@ /* #include "binarycursor.h" -#include "binportion.h" #include "buffercache.h" #include "bufferline.h" #include "bufferview.h" @@ -42,6 +41,7 @@ #include "named.h" #include "singleton.h" */ +#include "portion.h" #include "work.h" #include "workqueue.h" #include "../helpers.h" @@ -110,6 +110,7 @@ bool populate_glibext_module(void) result = true; + if (result) result = ensure_python_binary_portion_is_registered(); if (result) result = ensure_python_generic_work_is_registered(); if (result) result = ensure_python_work_queue_is_registered(); @@ -117,7 +118,6 @@ bool populate_glibext_module(void) if (result) result = ensure_python_singleton_candidate_is_registered(); if (result) result = ensure_python_binary_cursor_is_registered(); - if (result) result = ensure_python_binary_portion_is_registered(); if (result) result = ensure_python_buffer_cache_is_registered(); if (result) result = ensure_python_buffer_line_is_registered(); #ifdef INCLUDE_GTK_SUPPORT diff --git a/plugins/pychrysalide/glibext/portion.c b/plugins/pychrysalide/glibext/portion.c index 70eb314..d95308c 100644 --- a/plugins/pychrysalide/glibext/portion.c +++ b/plugins/pychrysalide/glibext/portion.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * binportion.c - équivalent Python du fichier "glibext/gbinportion.c" + * portion.c - équivalent Python du fichier "glibext/portion.c" * * Copyright (C) 2019-2020 Cyrille Bagard * @@ -22,15 +22,14 @@ */ -#include "binportion.h" +#include "portion.h" #include #include -#include -#include +#include #include "constants.h" @@ -40,13 +39,13 @@ -/* Accompagne la création d'une instance dérivée en Python. */ -static PyObject *py_bin_portion_new(PyTypeObject *, PyObject *, PyObject *); +CREATE_DYN_CONSTRUCTOR(binary_portion, G_TYPE_BINARY_PORTION); + /* Initialise une instance sur la base du dérivé de GObject. */ -static int py_bin_portion_init(PyObject *, PyObject *, PyObject *); +static int py_binary_portion_init(PyObject *, PyObject *, PyObject *); -/* Effectue une comparaison avec un objet Python 'BinPortion'. */ +/* Effectue une comparaison avec un objet Python BinaryPortion. */ static PyObject *py_binary_portion_richcompare(PyObject *, PyObject *, int); /* Assure qu'une portion ne dépasse pas une position donnée. */ @@ -77,66 +76,6 @@ static int py_binary_portion_set_rights(PyObject *, PyObject *, void *); /****************************************************************************** * * -* Paramètres : type = type du nouvel objet à mettre en place. * -* args = éventuelle liste d'arguments. * -* kwds = éventuel dictionnaire de valeurs mises à disposition. * -* * -* Description : Accompagne la création d'une instance dérivée en Python. * -* * -* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_bin_portion_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Objet à retourner */ - PyTypeObject *base; /* Type de base à dériver */ - bool first_time; /* Evite les multiples passages*/ - GType gtype; /* Nouveau type de processeur */ - bool status; /* Bilan d'un enregistrement */ - - /* Validations diverses */ - - base = get_python_binary_portion_type(); - - if (type == base) - goto simple_way; - - /* Mise en place d'un type dédié */ - - first_time = (g_type_from_name(type->tp_name) == 0); - - gtype = build_dynamic_type(G_TYPE_BIN_PORTION, type->tp_name, NULL, NULL, NULL); - - if (first_time) - { - status = register_class_for_dynamic_pygobject(gtype, type); - - if (!status) - { - result = NULL; - goto exit; - } - - } - - /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ - - simple_way: - - result = PyType_GenericNew(type, args, kwds); - - exit: - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * * kwds = arguments de type key=val fournis. * @@ -149,33 +88,30 @@ static PyObject *py_bin_portion_new(PyTypeObject *type, PyObject *args, PyObject * * ******************************************************************************/ -static int py_bin_portion_init(PyObject *self, PyObject *args, PyObject *kwds) +static int py_binary_portion_init(PyObject *self, PyObject *args, PyObject *kwds) { - const char *code; /* Identifiant de couleur */ vmpa2t *addr; /* Emplacement de portion */ unsigned long long size; /* Taille de la portion */ int ret; /* Bilan de lecture des args. */ - GBinPortion *portion; /* Portion à manipuler */ + GBinaryPortion *portion; /* Portion à manipuler */ - static char *kwlist[] = { "code", "addr", "size", NULL }; + static char *kwlist[] = { "addr", "size", NULL }; #define BINARY_PORTION_DOC \ - "The BinPortion object handles parts of binaries usually formally" \ + "The BinaryPortion object handles parts of binaries usually formally" \ " identified in binary formats, like program segments or sections for ELF" \ " files for example.\n" \ "\n" \ "Instances can be created using the following constructor:\n" \ "\n" \ - " BinPortion(code, addr, size)" \ + " BinaryPortion(addr, size)" \ "\n" \ - "Where code is the CSS class style for the rendering color to use, addr is" \ - " the starting point of the portion in memory, as a pychrysalide.arch.vmpa" \ - " value, and size is the size of the portion." \ + "Where *addr* is the starting point of the portion in memory, as a" \ + " pychrysalide.arch.vmpa value, and *size* is the size of the portion." /* Récupération des paramètres */ - ret = PyArg_ParseTupleAndKeywords(args, kwds, "sO&K", kwlist, - &code, convert_any_to_vmpa, &addr, &size); + ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&K", kwlist, convert_any_to_vmpa, &addr, &size); if (!ret) return -1; /* Initialisation d'un objet GLib */ @@ -189,11 +125,13 @@ static int py_bin_portion_init(PyObject *self, PyObject *args, PyObject *kwds) /* Eléments de base */ - portion = G_BIN_PORTION(pygobject_get(self)); - - portion->code = strdup(code); + portion = G_BINARY_PORTION(pygobject_get(self)); - init_mrange(&portion->range, addr, size); + if (!g_binary_portion_create(portion, addr, size)) + { + clean_vmpa_arg(addr); + return -1; + } clean_vmpa_arg(addr); @@ -208,7 +146,7 @@ static int py_bin_portion_init(PyObject *self, PyObject *args, PyObject *kwds) * b = second object Python à consulter. * * op = type de comparaison menée. * * * -* Description : Effectue une comparaison avec un objet Python 'BinPortion'. * +* Description : Effectue une comparaison avec un objet Python BinaryPortion. * * * * Retour : Bilan de l'opération. * * * @@ -220,8 +158,8 @@ static PyObject *py_binary_portion_richcompare(PyObject *a, PyObject *b, int op) { PyObject *result; /* Bilan à retourner */ int ret; /* Bilan de lecture des args. */ - const GBinPortion *portion_a; /* Premier élément à traiter */ - const GBinPortion *portion_b; /* Second élément à traiter */ + const GBinaryPortion *portion_a; /* Premier élément à traiter */ + const GBinaryPortion *portion_b; /* Second élément à traiter */ int status; /* Résultat d'une comparaison */ ret = PyObject_IsInstance(b, (PyObject *)get_python_binary_portion_type()); @@ -231,8 +169,8 @@ static PyObject *py_binary_portion_richcompare(PyObject *a, PyObject *b, int op) goto cmp_done; } - portion_a = G_BIN_PORTION(pygobject_get(a)); - portion_b = G_BIN_PORTION(pygobject_get(b)); + portion_a = G_BINARY_PORTION(pygobject_get(a)); + portion_b = G_BINARY_PORTION(pygobject_get(b)); status = g_binary_portion_compare(&portion_a, &portion_b); @@ -265,16 +203,16 @@ static PyObject *py_binary_portion_limit_range(PyObject *self, PyObject *args) PyObject *result; /* Trouvailles à retourner */ unsigned long long max; /* Taille maximale à accorder */ int ret; /* Bilan de lecture des args. */ - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ bool status; /* Bilan de la modification */ -#define BINARY_SYMBOL_LIMIT_RANGE_METHOD PYTHON_METHOD_DEF \ +#define BINARY_PORTION_LIMIT_RANGE_METHOD PYTHON_METHOD_DEF \ ( \ limit_range, "$self, max, /", \ METH_VARARGS, py_binary_portion, \ "Ensure the portion range does not cross a boundary size.\n" \ "\n" \ - "An integer value is expected as the maximum size of the" \ + "An *max* integer value is expected as the maximum size of the" \ " portion.\n" \ "\n" \ "A boolean value indicating the success of the operation is" \ @@ -284,7 +222,7 @@ static PyObject *py_binary_portion_limit_range(PyObject *self, PyObject *args) ret = PyArg_ParseTuple(args, "K", &max); if (!ret) return NULL; - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); status = g_binary_portion_limit_range(portion, max); @@ -311,24 +249,27 @@ static PyObject *py_binary_portion_limit_range(PyObject *self, PyObject *args) static PyObject *py_binary_portion_include(PyObject *self, PyObject *args) { - GBinPortion *sub; /* Sous-portion à inclure */ + GBinaryPortion *sub; /* Sous-portion à inclure */ int ret; /* Bilan de lecture des args. */ - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ -#define BINARY_SYMBOL_INCLUDE_METHOD PYTHON_METHOD_DEF \ -( \ - include, "$self, sub, /", \ - METH_VARARGS, py_binary_portion, \ - "Include another binary portion as a child item.\n" \ - "\n" \ - "The sub portion has to be a pychrysalide.glibext.BinPortion" \ - " instance." \ +#define BINARY_PORTION_INCLUDE_METHOD PYTHON_METHOD_DEF \ +( \ + include, "$self, sub, /", \ + METH_VARARGS, py_binary_portion, \ + "Include another binary portion as a child item.\n" \ + "\n" \ + "The provided *sub* portion has to be a" \ + " pychrysalide.glibext.BinaryPortion instance." \ + "\n" \ + "The returned value is a boolean value providing the" \ + " status of the operation." \ ) ret = PyArg_ParseTuple(args, "O&", convert_to_binary_portion, &sub); if (!ret) return NULL; - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); g_object_ref(G_OBJECT(sub)); g_binary_portion_include(portion, sub); @@ -354,7 +295,7 @@ static PyObject *py_binary_portion_include(PyObject *self, PyObject *args) static PyObject *py_binary_portion_get_desc(PyObject *self, void *closure) { PyObject *result; /* Résultat à retourner */ - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ const char *desc; /* Description récupérée */ #define BINARY_PORTION_DESC_ATTRIB PYTHON_GETSET_DEF_FULL \ @@ -364,7 +305,7 @@ static PyObject *py_binary_portion_get_desc(PyObject *self, void *closure) " simple string." \ ) - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); desc = g_binary_portion_get_desc(portion); @@ -391,7 +332,7 @@ static PyObject *py_binary_portion_get_desc(PyObject *self, void *closure) static int py_binary_portion_set_desc(PyObject *self, PyObject *value, void *closure) { - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ const char *desc; /* Description à définir */ if (!PyUnicode_Check(value)) @@ -400,7 +341,7 @@ static int py_binary_portion_set_desc(PyObject *self, PyObject *value, void *clo return -1; } - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); desc = PyUnicode_DATA(value); @@ -427,7 +368,7 @@ static int py_binary_portion_set_desc(PyObject *self, PyObject *value, void *clo static PyObject *py_binary_portion_get_range(PyObject *self, void *closure) { PyObject *result; /* Résultat à retourner */ - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ const mrange_t *range; /* Espace de couverture */ #define BINARY_PORTION_RANGE_ATTRIB PYTHON_GET_DEF_FULL \ @@ -438,7 +379,7 @@ static PyObject *py_binary_portion_get_range(PyObject *self, void *closure) "This property is a pychrysalide.arch.mrange instance." \ ) - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); range = g_binary_portion_get_range(portion); @@ -465,7 +406,7 @@ static PyObject *py_binary_portion_get_range(PyObject *self, void *closure) static PyObject *py_binary_portion_get_continuation(PyObject *self, void *closure) { PyObject *result; /* Résultat à retourner */ - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ bool status; /* Bilan d'une consultation */ #define BINARY_PORTION_CONTINUATION_ATTRIB PYTHON_GETSET_DEF_FULL \ @@ -478,7 +419,7 @@ static PyObject *py_binary_portion_get_continuation(PyObject *self, void *closur " several parts when included in the portion tree." \ ) - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); status = g_binary_portion_is_continuation(portion); @@ -506,7 +447,7 @@ static PyObject *py_binary_portion_get_continuation(PyObject *self, void *closur static int py_binary_portion_set_continuation(PyObject *self, PyObject *value, void *closure) { - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ bool status; /* Valeur à manipuler */ if (!PyBool_Check(value)) @@ -515,7 +456,7 @@ static int py_binary_portion_set_continuation(PyObject *self, PyObject *value, v return -1; } - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); status = (value == Py_True); @@ -542,17 +483,17 @@ static int py_binary_portion_set_continuation(PyObject *self, PyObject *value, v static PyObject *py_binary_portion_get_rights(PyObject *self, void *closure) { PyObject *result; /* Résultat à retourner */ - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ PortionAccessRights rights; /* Bilan d'une consultation */ #define BINARY_PORTION_RIGHTS_ATTRIB PYTHON_GETSET_DEF_FULL \ ( \ rights, py_binary_portion, \ "Access rights declared for the binary portion, as a" \ - " pychrysalide.glibext.BinPortion.PortionAccessRights value." \ + " pychrysalide.glibext.BinaryPortion.PortionAccessRights value."\ ) - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); rights = g_binary_portion_get_rights(portion); @@ -579,13 +520,13 @@ static PyObject *py_binary_portion_get_rights(PyObject *self, void *closure) static int py_binary_portion_set_rights(PyObject *self, PyObject *value, void *closure) { - GBinPortion *portion; /* Version GLib du type */ + GBinaryPortion *portion; /* Version GLib du type */ PortionAccessRights rights; /* Valeur à manipuler */ if (convert_to_portion_access_rights(value, &rights) != 1) return -1; - portion = G_BIN_PORTION(pygobject_get(self)); + portion = G_BINARY_PORTION(pygobject_get(self)); g_binary_portion_set_rights(portion, rights); @@ -609,8 +550,8 @@ static int py_binary_portion_set_rights(PyObject *self, PyObject *value, void *c PyTypeObject *get_python_binary_portion_type(void) { static PyMethodDef py_binary_portion_methods[] = { - BINARY_SYMBOL_LIMIT_RANGE_METHOD, - BINARY_SYMBOL_INCLUDE_METHOD, + BINARY_PORTION_LIMIT_RANGE_METHOD, + BINARY_PORTION_INCLUDE_METHOD, { NULL } }; @@ -626,7 +567,7 @@ PyTypeObject *get_python_binary_portion_type(void) PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "pychrysalide.glibext.BinPortion", + .tp_name = "pychrysalide.glibext.BinaryPortion", .tp_basicsize = sizeof(PyGObject), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, @@ -638,8 +579,8 @@ PyTypeObject *get_python_binary_portion_type(void) .tp_methods = py_binary_portion_methods, .tp_getset = py_binary_portion_getseters, - .tp_init = py_bin_portion_init, - .tp_new = py_bin_portion_new, + .tp_init = py_binary_portion_init, + .tp_new = py_binary_portion_new, }; @@ -652,7 +593,7 @@ PyTypeObject *get_python_binary_portion_type(void) * * * Paramètres : module = module dont la définition est à compléter. * * * -* Description : Prend en charge l'objet 'pychrysalide.glibext.BinPortion'. * +* Description : Prend en charge l'objet 'pychrysalide.glibext.BinaryPortion'.* * * * Retour : Bilan de l'opération. * * * @@ -662,7 +603,7 @@ PyTypeObject *get_python_binary_portion_type(void) bool ensure_python_binary_portion_is_registered(void) { - PyTypeObject *type; /* Type Python 'BinPortion' */ + PyTypeObject *type; /* Type Python 'BinaryPortion' */ PyObject *module; /* Module à recompléter */ PyObject *dict; /* Dictionnaire du module */ @@ -674,7 +615,7 @@ bool ensure_python_binary_portion_is_registered(void) dict = PyModule_GetDict(module); - if (!register_class_for_pygobject(dict, G_TYPE_BIN_PORTION, type)) + if (!register_class_for_pygobject(dict, G_TYPE_BINARY_PORTION, type)) return false; if (!define_binary_portion_constants(type)) @@ -718,7 +659,7 @@ int convert_to_binary_portion(PyObject *arg, void *dst) break; case 1: - *((GBinPortion **)dst) = G_BIN_PORTION(pygobject_get(arg)); + *((GBinaryPortion **)dst) = G_BINARY_PORTION(pygobject_get(arg)); break; default: diff --git a/plugins/pychrysalide/glibext/portion.h b/plugins/pychrysalide/glibext/portion.h index b27c8ea..a417c01 100644 --- a/plugins/pychrysalide/glibext/portion.h +++ b/plugins/pychrysalide/glibext/portion.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * binportion.h - prototypes pour l'équivalent Python du fichier "glibext/gbinportion.h" + * portion.h - prototypes pour l'équivalent Python du fichier "glibext/portion.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,8 +22,8 @@ */ -#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_BINPORTION_H -#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_BINPORTION_H +#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_PORTION_H +#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_PORTION_H #include @@ -34,7 +34,7 @@ /* Fournit un accès à une définition de type à diffuser. */ PyTypeObject *get_python_binary_portion_type(void); -/* Prend en charge l'objet 'pychrysalide.glibext.BinPortion'. */ +/* Prend en charge l'objet 'pychrysalide.glibext.BinaryPortion'. */ bool ensure_python_binary_portion_is_registered(void); /* Tente de convertir en portion de binaire. */ @@ -42,4 +42,4 @@ int convert_to_binary_portion(PyObject *, void *); -#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_BINPORTION_H */ +#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_PORTION_H */ diff --git a/src/format/executable-int.c b/src/format/executable-int.c deleted file mode 100644 index 0e94e74..0000000 --- a/src/format/executable-int.c +++ /dev/null @@ -1,155 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * executable-int.c - code utile aux formats d'exécutables - * - * Copyright (C) 2015-2018 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 Chrysalide. If not, see . - */ - - -#include "executable-int.h" - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* off = position physique à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une position physique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExeFormat *format, phys_t off, vmpa2t *pos) -{ - init_vmpa(pos, off, VMPA_NO_VIRTUAL); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse virtuelle à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_exe_format_without_virt_translate_address_into_vmpa(const GExeFormat *format, virt_t addr, vmpa2t *pos) -{ - /** - * S'il n'y a pas de notion de mémoire virtuelle, positions physiques et - * adresses virtuelles se confondent. - * - * On reste néanmoins cohérent, et on n'utilise donc pas d'adresse virtuelle. - * - * Les sauts dans le code renvoient de façon transparente vers des positions - * physiques. - */ - - init_vmpa(pos, addr, VMPA_NO_VIRTUAL); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* off = position physique à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une position physique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_exe_format_translate_offset_into_vmpa_using_portions(GExeFormat *format, phys_t off, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - GBinPortion *portions; /* Liste de découpages */ - - portions = g_exe_format_get_portions(format); - - if (portions == NULL) - result = false; - - else - { - result = g_binary_portion_translate_offset_into_vmpa(portions, off, pos); - - g_object_unref(G_OBJECT(portions)); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse virtuelle à retrouver. * -* pos = position correspondante. [OUT] * -* * -* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_exe_format_translate_address_into_vmpa_using_portions(GExeFormat *format, virt_t addr, vmpa2t *pos) -{ - bool result; /* Bilan à retourner */ - GBinPortion *portions; /* Liste de découpages */ - - portions = g_exe_format_get_portions(format); - - if (portions == NULL) - result = false; - - else - { - result = g_binary_portion_translate_address_into_vmpa(portions, addr, pos); - - g_object_unref(G_OBJECT(portions)); - - } - - return result; - -} diff --git a/src/format/executable-int.h b/src/format/executable-int.h index 73b647c..1ca1bdb 100644 --- a/src/format/executable-int.h +++ b/src/format/executable-int.h @@ -35,12 +35,11 @@ /* Indique le type d'architecture visée par le format. */ typedef char * (* get_target_machine_fc) (const GExecutableFormat *); -#if 0 /* Fournit l'adresse principale associée à un format. */ typedef bool (* get_main_addr_fc) (GExecutableFormat *, vmpa2t *); /* Etend la définition des portions au sein d'un binaire. */ -typedef void (* refine_portions_fc) (GExecutableFormat *); +typedef bool (* refine_portions_fc) (GExecutableFormat *); /* Fournit l'emplacement correspondant à une position physique. */ typedef bool (* translate_phys_fc) (GExecutableFormat *, phys_t, vmpa2t *); @@ -48,28 +47,13 @@ typedef bool (* translate_phys_fc) (GExecutableFormat *, phys_t, vmpa2t *); /* Fournit l'emplacement correspondant à une adresse virtuelle. */ typedef bool (* translate_virt_fc) (GExecutableFormat *, virt_t, vmpa2t *); -/* Fournit l'emplacement d'une section donnée. */ -typedef bool (* get_range_by_name_fc) (const GExecutableFormat *, const char *, mrange_t *); - -#endif - /* Format d'exécutable générique (instance) */ struct _GExecutableFormat { - GProgramFormat parent; /* A laisser en premier */ - -#if 0 + GProgramFormat parent; /* A laisser en premier */ - GDbgFormat **debugs; /* Informations de débogage */ - size_t debugs_count; /* Nombre de ces informations */ - - GBinPortion **user_portions; /* Couches de morceaux binaires*/ - size_t user_count; /* Nombre de ces portions */ - GBinPortion *portions; /* Couches de morceaux binaires*/ - GMutex mutex; /* Accès à l'arborescence */ - -#endif + GBinaryPortion *portions; /* Couches de morceaux binaires*/ }; @@ -80,41 +64,29 @@ struct _GExecutableFormatClass get_target_machine_fc get_machine; /* Architecture ciblée */ -#if 0 get_main_addr_fc get_main_addr; /* Obtention d'adresse première*/ refine_portions_fc refine_portions; /* Décrit les portions binaires*/ translate_phys_fc translate_phys; /* Correspondance phys -> vmpa */ translate_virt_fc translate_virt; /* Correspondance virt -> vmpa */ - get_range_by_name_fc get_range_by_name; /* Emplacement de sections */ - -#endif - }; -#if 0 - -/* Crée les portions potentiellement utiles aux traductions. */ -void g_executable_format_setup_portions(GExecutableFormat *, GtkStatusStack *); - -/* Effectue les ultimes opérations de chargement d'un binaire. */ -bool g_executable_format_complete_loading(GExecutableFormat *, wgroup_id_t, GtkStatusStack *); +/* Met en place un nouveau contenu binaire à analyser. */ +bool g_executable_format_create(GExecutableFormat *, GBinContent *); /* Fournit l'emplacement correspondant à une position physique. */ -bool g_exe_format_without_virt_translate_offset_into_vmpa(const GExecutableFormat *, phys_t, vmpa2t *); - -/* Fournit l'emplacement correspondant à une adresse virtuelle. */ -bool g_exe_format_without_virt_translate_address_into_vmpa(const GExecutableFormat *, virt_t, vmpa2t *); +bool g_executable_format_translate_offset_into_vmpa_without_virt(const GExecutableFormat *, phys_t, vmpa2t *); /* Fournit l'emplacement correspondant à une position physique. */ -bool g_exe_format_translate_offset_into_vmpa_using_portions(GExecutableFormat *, phys_t, vmpa2t *); +bool g_executable_format_translate_offset_into_vmpa_with_portions(GExecutableFormat *, phys_t, vmpa2t *); /* Fournit l'emplacement correspondant à une adresse virtuelle. */ -bool g_exe_format_translate_address_into_vmpa_using_portions(GExecutableFormat *, virt_t, vmpa2t *); +bool g_executable_format_translate_address_into_vmpa_without_virt(const GExecutableFormat *, virt_t, vmpa2t *); -#endif +/* Fournit l'emplacement correspondant à une adresse virtuelle. */ +bool g_executable_format_translate_address_into_vmpa_with_portions(GExecutableFormat *, virt_t, vmpa2t *); diff --git a/src/format/executable.c b/src/format/executable.c index 187bd4e..80bfc9d 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -25,19 +25,17 @@ #include -/* #include #include -#include +//#include #include -*/ + #include "executable-int.h" -/* -#include "format.h" #include "../core/logs.h" +/* #include "../plugins/pglist.h" */ @@ -98,7 +96,7 @@ static void g_executable_format_class_init(GExecutableFormatClass *klass) static void g_executable_format_init(GExecutableFormat *format) { - //g_mutex_init(&format->mutex); + format->portions = NULL; } @@ -117,24 +115,8 @@ static void g_executable_format_init(GExecutableFormat *format) static void g_executable_format_dispose(GExecutableFormat *format) { - -#if 0 - size_t i; /* Boucle de parcours */ - - for (i = 0; i < format->debugs_count; i++) - g_clear_object(&format->debugs[i]); - - for (i = 0; i < format->user_count; i++) - g_clear_object(&format->user_portions[i]); - g_clear_object(&format->portions); - g_mutex_clear(&format->mutex); - -#endif - - - G_OBJECT_CLASS(g_executable_format_parent_class)->dispose(G_OBJECT(format)); } @@ -154,108 +136,56 @@ static void g_executable_format_dispose(GExecutableFormat *format) static void g_executable_format_finalize(GExecutableFormat *format) { -#if 0 - - if (format->debugs != NULL) - free(format->debugs); - - if (format->user_portions != NULL) - free(format->user_portions); - -#endif - - - G_OBJECT_CLASS(g_executable_format_parent_class)->finalize(G_OBJECT(format)); } - -#if 0 - /****************************************************************************** * * -* Paramètres : format = informations chargées à compléter. * -* info = informations de débogage à lier. * +* Paramètres : format = description du format à initialiser pleinement. * +* content = contenu binaire à parcourir. * * * -* Description : Rajoute des informations de débogage à un exécutable. * +* Description : Met en place un nouveau contenu binaire à analyser. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -void g_executable_format_add_debug_info(GExecutableFormat *format, GDbgFormat *info) +bool g_executable_format_create(GExecutableFormat *format, GBinContent *content) { - const char *desc; /* Description humaine associée*/ - - desc = g_known_format_get_description(G_KNOWN_FORMAT(info)); - - if (desc == NULL) - log_simple_message(LMT_WARNING, _("Unnamed debug information")); - else - log_variadic_message(LMT_INFO, _("Found debug information: %s"), desc); - - format->debugs = realloc(format->debugs, ++format->debugs_count * sizeof(GDbgFormat *)); - - format->debugs[format->debugs_count - 1] = info; - -} - + bool result; /* Bilan à retourner */ + vmpa2t addr; /* Emplacement vide de sens */ + phys_t length; /* Taille de portion globale */ + GExecutableFormatClass *class; /* Classe de l'instance */ -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Compte le nombre de formats de débogage liés à l'exécutable. * -* * -* Retour : Nombre de formats de débogage attachés. * -* * -* Remarques : - * -* * -******************************************************************************/ + result = g_program_format_create(G_PROGRAM_FORMAT(format), content); + if (!result) goto exit; -size_t g_executable_format_count_debug_info(const GExecutableFormat *format) -{ - return format->debugs_count; + /* Définition de portions */ -} + /** + * Avant de lire l'entête du format, on ne sait pas où on se trouve ! + */ + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + length = g_binary_content_compute_size(G_KNOWN_FORMAT(format)->content); -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* index = indice des informations à transmettre. * -* * -* Description : Fournit un format de débogage attaché à l'exécutable. * -* * -* Retour : Informations de débogage attachées. * -* * -* Remarques : - * -* * -******************************************************************************/ + format->portions = g_binary_portion_new(&addr, length); -GDbgFormat *g_executable_format_get_debug_info(const GExecutableFormat *format, size_t index) -{ - GDbgFormat *result; /* Format à retourner */ + class = G_EXECUTABLE_FORMAT_GET_CLASS(format); - if (index >= format->debugs_count) - result = NULL; + if (class->refine_portions != NULL) + result = class->refine_portions(format); - else - { - result = format->debugs[index]; - g_object_ref(G_OBJECT(result)); - } + exit: return result; } -#endif - /****************************************************************************** * * @@ -285,8 +215,6 @@ char *g_executable_format_get_target_machine(const GExecutableFormat *format) } -#if 0 - /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * @@ -294,7 +222,7 @@ char *g_executable_format_get_target_machine(const GExecutableFormat *format) * * * Description : Fournit l'adresse principale associée à un format. * * * -* Retour : Bilan des recherches. * +* Retour : Validité de l'adresse transmise. * * * * Remarques : - * * * @@ -303,110 +231,11 @@ char *g_executable_format_get_target_machine(const GExecutableFormat *format) bool g_executable_format_get_main_address(GExecutableFormat *format, vmpa2t *addr) { bool result; /* Bilan à retourner */ - GBinFormat *base; /* Version d'instance parente */ - - result = false; - - if (G_EXECUTABLE_FORMAT_GET_CLASS(format)->get_main_addr != NULL) - result = G_EXECUTABLE_FORMAT_GET_CLASS(format)->get_main_addr(format, addr); - - if (!result) - { - base = G_BIN_FORMAT(format); - - g_rw_lock_reader_lock(&base->pt_lock); - - if (base->pt_count[DPL_ENTRY_POINT] > 0) - result = g_executable_format_translate_address_into_vmpa(format, base->start_points[DPL_ENTRY_POINT][0], addr); - - g_rw_lock_reader_unlock(&base->pt_lock); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance à traiter. * -* status = barre de statut à tenir informée. * -* * -* Description : Crée les portions potentiellement utiles aux traductions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_executable_format_setup_portions(GExecutableFormat *format, GtkStatusStack *status) -{ - vmpa2t addr; /* Emplacement vide de sens */ - phys_t length; /* Taille de portion globale */ - GExecutableFormatClass *class; /* Classe de l'instance */ - size_t i; /* Boucle de parcours */ - - /** - * Avant de lire l'entête du format, on ne sait pas où on se trouve ! - */ - init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - - length = g_binary_content_compute_size(G_KNOWN_FORMAT(format)->content); - - format->portions = g_binary_portion_new(BPC_RAW, &addr, length); + GExecutableFormatClass *class; /* Classe de l'instance */ class = G_EXECUTABLE_FORMAT_GET_CLASS(format); - if (class->refine_portions != NULL) - class->refine_portions(format); - - for (i = 0; i < format->user_count; i++) - { - g_object_ref(G_OBJECT(format->user_portions[i])); - g_executable_format_include_portion(format, format->user_portions[i], NULL); - } - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance à traiter. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * -* * -* Description : Effectue les ultimes opérations de chargement d'un binaire. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_executable_format_complete_loading(GExecutableFormat *format, wgroup_id_t gid, GtkStatusStack *status) -{ - bool result; /* Bilan à faire remonter */ - size_t count; /* Qté d'infos supplémentaires */ - size_t i; /* Boucle de parcours */ - GDbgFormat *dbg; /* Informations de débogage */ - - result = true; - - attach_debug_format(format); - - count = g_executable_format_count_debug_info(format); - - for (i = 0; i < count && result; i++) - { - dbg = g_executable_format_get_debug_info(format, i); - - result = g_known_format_analyze(G_KNOWN_FORMAT(dbg), gid, status); - - g_object_unref(G_OBJECT(dbg)); - - } + result = class->get_main_addr(format, addr); return result; @@ -417,44 +246,19 @@ bool g_executable_format_complete_loading(GExecutableFormat *format, wgroup_id_t * * * Paramètres : format = description de l'exécutable à modifier. * * portion = portion à inclure dans les définitions du format. * -* * -* Description : Enregistre une portion artificielle pour le format. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_executable_format_register_user_portion(GExecutableFormat *format, GBinPortion *portion) -{ - g_mutex_lock(&format->mutex); - - format->user_portions = realloc(format->user_portions, ++format->user_count * sizeof(GBinPortion *)); - - format->user_portions[format->user_count - 1] = portion; - - g_mutex_unlock(&format->mutex); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à modifier. * -* portion = portion à inclure dans les définitions du format. * * origin = source de définition de la portion fournie. * * * * Description : Procède à l'enregistrement d'une portion dans un format. * * * -* Retour : - * +* Retour : Bilan de l'opération : true si inclusion, false sinon. * * * * Remarques : - * * * ******************************************************************************/ -void g_executable_format_include_portion(GExecutableFormat *format, GBinPortion *portion, const vmpa2t *origin) +bool g_executable_format_include_portion(GExecutableFormat *format, GBinaryPortion *portion, const vmpa2t *origin) { + bool result; /* Bilan à retourner */ phys_t available; /* Taille totale du bianire */ const mrange_t *range; /* Emplacement de la portion */ phys_t start; /* Début de zone de la portion */ @@ -463,6 +267,8 @@ void g_executable_format_include_portion(GExecutableFormat *format, GBinPortion phys_t remaining; /* Taille maximale envisageable*/ bool truncated; /* Modification faite ? */ + result = false; + available = g_binary_content_compute_size(G_KNOWN_FORMAT(format)->content); range = g_binary_portion_get_range(portion); @@ -470,14 +276,9 @@ void g_executable_format_include_portion(GExecutableFormat *format, GBinPortion start = get_phy_addr(get_mrange_addr(range)); if (get_mrange_length(range) == 0) - { log_variadic_message(LMT_BAD_BINARY, _("The binary portion '%s' is empty and thus useless... Discarding!"), g_binary_portion_get_desc(portion)); - g_object_unref(G_OBJECT(portion)); - - } - else if (start >= available) { if (origin == NULL) @@ -489,12 +290,10 @@ void g_executable_format_include_portion(GExecutableFormat *format, GBinPortion asprintf(&msg, _("Defined binary portion '%s' is out of the file scope... Discarding!"), g_binary_portion_get_desc(portion)); - g_binary_format_add_error(G_BIN_FORMAT(format), BFE_STRUCTURE, origin, msg); + //g_binary_format_add_error(G_BIN_FORMAT(format), BFE_STRUCTURE, origin, msg); free(msg); - g_object_unref(G_OBJECT(portion)); - } else @@ -507,14 +306,12 @@ void g_executable_format_include_portion(GExecutableFormat *format, GBinPortion log_variadic_message(LMT_BAD_BINARY, _("Truncated binary portion '%s' to fit the binary content size!"), g_binary_portion_get_desc(portion)); - g_mutex_lock(&format->mutex); - - g_binary_portion_include(format->portions, portion); - - g_mutex_unlock(&format->mutex); + result = g_binary_portion_include(format->portions, portion); } + return result; + } @@ -531,18 +328,15 @@ void g_executable_format_include_portion(GExecutableFormat *format, GBinPortion * * ******************************************************************************/ -GBinPortion *g_executable_format_get_portions(GExecutableFormat *format) +GBinaryPortion *g_executable_format_get_portions(GExecutableFormat *format) { - GBinPortion *result; /* Instance à retourner */ - - g_mutex_lock(&format->mutex); + GBinaryPortion *result; /* Instance à retourner */ result = format->portions; - if (result != NULL) - g_object_ref(G_OBJECT(result)); + assert(result != NULL); - g_mutex_unlock(&format->mutex); + ref_object(result); return result; @@ -566,8 +360,11 @@ GBinPortion *g_executable_format_get_portions(GExecutableFormat *format) bool g_executable_format_translate_offset_into_vmpa(GExecutableFormat *format, phys_t off, vmpa2t *pos) { bool result; /* Bilan à retourner */ + GExecutableFormatClass *class; /* Classe de l'instance */ - result = G_EXECUTABLE_FORMAT_GET_CLASS(format)->translate_phys(format, off, pos); + class = G_EXECUTABLE_FORMAT_GET_CLASS(format); + + result = class->translate_phys(format, off, pos); return result; @@ -577,10 +374,10 @@ bool g_executable_format_translate_offset_into_vmpa(GExecutableFormat *format, p /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * -* addr = adresse virtuelle à retrouver. * +* off = position physique à retrouver. * * pos = position correspondante. [OUT] * * * -* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* Description : Fournit l'emplacement correspondant à une position physique. * * * * Retour : Bilan de l'opération. * * * @@ -588,11 +385,38 @@ bool g_executable_format_translate_offset_into_vmpa(GExecutableFormat *format, p * * ******************************************************************************/ -bool g_executable_format_translate_address_into_vmpa(GExecutableFormat *format, virt_t addr, vmpa2t *pos) +bool g_executable_format_translate_offset_into_vmpa_without_virt(const GExecutableFormat *format, phys_t off, vmpa2t *pos) +{ + init_vmpa(pos, off, VMPA_NO_VIRTUAL); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* off = position physique à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une position physique. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_executable_format_translate_offset_into_vmpa_with_portions(GExecutableFormat *format, phys_t off, vmpa2t *pos) { bool result; /* Bilan à retourner */ - result = G_EXECUTABLE_FORMAT_GET_CLASS(format)->translate_virt(format, addr, pos); + if (format->portions == NULL) + result = false; + + else + result = g_binary_portion_translate_offset_into_vmpa(format->portions, off, pos); return result; @@ -602,10 +426,10 @@ bool g_executable_format_translate_address_into_vmpa(GExecutableFormat *format, /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * -* name = nom de la section recherchée. * -* range = emplacement en mémoire à renseigner. [OUT] * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * * * -* Description : Fournit l'emplacement d'une section donnée. * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * * * * Retour : Bilan de l'opération. * * * @@ -613,21 +437,77 @@ bool g_executable_format_translate_address_into_vmpa(GExecutableFormat *format, * * ******************************************************************************/ -bool g_executable_format_get_section_range_by_name(const GExecutableFormat *format, const char *name, mrange_t *range) +bool g_executable_format_translate_address_into_vmpa(GExecutableFormat *format, virt_t addr, vmpa2t *pos) { bool result; /* Bilan à retourner */ GExecutableFormatClass *class; /* Classe de l'instance */ class = G_EXECUTABLE_FORMAT_GET_CLASS(format); - if (class->get_range_by_name == NULL) + result = class->translate_virt(format, addr, pos); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_executable_format_translate_address_into_vmpa_without_virt(const GExecutableFormat *format, virt_t addr, vmpa2t *pos) +{ + /** + * S'il n'y a pas de notion de mémoire virtuelle, positions physiques et + * adresses virtuelles se confondent. + * + * On reste néanmoins cohérent, et on n'utilise donc pas d'adresse virtuelle. + * + * Les sauts dans le code renvoient de façon transparente vers des positions + * physiques. + */ + + init_vmpa(pos, addr, VMPA_NO_VIRTUAL); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_executable_format_translate_address_into_vmpa_with_portions(GExecutableFormat *format, virt_t addr, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + + if (format->portions == NULL) result = false; else - result = class->get_range_by_name(format, name, range); + result = g_binary_portion_translate_address_into_vmpa(format->portions, addr, pos); return result; } - -#endif diff --git a/src/format/executable.h b/src/format/executable.h index 6695b92..da71d66 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -25,7 +25,11 @@ #define _FORMAT_EXECUTABLE_H +#include + + #include "../glibext/helpers.h" +#include "../glibext/portion.h" @@ -37,46 +41,14 @@ DECLARE_GTYPE(GExecutableFormat, g_executable_format, G, EXECUTABLE_FORMAT); /* Indique le type d'architecture visée par le format. */ char *g_executable_format_get_target_machine(const GExecutableFormat *); - - - - -#if 0 - - -/* -#include "debuggable.h" -#include "../glibext/gbinportion.h" -*/ - - - -/* Rajoute des informations de débogage à un exécutable. */ -void g_executable_format_add_debug_info(GExecutableFormat *, GDbgFormat *); - -/* Compte le nombre de formats de débogage liés à l'exécutable. */ -size_t g_executable_format_count_debug_info(const GExecutableFormat *); - -/* Fournit un format de débogage attaché à l'exécutable. */ -GDbgFormat *g_executable_format_get_debug_info(const GExecutableFormat *, size_t); - -/* Indique le type d'architecture visée par le format. */ -//const char *g_executable_format_get_target_machine(const GExecutableFormat *); - /* Fournit l'adresse principale associée à un format. */ bool g_executable_format_get_main_address(GExecutableFormat *, vmpa2t *); -/* Enregistre une portion artificielle pour le format. */ -void g_executable_format_register_user_portion(GExecutableFormat *, GBinPortion *); - /* Procède à l'enregistrement d'une portion dans un format. */ -void g_executable_format_include_portion(GExecutableFormat *, GBinPortion *, const vmpa2t *); +bool g_executable_format_include_portion(GExecutableFormat *, GBinaryPortion *, const vmpa2t *); /* Fournit la première couche des portions composent le binaire. */ -GBinPortion *g_executable_format_get_portions(GExecutableFormat *); - -/* Fournit les espaces mémoires des portions exécutables. */ -mrange_t *g_executable_format_get_x_ranges(GExecutableFormat *, size_t *); +GBinaryPortion *g_executable_format_get_portions(GExecutableFormat *); /* Fournit l'emplacement correspondant à une position physique. */ bool g_executable_format_translate_offset_into_vmpa(GExecutableFormat *, phys_t, vmpa2t *); @@ -85,30 +57,24 @@ bool g_executable_format_translate_offset_into_vmpa(GExecutableFormat *, phys_t, bool g_executable_format_translate_address_into_vmpa(GExecutableFormat *, virt_t, vmpa2t *); -#define g_executable_format_translate_offset_into_address(fmt, off, addr) \ - ({ \ - bool __result; \ - vmpa2t __pos; \ - __result = g_executable_format_translate_offset_into_vmpa(fmt, off, &__pos); \ - *addr = get_virt_addr(&__pos); \ - __result; \ +#define g_executable_format_translate_offset_into_address(fmt, off, addr) \ + ({ \ + bool __result; \ + vmpa2t __pos; \ + __result = g_executable_format_translate_offset_into_vmpa(fmt, off, &__pos); \ + *addr = get_virt_addr(&__pos); \ + __result; \ }) -#define g_executable_format_translate_address_into_offset(fmt, addr, off) \ - ({ \ - bool __result; \ - vmpa2t __pos; \ - __result = g_executable_format_translate_address_into_vmpa(fmt, addr, &__pos); \ - *off = get_phy_addr(&__pos); \ - __result; \ +#define g_executable_format_translate_address_into_offset(fmt, addr, off) \ + ({ \ + bool __result; \ + vmpa2t __pos; \ + __result = g_executable_format_translate_address_into_vmpa(fmt, addr, &__pos); \ + *off = get_phy_addr(&__pos); \ + __result; \ }) -/* Fournit l'emplacement d'une section donnée. */ -bool g_executable_format_get_section_range_by_name(const GExecutableFormat *, const char *, mrange_t *); - -#endif - - #endif /* _FORMAT_EXECUTABLE_H */ diff --git a/src/format/flat-int.h b/src/format/flat-int.h index 2630ef9..f858ba3 100644 --- a/src/format/flat-int.h +++ b/src/format/flat-int.h @@ -50,7 +50,7 @@ struct _GFlatFormatClass }; -/* Met en place une nouvelle instance de format de à plat. */ +/* Met en place une nouvelle instance de format à plat. */ bool g_flat_format_create(GFlatFormat *, GBinContent *, const char *, SourceEndian); diff --git a/src/format/flat.c b/src/format/flat.c index 26dd22b..c4e6edb 100644 --- a/src/format/flat.c +++ b/src/format/flat.c @@ -58,13 +58,8 @@ static char *g_flat_format_get_key(const GFlatFormat *); /* Fournit une description humaine du format. */ static char *g_flat_format_get_description(const GFlatFormat *); - -#if 0 - /* Assure l'interprétation d'un format en différé. */ -static bool g_flat_format_analyze(GFlatFormat *, wgroup_id_t, GtkStatusStack *); - -#endif +static bool g_flat_format_analyze(GFlatFormat *); /* Informe quant au boutisme utilisé. */ static SourceEndian g_flat_format_get_endianness(const GFlatFormat *); @@ -118,15 +113,8 @@ static void g_flat_format_class_init(GFlatFormatClass *klass) known->get_key = (known_get_key_fc)g_flat_format_get_key; known->get_desc = (known_get_desc_fc)g_flat_format_get_description; - - - -#if 0 - known->analyze = (known_analyze_fc)g_flat_format_analyze; -#endif - prgm = G_PROGRAM_FORMAT_CLASS(klass); prgm->get_endian = (program_get_endian_fc)g_flat_format_get_endianness; @@ -136,11 +124,9 @@ static void g_flat_format_class_init(GFlatFormatClass *klass) exe->get_machine = (get_target_machine_fc)g_flat_format_get_target_machine; #if 0 exe->get_main_addr = (get_main_addr_fc)g_flat_format_get_main_address; - - exe->translate_phys = (translate_phys_fc)g_exe_format_translate_offset_into_vmpa_using_portions; - exe->translate_virt = (translate_virt_fc)g_exe_format_translate_address_into_vmpa_using_portions; - #endif + exe->translate_phys = g_executable_format_translate_offset_into_vmpa_with_portions; + exe->translate_virt = g_executable_format_translate_address_into_vmpa_with_portions; } @@ -238,8 +224,10 @@ GFlatFormat *g_flat_format_new(GBinContent *content, const char *machine, Source * * * Paramètres : format = description du format connu à consulter. * * content = contenu binaire à parcourir. * +* machine = architecture déterminée pour le code. * + endian = boutisme à observer pour les données. * * * -* Description : Met en place une nouvelle instance de format de à plat. * +* Description : Met en place une nouvelle instance de format à plat. * * * * Retour : Bilan de l'opération. * * * @@ -251,7 +239,7 @@ bool g_flat_format_create(GFlatFormat *format, GBinContent *content, const char { bool result; /* Bilan à retourner */ - result = g_known_format_create(G_KNOWN_FORMAT(format), content); + result = g_executable_format_create(G_EXECUTABLE_FORMAT(format), content); format->machine = strdup(machine); format->endian = endian; @@ -313,15 +301,9 @@ static char *g_flat_format_get_description(const GFlatFormat *format) } - - -#if 0 - /****************************************************************************** * * * Paramètres : format = format chargé dont l'analyse est lancée. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * * * * Description : Assure l'interprétation d'un format en différé. * * * @@ -331,20 +313,16 @@ static char *g_flat_format_get_description(const GFlatFormat *format) * * ******************************************************************************/ -static bool g_flat_format_analyze(GFlatFormat *format, wgroup_id_t gid, GtkStatusStack *status) +static bool g_flat_format_analyze(GFlatFormat *format) { bool result; /* Bilan à retourner */ result = true; - g_executable_format_setup_portions(G_EXECUTABLE_FORMAT(format), status); - return result; } -#endif - /****************************************************************************** * * diff --git a/src/format/known-int.h b/src/format/known-int.h index bac0c5c..75d0dab 100644 --- a/src/format/known-int.h +++ b/src/format/known-int.h @@ -36,13 +36,10 @@ typedef char * (* known_get_key_fc) (const GKnownFormat *); /* Fournit une description humaine du format. */ typedef char * (* known_get_desc_fc) (const GKnownFormat *); -#if 0 /*Assure l'interprétation d'un format en différé. */ -typedef bool (* known_analyze_fc) (GKnownFormat *, wgroup_id_t, GtkStatusStack *); - -/* Réalise un traitement post-désassemblage. */ -typedef void (* known_complete_analysis_fc) (GKnownFormat *, wgroup_id_t, GtkStatusStack *); +typedef bool (* known_analyze_fc) (GKnownFormat *); +#if 0 /* Charge un format depuis une mémoire tampon. */ typedef bool (* load_known_fc) (GKnownFormat *, GObjectStorage *, packed_buffer_t *); @@ -68,10 +65,9 @@ struct _GKnownFormatClass known_get_key_fc get_key; /* Désignation interne */ known_get_desc_fc get_desc; /* Désignation humaine */ -#if 0 known_analyze_fc analyze; /* Interprétation du format */ - known_complete_analysis_fc complete; /* Terminaison d'analyse */ +#if 0 load_known_fc load; /* Chargement depuis un tampon */ store_known_fc store; /* Conservation dans un tampon */ #endif diff --git a/src/format/known.c b/src/format/known.c index c32a00b..bc03793 100644 --- a/src/format/known.c +++ b/src/format/known.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * format.c - support des différents formats binaires reconnus * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -194,7 +194,7 @@ static void g_known_format_finalize(GKnownFormat *format) /****************************************************************************** * * -* Paramètres : format = description du format connu à consulter. * +* Paramètres : format = description du format à initialiser pleinement. * * content = contenu binaire à parcourir. * * * * Description : Met en place un nouveau contenu binaire à analyser. * @@ -301,13 +301,9 @@ char *g_known_format_get_description(const GKnownFormat *format) } -#if 0 - /****************************************************************************** * * * Paramètres : format = format chargé dont l'analyse est lancée. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * * * * Description : Assure l'interprétation d'un format en différé. * * * @@ -317,56 +313,24 @@ char *g_known_format_get_description(const GKnownFormat *format) * * ******************************************************************************/ -bool g_known_format_analyze(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status) +bool g_known_format_analyze(GKnownFormat *format) { bool result; /* Bilan à retourner */ GKnownFormatClass *class; /* Classe de l'instance */ - handle_known_format_analysis(PGA_FORMAT_ANALYSIS_STARTED, format, gid, status); + //handle_known_format_analysis(PGA_FORMAT_ANALYSIS_STARTED, format, gid, status); class = G_KNOWN_FORMAT_GET_CLASS(format); - result = class->analyze(format, gid, status); + result = class->analyze(format); - handle_known_format_analysis(PGA_FORMAT_ANALYSIS_ENDED, format, gid, status); + //handle_known_format_analysis(PGA_FORMAT_ANALYSIS_ENDED, format, gid, status); return result; } -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à manipuler. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * -* * -* Description : Réalise un traitement post-désassemblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_known_format_complete_analysis(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status) -{ - GKnownFormatClass *class; /* Classe de l'instance */ - - handle_known_format_analysis(PGA_FORMAT_POST_ANALYSIS_STARTED, format, gid, status); - - class = G_KNOWN_FORMAT_GET_CLASS(format); - - if (class->complete != NULL) - class->complete(format, gid, status); - - handle_known_format_analysis(PGA_FORMAT_POST_ANALYSIS_ENDED, format, gid, status); - -} - -#endif - - /* ---------------------------------------------------------------------------------- */ /* CONSERVATION ET RECHARGEMENT DES DONNEES */ diff --git a/src/format/known.h b/src/format/known.h index 3da433a..41236df 100644 --- a/src/format/known.h +++ b/src/format/known.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * format.h - prototypes pour le support des différents formats binaires reconnus * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -45,15 +45,8 @@ char *g_known_format_get_key(const GKnownFormat *); /* Fournit une description humaine du format. */ char *g_known_format_get_description(const GKnownFormat *); -#if 0 - /* Assure l'interprétation d'un format en différé. */ -bool g_known_format_analyze(GKnownFormat *, wgroup_id_t, GtkStatusStack *); - -/* Réalise un traitement post-désassemblage. */ -void g_known_format_complete_analysis(GKnownFormat *, wgroup_id_t, GtkStatusStack *); - -#endif +bool g_known_format_analyze(GKnownFormat *); diff --git a/src/format/program-int.h b/src/format/program-int.h index 958c6ff..1549a0a 100644 --- a/src/format/program-int.h +++ b/src/format/program-int.h @@ -35,6 +35,9 @@ /* Indique le boutisme employé par le format binaire analysé. */ typedef SourceEndian (* program_get_endian_fc) (const GProgramFormat *); +/* Fournit l'emplacement d'une section donnée. */ +typedef bool (* get_range_by_name_fc) (const GProgramFormat *, const char *, mrange_t *); + /* Format de programme générique (instance) */ struct _GProgramFormat @@ -49,10 +52,13 @@ struct _GProgramFormatClass GKnownFormatClass parent; /* A laisser en premier */ program_get_endian_fc get_endian; /* Boutisme employé */ + get_range_by_name_fc get_range_by_name; /* Emplacement de sections */ }; +/* Met en place un nouveau contenu binaire à analyser. */ +bool g_program_format_create(GProgramFormat *, GBinContent *); diff --git a/src/format/program.c b/src/format/program.c index 3624496..d44f988 100644 --- a/src/format/program.c +++ b/src/format/program.c @@ -285,8 +285,28 @@ static void g_program_format_finalize(GProgramFormat *format) } +/****************************************************************************** +* * +* Paramètres : format = description du format à initialiser pleinement. * +* content = contenu binaire à parcourir. * +* * +* Description : Met en place un nouveau contenu binaire à analyser. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_program_format_create(GProgramFormat *format, GBinContent *content) +{ + bool result; /* Bilan à retourner */ + result = g_known_format_create(G_KNOWN_FORMAT(format), content); + return result; + +} #if 0 @@ -446,6 +466,38 @@ SourceEndian g_program_format_get_endianness(const GProgramFormat *format) } +/****************************************************************************** +* * +* Paramètres : format = description du programme à consulter. * +* name = nom de la section recherchée. * +* range = emplacement en mémoire à renseigner. [OUT] * +* * +* Description : Fournit l'emplacement d'une section donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_program_format_get_section_range_by_name(const GProgramFormat *format, const char *name, mrange_t *range) +{ + bool result; /* Bilan à retourner */ + GProgramFormatClass *class; /* Classe de l'instance */ + + class = G_PROGRAM_FORMAT_GET_CLASS(format); + + if (class->get_range_by_name == NULL) + result = false; + + else + result = class->get_range_by_name(format, name, range); + + return result; + +} + + #if 0 /****************************************************************************** diff --git a/src/format/program.h b/src/format/program.h index 51b7860..0eb26ae 100644 --- a/src/format/program.h +++ b/src/format/program.h @@ -25,6 +25,10 @@ #define _FORMAT_PROGRAM_H +#include + + +#include "../arch/vmpa.h" #include "../common/datatypes.h" #include "../glibext/helpers.h" @@ -38,14 +42,14 @@ DECLARE_GTYPE(GProgramFormat, g_program_format, G, PROGRAM_FORMAT); /* Indique le boutisme employé par le format binaire analysé. */ SourceEndian g_program_format_get_endianness(const GProgramFormat *); +/* Fournit l'emplacement d'une section donnée. */ +bool g_program_format_get_section_range_by_name(const GProgramFormat *, const char *, mrange_t *); #if 0 -#include -#include #include diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 2d4abb8..adbec4c 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -9,8 +9,6 @@ noinst_LTLIBRARIES = libglibext.la libglibextui.la # configuration-int.h \ # configuration.h configuration.c \ # gbinarycursor.h gbinarycursor.c \ -# gbinportion-int.h \ -# gbinportion.h gbinportion.c \ # glinecursor-int.h \ # glinecursor.h glinecursor.c \ # gnhash.h gnhash.c \ @@ -43,6 +41,8 @@ noinst_LTLIBRARIES = libglibext.la libglibextui.la libglibext_la_SOURCES = \ chrysamarshal.h chrysamarshal.c \ helpers.h \ + portion-int.h \ + portion.h portion.c \ work-int.h \ work.h work.c \ workgroup-int.h \ diff --git a/src/glibext/portion-int.h b/src/glibext/portion-int.h index a29f53c..c044206 100644 --- a/src/glibext/portion-int.h +++ b/src/glibext/portion-int.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * binportion.h - prototypes pour la définition interne des portions de binaire + * portion-int.h - prototypes internes pour la définition interne des portions de binaire * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,46 +21,49 @@ */ -#ifndef _GLIBEXT_BINPORTION_INT_H -#define _GLIBEXT_BINPORTION_INT_H +#ifndef GLIBEXT_PORTION_INT_H +#define GLIBEXT_PORTION_INT_H -#include "gbinportion.h" +#include "portion.h" /* Portion de données binaires quelconques (instance) */ -struct _GBinPortion +struct _GBinaryPortion { GObject parent; /* A laisser en premier */ - char *code; /* Code de la couleur de fond */ - -#ifdef INCLUDE_GTK_SUPPORT - cairo_surface_t *icon; /* Image de représentation */ -#endif - char *desc; /* Désignation humaine */ - char **text; /* Lignes brutes à représenter */ - size_t lcount; /* Quantité de ces lignes */ mrange_t range; /* Emplacement dans le code */ bool continued; /* Suite d'une découpe ? */ PortionAccessRights rights; /* Droits d'accès */ - GBinPortion **subs; /* Portions incluses */ + GBinaryPortion **subs; /* Portions incluses */ size_t count; /* Quantité d'inclusions */ }; /* Portion de données binaires quelconques (classe) */ -struct _GBinPortionClass +struct _GBinaryPortionClass { GObjectClass parent; /* A laisser en premier */ }; +/* Met en place une description de partie de code vierge. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_create(GBinaryPortion *, const vmpa2t *, phys_t); + + -#endif /* _GLIBEXT_BINPORTION_INT_H */ +#endif /* GLIBEXT_PORTION_INT_H */ diff --git a/src/glibext/portion.c b/src/glibext/portion.c index 12e12fb..e5604b6 100644 --- a/src/glibext/portion.c +++ b/src/glibext/portion.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * binportion.c - représentation graphique de portions de binaire + * portion.c - représentation graphique de portions de binaire * - * Copyright (C) 2013-2019 Cyrille Bagard + * Copyright (C) 2013-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,26 +21,26 @@ */ -#include "gbinportion.h" +#include "portion.h" #include #include -#include -#include +//#include +//#include #include #include -#include "gbinportion-int.h" -#include "../analysis/human/asm/lang.h" +#include "portion-int.h" +//#include "../analysis/human/asm/lang.h" #include "../common/extstr.h" #include "../common/sort.h" -#include "../core/columns.h" -#include "../glibext/gbinarycursor.h" -#include "../glibext/linegen-int.h" +//#include "../core/columns.h" +//#include "../glibext/gbinarycursor.h" +//#include "../glibext/linegen-int.h" @@ -48,50 +48,16 @@ /* Initialise la classe des portions de données binaires. */ -static void g_binary_portion_class_init(GBinPortionClass *); +static void g_binary_portion_class_init(GBinaryPortionClass *); /* Initialise une instance de portion de données binaires. */ -static void g_binary_portion_init(GBinPortion *); - -/* Procède à l'initialisation de l'interface de génération. */ -static void g_binary_portion_interface_init(GLineGeneratorInterface *); +static void g_binary_portion_init(GBinaryPortion *); /* Supprime toutes les références externes. */ -static void g_binary_portion_dispose(GBinPortion *); +static void g_binary_portion_dispose(GBinaryPortion *); /* Procède à la libération totale de la mémoire. */ -static void g_binary_portion_finalize(GBinPortion *); - -#ifdef INCLUDE_GTK_SUPPORT - -/* Détermine l'aire d'une sous-portion. */ -static bool g_binary_portion_compute_sub_area(const GBinPortion *, phys_t, const GdkRectangle *, GdkRectangle *); - -#endif - - - -/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ - - -/* Indique le nombre de ligne prêtes à être générées. */ -static size_t g_binary_portion_count_lines(const GBinPortion *); - -#ifdef INCLUDE_GTK_SUPPORT - -/* Retrouve l'emplacement correspondant à une position donnée. */ -static void g_binary_portion_compute_cursor(const GBinPortion *, gint, size_t, size_t, GLineCursor **); - -/* Détermine si le conteneur s'inscrit dans une plage donnée. */ -static int g_binary_portion_contain_cursor(const GBinPortion *, size_t, size_t, const GLineCursor *); - -#endif - -/* Renseigne sur les propriétés liées à un générateur. */ -static BufferLineFlags g_binary_portion_get_flags(const GBinPortion *, size_t, size_t); - -/* Imprime dans une ligne de rendu le contenu représenté. */ -static void g_binary_portion_print(GBinPortion *, GBufferLine *, size_t, size_t, const GBinContent *); +static void g_binary_portion_finalize(GBinaryPortion *); @@ -99,20 +65,7 @@ static void g_binary_portion_print(GBinPortion *, GBufferLine *, size_t, size_t, /* Détermine si une portion contient une adresse donnée. */ -static bool g_binary_portion_contains_vmpa(const GBinPortion *, const vmpa2t *); - -#ifdef INCLUDE_GTK_SUPPORT - -/* Recherche la portion présente à une adresse donnée. */ -static GBinPortion *g_binary_portion_find_with_area_at_addr(GBinPortion *, const vmpa2t *, GdkRectangle *); - -/* Détermine si une portion contient une position donnée. */ -static bool g_binary_portion_contains_physical(const GBinPortion *, phys_t); - -/* Détermine si une portion contient une adresse donnée. */ -static bool g_binary_portion_contains_virtual(const GBinPortion *, virt_t); - -#endif +static bool g_binary_portion_contains_vmpa(const GBinaryPortion *, const vmpa2t *); @@ -122,8 +75,7 @@ static bool g_binary_portion_contains_virtual(const GBinPortion *, virt_t); /* Indique le type défini par la GLib pour les portions de données binaires. */ -G_DEFINE_TYPE_WITH_CODE(GBinPortion, g_binary_portion, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_binary_portion_interface_init)); +G_DEFINE_TYPE(GBinaryPortion, g_binary_portion, G_TYPE_OBJECT); /****************************************************************************** @@ -138,7 +90,7 @@ G_DEFINE_TYPE_WITH_CODE(GBinPortion, g_binary_portion, G_TYPE_OBJECT, * * ******************************************************************************/ -static void g_binary_portion_class_init(GBinPortionClass *klass) +static void g_binary_portion_class_init(GBinaryPortionClass *klass) { GObjectClass *object; /* Autre version de la classe */ @@ -163,49 +115,21 @@ static void g_binary_portion_class_init(GBinPortionClass *klass) * * ******************************************************************************/ -static void g_binary_portion_init(GBinPortion *portion) +static void g_binary_portion_init(GBinaryPortion *portion) { vmpa2t dummy; /* Coquille presque vide */ - portion->code = NULL; - -#ifdef INCLUDE_GTK_SUPPORT - portion->icon = NULL; -#endif - portion->desc = NULL; - portion->text = NULL; - portion->lcount = 0; init_vmpa(&dummy, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); init_mrange(&portion->range, &dummy, VMPA_NO_VIRTUAL); portion->continued = false; -} - - -/****************************************************************************** -* * -* Paramètres : iface = interface GLib à initialiser. * -* * -* Description : Procède à l'initialisation de l'interface de génération. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + portion->rights = PAC_NONE; -static void g_binary_portion_interface_init(GLineGeneratorInterface *iface) -{ - iface->count = (linegen_count_lines_fc)g_binary_portion_count_lines; -#ifdef INCLUDE_GTK_SUPPORT - iface->compute = (linegen_compute_fc)g_binary_portion_compute_cursor; - iface->contain = (linegen_contain_fc)g_binary_portion_contain_cursor; -#endif - iface->get_flags = (linegen_get_flags_fc)g_binary_portion_get_flags; - iface->print = (linegen_print_fc)g_binary_portion_print; + portion->subs = NULL; + portion->count = 0; } @@ -222,7 +146,7 @@ static void g_binary_portion_interface_init(GLineGeneratorInterface *iface) * * ******************************************************************************/ -static void g_binary_portion_dispose(GBinPortion *portion) +static void g_binary_portion_dispose(GBinaryPortion *portion) { size_t i; /* Boucle de parcours */ @@ -246,27 +170,11 @@ static void g_binary_portion_dispose(GBinPortion *portion) * * ******************************************************************************/ -static void g_binary_portion_finalize(GBinPortion *portion) +static void g_binary_portion_finalize(GBinaryPortion *portion) { - size_t i; /* Boucle de parcours */ - - if (portion->code != NULL) - free(portion->code); - -#ifdef INCLUDE_GTK_SUPPORT - if (portion->icon != NULL) - cairo_surface_destroy(portion->icon); -#endif - if (portion->desc != NULL) free(portion->desc); - for (i = 0; i < portion->lcount; i++) - free(portion->text[i]); - - if (portion->text != NULL) - free(portion->text); - if (portion->subs != NULL) free(portion->subs); @@ -277,8 +185,7 @@ static void g_binary_portion_finalize(GBinPortion *portion) /****************************************************************************** * * -* Paramètres : code = désignation humaine de la couleur de fond. * -* addr = emplacement de la section à conserver. * +* Paramètres : addr = emplacement de la section à conserver. * * size = taille de la section à conserver. * * * * Description : Crée une description de partie de code vierge. * @@ -289,15 +196,11 @@ static void g_binary_portion_finalize(GBinPortion *portion) * * ******************************************************************************/ -GBinPortion *g_binary_portion_new(const char *code, const vmpa2t *addr, phys_t size) +GBinaryPortion *g_binary_portion_new(const vmpa2t *addr, phys_t size) { - GBinPortion *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_BIN_PORTION, NULL); + GBinaryPortion *result; /* Structure à retourner */ - result->code = strdup(code); - - init_mrange(&result->range, addr, size); + result = g_object_new(G_TYPE_BINARY_PORTION, NULL); return result; @@ -306,89 +209,60 @@ GBinPortion *g_binary_portion_new(const char *code, const vmpa2t *addr, phys_t s /****************************************************************************** * * -* Paramètres : a = premières informations à consulter. * -* b = secondes informations à consulter. * +* Paramètres : portion = instance à initialiser pleinement. * +* addr = emplacement de la section à conserver. * +* size = taille de la section à conserver. * * * -* Description : Etablit la comparaison ascendante entre deux portions. * +* Description : Met en place une description de partie de code vierge. * * * -* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -int g_binary_portion_compare(const GBinPortion **a, const GBinPortion **b) +bool g_binary_portion_create(GBinaryPortion *portion, const vmpa2t *addr, phys_t size) { - int result; /* Bilan à retourner */ - const vmpa2t *addr_a; /* Adresse de la portion 'a' */ - const vmpa2t *addr_b; /* Adresse de la portion 'b' */ + bool result; /* Bilan à retourner */ - addr_a = get_mrange_addr(&(*a)->range); - addr_b = get_mrange_addr(&(*b)->range); + result = true; - result = cmp_vmpa(addr_a, addr_b); + init_mrange(&portion->range, addr, size); return result; } -#ifdef INCLUDE_GTK_SUPPORT - - /****************************************************************************** * * -* Paramètres : portion = description de partie à mettre à jour. * -* icon = image miniature de représentation à associer. * -* * -* Description : Attribue à la portion une éventuelle image de représentation.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_portion_set_icon(GBinPortion *portion, cairo_surface_t *icon) -{ - if (icon != NULL) - portion->icon = cairo_surface_reference(icon); - - else - portion->icon = NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : portion = description de partie à consulter. * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * * * -* Description : Fournit une éventuelle image de représentation de portion. * +* Description : Etablit la comparaison ascendante entre deux portions. * * * -* Retour : Image miniature de représentation associée. * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * * * * Remarques : - * * * ******************************************************************************/ -cairo_surface_t *g_binary_portion_get_icon(const GBinPortion *portion) +int g_binary_portion_compare(const GBinaryPortion **a, const GBinaryPortion **b) { - cairo_surface_t *result; + int result; /* Bilan à retourner */ + const vmpa2t *addr_a; /* Adresse de la portion 'a' */ + const vmpa2t *addr_b; /* Adresse de la portion 'b' */ - result = portion->icon; + addr_a = get_mrange_addr(&(*a)->range); + addr_b = get_mrange_addr(&(*b)->range); - if (result != NULL) - cairo_surface_reference(result); + result = cmp_vmpa(addr_a, addr_b); return result; } -#endif - - /****************************************************************************** * * * Paramètres : portion = description de partie à mettre à jour. * @@ -402,26 +276,11 @@ cairo_surface_t *g_binary_portion_get_icon(const GBinPortion *portion) * * ******************************************************************************/ -void g_binary_portion_set_desc(GBinPortion *portion, const char *desc) +void g_binary_portion_set_desc(GBinaryPortion *portion, const char *desc) { - size_t i; /* Boucle de parcours */ - GCodingLanguage *lang; /* Langage de sortie préféré */ - if (portion->desc != NULL) - { free(portion->desc); - for (i = 0; i < portion->lcount; i++) - free(portion->text[i]); - - if (portion->text != NULL) - { - free(portion->text); - portion->text = NULL; - } - - } - if (desc == NULL) portion->desc = NULL; @@ -432,40 +291,6 @@ void g_binary_portion_set_desc(GBinPortion *portion, const char *desc) if (portion->continued) portion->desc = stradd(portion->desc, _(" (continued)")); - /* Constitution du rendu */ - - portion->text = calloc(5, sizeof(char *)); - portion->lcount = 5; - - portion->text[0] = strdup("======================================================"); - portion->text[1] = strdup(""); - - asprintf(&portion->text[2], "%s (%s%s%s%s)", portion->desc, _("rights: "), - portion->rights & PAC_READ ? "r" : "-", - portion->rights & PAC_WRITE ? "w" : "-", - portion->rights & PAC_EXEC ? "x" : "-"); - - portion->text[3] = strdup(""); - portion->text[4] = strdup("======================================================"); - - /* Ajout de la touche "commentaires" */ - - lang = g_asm_language_new(); - - g_coding_language_encapsulate_comments(lang, &portion->text, &portion->lcount); - - g_object_unref(G_OBJECT(lang)); - - /* Ajout de deux bordures vides */ - - portion->lcount += 2; - portion->text = realloc(portion->text, portion->lcount * sizeof(char *)); - - memmove(&portion->text[1], &portion->text[0], (portion->lcount - 2) * sizeof(char *)); - - portion->text[0] = NULL; - portion->text[portion->lcount - 1] = NULL; - } } @@ -483,7 +308,7 @@ void g_binary_portion_set_desc(GBinPortion *portion, const char *desc) * * ******************************************************************************/ -const char *g_binary_portion_get_desc(const GBinPortion *portion) +const char *g_binary_portion_get_desc(const GBinaryPortion *portion) { return portion->desc; @@ -502,7 +327,7 @@ const char *g_binary_portion_get_desc(const GBinPortion *portion) * * ******************************************************************************/ -const mrange_t *g_binary_portion_get_range(const GBinPortion *portion) +const mrange_t *g_binary_portion_get_range(const GBinaryPortion *portion) { return &portion->range; @@ -521,7 +346,7 @@ const mrange_t *g_binary_portion_get_range(const GBinPortion *portion) * * ******************************************************************************/ -bool g_binary_portion_limit_range(GBinPortion *portion, phys_t max) +bool g_binary_portion_limit_range(GBinaryPortion *portion, phys_t max) { bool result; /* Bilan à retourner */ phys_t current; /* Taille courante */ @@ -552,7 +377,7 @@ bool g_binary_portion_limit_range(GBinPortion *portion, phys_t max) * * ******************************************************************************/ -void g_binary_portion_mark_as_continued(GBinPortion *portion, bool continued) +void g_binary_portion_mark_as_continued(GBinaryPortion *portion, bool continued) { portion->continued = continued; @@ -571,7 +396,7 @@ void g_binary_portion_mark_as_continued(GBinPortion *portion, bool continued) * * ******************************************************************************/ -bool g_binary_portion_is_continuation(const GBinPortion *portion) +bool g_binary_portion_is_continuation(const GBinaryPortion *portion) { return portion->continued; @@ -591,7 +416,7 @@ bool g_binary_portion_is_continuation(const GBinPortion *portion) * * ******************************************************************************/ -void g_binary_portion_set_rights(GBinPortion *portion, PortionAccessRights rights) +void g_binary_portion_set_rights(GBinaryPortion *portion, PortionAccessRights rights) { portion->rights = rights; @@ -610,199 +435,13 @@ void g_binary_portion_set_rights(GBinPortion *portion, PortionAccessRights right * * ******************************************************************************/ -PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion) +PortionAccessRights g_binary_portion_get_rights(const GBinaryPortion *portion) { return portion->rights; } -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : portion = description de partie à mettre à jour. * -* tooltip = astuce à compléter. [OUT] * -* * -* Description : Prépare une astuce concernant une portion pour son affichage.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_portion_query_tooltip(GBinPortion *portion, GtkTooltip *tooltip) -{ - char *markup; /* Description à construire */ - VMPA_BUFFER(value); /* Traduction en texte */ - - /* Nom */ - - if (portion->desc != NULL) - { - markup = strdup(""); - markup = stradd(markup, portion->desc); - markup = stradd(markup, "\n"); - markup = stradd(markup, "\n"); - - } - else markup = strdup(""); - - markup = stradd(markup, "taille : "); - mrange_length_to_string(&portion->range, MDS_UNDEFINED, value, NULL); - markup = stradd(markup, value); - markup = stradd(markup, "\n"); - - /* Localisation */ - - markup = stradd(markup, ""); - markup = stradd(markup, _("Localisation")); - markup = stradd(markup, "\n"); - - markup = stradd(markup, _("physical: from ")); - - mrange_phys_to_string(&portion->range, MDS_UNDEFINED, true, value, NULL); - markup = stradd(markup, value); - markup = stradd(markup, _(" to ")); - mrange_phys_to_string(&portion->range, MDS_UNDEFINED, false, value, NULL); - markup = stradd(markup, value); - markup = stradd(markup, "\n"); - - markup = stradd(markup, _("memory: from ")); - - mrange_virt_to_string(&portion->range, MDS_UNDEFINED, true, value, NULL); - markup = stradd(markup, value); - markup = stradd(markup, _(" to ")); - mrange_virt_to_string(&portion->range, MDS_UNDEFINED, false, value, NULL); - markup = stradd(markup, value); - - markup = stradd(markup, "\n\n"); - - /* Droits d'accès */ - - markup = stradd(markup, ""); - markup = stradd(markup, _("Rights")); - markup = stradd(markup, "\n"); - - snprintf(value, 2 * VMPA_MAX_SIZE, "%s%s%s", - portion->rights & PAC_READ ? "r" : "-", - portion->rights & PAC_WRITE ? "w" : "-", - portion->rights & PAC_EXEC ? "x" : "-"); - - markup = stradd(markup, value); - - /* Impression finale */ - - gtk_tooltip_set_markup(tooltip, markup); - free(markup); - -} - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : portion = portion mère à consulter. * -* full = taille totale de la couche parente. * -* area = étendue de représentation de la portion mère. * -* sub_area = étendue de représentation de la portion fille. * -* * -* Description : Détermine l'aire d'une sous-portion. * -* * -* Retour : true si la sous-surface a été calculée correctement. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_binary_portion_compute_sub_area(const GBinPortion *portion, phys_t full, const GdkRectangle *area, GdkRectangle *sub_area) -{ - phys_t length; /* Taille de la portion */ - phys_t start; /* Position de départ */ - - length = get_mrange_length(&portion->range); - - /* On saute les portions comme le segment GNU_STACK... */ - if (length == 0) return false; - - start = get_phy_addr(get_mrange_addr(&portion->range)); - - sub_area->y = area->y; - sub_area->height = area->height; - - sub_area->x = area->x + (start * area->width) / full; - sub_area->width = (length * area->width) / full; - - return true; - -} - - -#endif - - -/****************************************************************************** -* * -* Paramètres : portion = description de partie à consulter. * -* context = contexte graphique associé à la procédure. * -* cr = contexte graphique pour le dessin. * -* area = étendue mise à disposition. * -* * -* Description : Représente la portion sur une bande dédiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_portion_draw(const GBinPortion *portion, GtkStyleContext *context, cairo_t *cr, const GdkRectangle *area) -{ - phys_t full; /* Espace total représenté */ - size_t i; /* Boucle de parcours */ - GBinPortion *sub; /* Portion incluse à montrer */ - GdkRectangle sub_area; /* Etendue d'une sous-portion */ - - /* Dessin de la portion courante */ - - cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); - - gtk_style_context_save(context); - - if (portion->code != NULL) - gtk_style_context_add_class(context, portion->code); - - gtk_render_background(context, cr, area->x, area->y, area->width, area->height); - - gtk_render_frame(context, cr, area->x, area->y, area->width, area->height); - - gtk_style_context_restore(context); - - /* Dessin des portions contenues */ - - full = get_mrange_length(&portion->range); - - for (i = 0; i < portion->count; i++) - { - sub = portion->subs[i]; - - if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area)) - continue; - - g_binary_portion_draw(sub, context, cr, &sub_area); - - } - -} - - -#endif - - /****************************************************************************** * * * Paramètres : portion = portion principale à compléter. * @@ -810,14 +449,15 @@ void g_binary_portion_draw(const GBinPortion *portion, GtkStyleContext *context, * * * Description : Procède à l'inclusion d'une portion dans une autre. * * * -* Retour : - * +* Retour : Bilan de l'opération : true si inclusion, false sinon. * * * * Remarques : - * * * ******************************************************************************/ -void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) +bool g_binary_portion_include(GBinaryPortion *portion, GBinaryPortion *sub) { + bool result; /* Bilan à retourner */ bool found; /* Zone d'accueil trouvée ? */ size_t best; /* Meilleur point d'insertion */ size_t missed; /* Indice de zone à déplacer */ @@ -825,11 +465,11 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) vmpa2t end; /* Fin de la zone commune */ phys_t overlapping; /* Taille de la zone commune */ bool continued; /* Suite d'une découpe ? */ - GBinPortion *left_part; /* Partie intégrable */ + GBinaryPortion *left_part; /* Partie intégrable */ vmpa2t start; /* Départ de la seconde partie */ - GBinPortion *right_part; /* Partie restante */ + GBinaryPortion *right_part; /* Partie restante */ - int g_binary_portion_is_included(const GBinPortion **a, const GBinPortion **b) + int g_binary_portion_is_included(const GBinaryPortion **a, const GBinaryPortion **b) { int result; /* Bilan à retourner */ @@ -839,7 +479,7 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) } - found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinPortion *), + found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinaryPortion *), (__compar_fn_t)g_binary_portion_is_included, &best); if (!found) @@ -879,7 +519,7 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) * */ - int g_binary_portion_track_missed_inclusion(const GBinPortion **a, const GBinPortion **b) + int g_binary_portion_track_missed_inclusion(const GBinaryPortion **a, const GBinaryPortion **b) { int result; /* Bilan à retourner */ @@ -891,14 +531,15 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) do { - found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinPortion *), + found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinaryPortion *), (__compar_fn_t)g_binary_portion_track_missed_inclusion, &missed); if (found) { - g_binary_portion_include(sub, portion->subs[missed]); + result = g_binary_portion_include(sub, portion->subs[missed]); + assert(result); - portion->subs = _qdelete(portion->subs, &portion->count, sizeof(GBinPortion *), missed); + portion->subs = _qdelete(portion->subs, &portion->count, sizeof(GBinaryPortion *), missed); } @@ -916,7 +557,7 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) * de découper la portion qui déborde. */ - int g_binary_portion_track_partial_inclusion(const GBinPortion **a, const GBinPortion **b) + int g_binary_portion_track_partial_inclusion(const GBinaryPortion **a, const GBinaryPortion **b) { int result; /* Bilan à retourner */ @@ -926,7 +567,7 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) } - found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinPortion *), + found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinaryPortion *), (__compar_fn_t)g_binary_portion_track_partial_inclusion, &best); if (found) @@ -940,7 +581,7 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) /* Partie contenue */ - left_part = g_binary_portion_new(sub->code, get_mrange_addr(&sub->range), overlapping); + left_part = g_binary_portion_new(get_mrange_addr(&sub->range), overlapping); g_binary_portion_set_desc(left_part, sub->desc); g_binary_portion_mark_as_continued(left_part, continued); @@ -958,7 +599,7 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) copy_vmpa(&start, get_mrange_addr(&sub->range)); advance_vmpa(&start, overlapping); - right_part = g_binary_portion_new(sub->code, &start, get_mrange_length(&sub->range) - overlapping); + right_part = g_binary_portion_new(&start, get_mrange_length(&sub->range) - overlapping); if (!continued) g_binary_portion_mark_as_continued(right_part, true); @@ -972,22 +613,34 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) /* Inclusions des parties */ - g_binary_portion_include(portion, left_part); - g_binary_portion_include(portion, right_part); + result = g_binary_portion_include(portion, left_part); - g_object_unref(G_OBJECT(sub)); + if (result) + result = g_binary_portion_include(portion, right_part); + + unref_object(left_part); + unref_object(right_part); } else - portion->subs = qinsert(portion->subs, &portion->count, sizeof(GBinPortion *), + { + ref_object(sub); + + portion->subs = qinsert(portion->subs, &portion->count, sizeof(GBinaryPortion *), (__compar_fn_t)g_binary_portion_compare, &sub); + result = true; + + } + } /* Poursuite de l'inclusion dans la sous-portion adaptée... */ else - g_binary_portion_include(portion->subs[best], sub); + result = g_binary_portion_include(portion->subs[best], sub); + + return result; } @@ -1006,11 +659,11 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) * * ******************************************************************************/ -bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void *data) +bool g_binary_portion_visit(GBinaryPortion *portion, visit_portion_fc visitor, void *data) { bool result; /* Etat à retourner */ - bool visit_portion(GBinPortion *p, GBinPortion *pp) + bool visit_portion(GBinaryPortion *p, GBinaryPortion *pp) { bool ret; /* Etat à retourner */ size_t i; /* Boucle de parcours */ @@ -1043,253 +696,10 @@ bool g_binary_portion_visit(GBinPortion *portion, visit_portion_fc visitor, void /* ---------------------------------------------------------------------------------- */ -/* OFFRE DE CAPACITES DE GENERATION */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : portion = générateur à consulter. * -* * -* Description : Indique le nombre de ligne prêtes à être générées. * -* * -* Retour : Nombre de lignes devant apparaître au final. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t g_binary_portion_count_lines(const GBinPortion *portion) -{ - return portion->lcount; - -} - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : portion = générateur à consulter. * -* x = position géographique sur la ligne concernée. * -* index = indice de cette même ligne dans le tampon global. * -* repeat = indice d'utilisations successives du générateur. * -* cursor = emplacement à constituer. [OUT] * -* * -* Description : Retrouve l'emplacement correspondant à une position donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_portion_compute_cursor(const GBinPortion *portion, gint x, size_t index, size_t repeat, GLineCursor **cursor) -{ - *cursor = g_binary_cursor_new(); - - g_binary_cursor_update(G_BINARY_CURSOR(*cursor), get_mrange_addr(&portion->range)); - -} - - -/****************************************************************************** -* * -* Paramètres : portion = générateur à consulter. * -* index = indice de cette même ligne dans le tampon global. * -* repeat = indice d'utilisations successives du générateur. * -* cursor = emplacement à analyser. * -* * -* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * -* * -* Retour : Bilan de la détermination, utilisable en comparaisons. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int g_binary_portion_contain_cursor(const GBinPortion *portion, size_t index, size_t repeat, const GLineCursor *cursor) -{ - int result; /* Conclusion à retourner */ - vmpa2t addr; /* Autre emplacement à comparer*/ - - assert(G_IS_BINARY_CURSOR(cursor)); - - g_binary_cursor_retrieve(G_BINARY_CURSOR(cursor), &addr); - - result = cmp_vmpa(&addr, get_mrange_addr(&portion->range)); - - return result; - -} - - -#endif - - -/****************************************************************************** -* * -* Paramètres : portion = générateur à consulter. * -* index = indice de cette même ligne dans le tampon global. * -* repeat = indice d'utilisations successives du générateur. * -* * -* Description : Renseigne sur les propriétés liées à un générateur. * -* * -* Retour : Propriétés particulières associées. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static BufferLineFlags g_binary_portion_get_flags(const GBinPortion *portion, size_t index, size_t repeat) -{ - return (repeat == 0 ? BLF_WIDTH_MANAGER : BLF_NONE); - -} - - -/****************************************************************************** -* * -* Paramètres : portion = générateur à utiliser pour l'impression. * -* line = ligne de rendu à compléter. * -* index = indice de cette même ligne dans le tampon global. * -* repeat = indice d'utilisations successives du générateur. * -* content = éventuel contenu binaire brut à imprimer. * -* * -* Description : Imprime dans une ligne de rendu le contenu représenté. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_portion_print(GBinPortion *portion, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content) -{ - assert(repeat < portion->lcount); - - g_buffer_line_fill_phys(line, DLC_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&portion->range)); - - g_buffer_line_fill_virt(line, DLC_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&portion->range)); - - if (portion->text[repeat] != NULL) - { - g_buffer_line_start_merge_at(line, DLC_ASSEMBLY_LABEL); - - g_buffer_line_append_text(line, DLC_ASSEMBLY_LABEL, SL(portion->text[repeat]), RTT_COMMENT, NULL); - - } - -} - - - -/* ---------------------------------------------------------------------------------- */ /* PARCOURS D'ENSEMBLES DE PORTIONS */ /* ---------------------------------------------------------------------------------- */ -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : portion = couche de portions à parcourir pour les recherches.* -* * -* Description : Compte le nombre de portions présentes dans une arborescence.* -* * -* Retour : Quantité de portions présentes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_binary_portion_count(const GBinPortion *portion) -{ - size_t result; /* Quantité à retourner */ - - - size_t measure_portion_size(const GBinPortion *root) - { - size_t count; /* Nombre de trouvailles */ - size_t i; /* Boucle de parcours */ - - count = 1; - - for (i = 0; i < root->count; i++) - count += measure_portion_size(root->subs[i]); - - return count; - - } - - - result = measure_portion_size(portion); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : portion = couche de portions à parcourir pour les recherches.* -* x = abscisse du point de recherche. * -* area = étendue de portion mère, puis celle trouvée. [OUT] * -* * -* Description : Recherche la portion présente à un point donné. * -* * -* Retour : Portion trouvée à l'endroit indiqué. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRectangle *area) -{ - GBinPortion *result; /* Portion à retourner */ - phys_t full; /* Espace total représenté */ - size_t i; /* Boucle de parcours */ - GBinPortion *sub; /* Portion incluse à traiter */ - GdkRectangle sub_area; /* Etendue d'une sous-portion */ - - result = NULL; - - full = get_mrange_length(&portion->range); - - for (i = 0; i < portion->count && result == NULL; i++) - { - sub = portion->subs[i]; - - if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area)) - continue; - - if (sub_area.x <= x && x < (sub_area.x + sub_area.width)) - { - result = g_binary_portion_find_at_pos(sub, x, &sub_area); - - if (result != NULL) - *area = sub_area; - - } - - } - - if (result == NULL) - { - result = portion; - g_object_ref(G_OBJECT(result)); - } - - return result; - -} - - -#endif - - /****************************************************************************** * * * Paramètres : portion = portion mère à consulter. * @@ -1303,7 +713,7 @@ GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRecta * * ******************************************************************************/ -static bool g_binary_portion_contains_vmpa(const GBinPortion *portion, const vmpa2t *addr) +static bool g_binary_portion_contains_vmpa(const GBinaryPortion *portion, const vmpa2t *addr) { bool result; /* Bilan à retourner */ const mrange_t *range; /* Emplacement de portion */ @@ -1338,16 +748,16 @@ static bool g_binary_portion_contains_vmpa(const GBinPortion *portion, const vmp * * ******************************************************************************/ -GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *addr) +GBinaryPortion *g_binary_portion_find_at_addr(GBinaryPortion *portion, const vmpa2t *addr) { - GBinPortion *result; /* Portion à retourner */ - phys_t full; /* Espace total représenté */ - size_t i; /* Boucle de parcours #1 */ - GBinPortion *sub; /* Portion incluse à traiter */ + GBinaryPortion *result; /* Portion à retourner */ + size_t i; /* Boucle de parcours */ + GBinaryPortion *sub; /* Portion incluse à traiter */ result = NULL; - full = get_mrange_length(&portion->range); + if (!g_binary_portion_contains_vmpa(portion, addr)) + goto done; for (i = 0; i < portion->count && result == NULL; i++) { @@ -1363,65 +773,10 @@ GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *a if (result == NULL) { result = portion; - g_object_ref(G_OBJECT(result)); + ref_object(result); } - return result; - -} - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -* * -* Paramètres : portion = couche de portions à parcourir pour les recherches.* -* addr = adresse du point de recherche. * -* area = étendue de portion mère, puis celle trouvée. [OUT] * -* * -* Description : Recherche la portion présente à une adresse donnée. * -* * -* Retour : Portion trouvée à l'endroit indiqué. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBinPortion *g_binary_portion_find_with_area_at_addr(GBinPortion *portion, const vmpa2t *addr, GdkRectangle *area) -{ - GBinPortion *result; /* Portion à retourner */ - phys_t full; /* Espace total représenté */ - size_t i; /* Boucle de parcours #1 */ - GBinPortion *sub; /* Portion incluse à traiter */ - GdkRectangle sub_area; /* Etendue d'une sous-portion */ - - result = NULL; - - full = get_mrange_length(&portion->range); - - for (i = 0; i < portion->count && result == NULL; i++) - { - sub = portion->subs[i]; - - if (!g_binary_portion_contains_vmpa(sub, addr)) - continue; - - if (!g_binary_portion_compute_sub_area(sub, full, area, &sub_area)) - continue; - - result = g_binary_portion_find_with_area_at_addr(sub, addr, &sub_area); - - if (result != NULL) - *area = sub_area; - - } - - if (result == NULL) - { - result = portion; - g_object_ref(G_OBJECT(result)); - } + done: return result; @@ -1430,114 +785,6 @@ static GBinPortion *g_binary_portion_find_with_area_at_addr(GBinPortion *portion /****************************************************************************** * * -* Paramètres : root = couche de portions à parcourir pour les recherches. * -* x = abscisse du point de recherche. * -* area = étendue de représentation de la portion mère. * -* addr = adresse correspondante. [OUT] * -* * -* Description : Fournit la position correspondant à une adresse donnée. * -* * -* Retour : Succès de la traduction. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_binary_portion_addr_from_pos(GBinPortion *root, gint x, const GdkRectangle *area, vmpa2t *addr) -{ - GdkRectangle owner_area; /* Aire de contenance */ - GBinPortion *owner; /* Conteneur propriétaire */ - - owner_area = *area; - - owner = g_binary_portion_find_at_pos(root, x, &owner_area); - if (owner == NULL) return false; - - copy_vmpa(addr, get_mrange_addr(&owner->range)); - - advance_vmpa(addr, (get_mrange_length(&owner->range) * (x - owner_area.x)) / owner_area.width); - - g_object_unref(G_OBJECT(owner)); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : root = couche de portions à parcourir pour les recherches. * -* addr = adresse du point de recherche. * -* area = étendue de représentation de la portion mère. * -* x = position correspondante. [OUT] * -* * -* Description : Fournit l'adresse correspondant à une position donnée. * -* * -* Retour : Succès de la traduction. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_binary_portion_pos_from_addr(GBinPortion *root, const vmpa2t *addr, const GdkRectangle *area, gint *x) -{ - GdkRectangle owner_area; /* Aire de contenance */ - GBinPortion *owner; /* Conteneur propriétaire */ - phys_t diff; /* Décalage à appliquer */ - - owner_area = *area; - - owner = g_binary_portion_find_with_area_at_addr(root, addr, &owner_area); - if (owner == NULL) return false; - - diff = compute_vmpa_diff(addr, get_mrange_addr(&owner->range)); - - *x = owner_area.x + (diff * owner_area.width) / get_mrange_length(&owner->range); - - g_object_unref(G_OBJECT(owner)); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : layer = couche de portions à consulter. * -* x = abscisse du point de recherche. * -* y = ordonnée du point de recherche. * -* area = étendue de représentation de la portion mère. * -* tooltip = astuce à compléter. [OUT] * -* * -* Description : Prépare une astuce concernant une portion pour son affichage.* -* * -* Retour : TRUE pour valider l'affichage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gboolean query_tooltip_for_binary_portion(GBinPortion *root, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip) -{ - GBinPortion *selected; /* Portion à décrire ici */ - - selected = g_binary_portion_find_at_pos(root, x, (GdkRectangle []) { *area }); - if (selected == NULL) return FALSE; - - g_binary_portion_query_tooltip(selected, tooltip); - - g_object_unref(G_OBJECT(selected)); - - return TRUE; - -} - - -#endif - - -/****************************************************************************** -* * * Paramètres : portion = portion mère à consulter. * * off = position physique du point de recherche. * * * @@ -1549,7 +796,7 @@ gboolean query_tooltip_for_binary_portion(GBinPortion *root, gint x, gint y, con * * ******************************************************************************/ -static bool g_binary_portion_contains_physical(const GBinPortion *portion, phys_t off) +static bool g_binary_portion_contains_physical(const GBinaryPortion *portion, phys_t off) { bool result; /* Bilan à retourner */ const mrange_t *range; /* Emplacement de portion */ @@ -1583,11 +830,11 @@ static bool g_binary_portion_contains_physical(const GBinPortion *portion, phys_ * * ******************************************************************************/ -bool g_binary_portion_translate_offset_into_vmpa(const GBinPortion *portion, phys_t off, vmpa2t *pos) +bool g_binary_portion_translate_offset_into_vmpa(const GBinaryPortion *portion, phys_t off, vmpa2t *pos) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours #1 */ - GBinPortion *sub; /* Portion incluse à traiter */ + GBinaryPortion *sub; /* Portion incluse à traiter */ const mrange_t *range; /* Emplacement de portion */ const vmpa2t *addr; /* Départ de la portion */ @@ -1643,7 +890,7 @@ bool g_binary_portion_translate_offset_into_vmpa(const GBinPortion *portion, phy * * ******************************************************************************/ -static bool g_binary_portion_contains_virtual(const GBinPortion *portion, virt_t virt) +static bool g_binary_portion_contains_virtual(const GBinaryPortion *portion, virt_t virt) { bool result; /* Bilan à retourner */ const mrange_t *range; /* Emplacement de portion */ @@ -1677,11 +924,11 @@ static bool g_binary_portion_contains_virtual(const GBinPortion *portion, virt_t * * ******************************************************************************/ -bool g_binary_portion_translate_address_into_vmpa(const GBinPortion *portion, virt_t virt, vmpa2t *pos) +bool g_binary_portion_translate_address_into_vmpa(const GBinaryPortion *portion, virt_t virt, vmpa2t *pos) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours #1 */ - GBinPortion *sub; /* Portion incluse à traiter */ + GBinaryPortion *sub; /* Portion incluse à traiter */ const mrange_t *range; /* Emplacement de portion */ const vmpa2t *addr; /* Départ de la portion */ diff --git a/src/glibext/portion.h b/src/glibext/portion.h index ea4b4aa..88d69b6 100644 --- a/src/glibext/portion.h +++ b/src/glibext/portion.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * binportion.h - prototypes pour la représentation graphique de portions de binaire + * portion.h - prototypes pour la représentation graphique de portions de binaire * - * Copyright (C) 2013-2019 Cyrille Bagard + * Copyright (C) 2013-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,120 +21,70 @@ */ -#ifndef _GLIBEXT_BINPORTION_H -#define _GLIBEXT_BINPORTION_H +#ifndef _GLIBEXT_PORTION_H +#define _GLIBEXT_PORTION_H -#include #include -#ifdef INCLUDE_GTK_SUPPORT -# include -#endif +#include "helpers.h" #include "../arch/vmpa.h" -#include "../common/fnv1a.h" /* ------------------------------- PORTION DE BINAIRE ------------------------------- */ -/** - * Couleurs de représentation. - */ - -#define BPC_RAW "binportion-raw" -#define BPC_CODE "binportion-code" -#define BPC_DATA "binportion-data" -#define BPC_DATA_RO "binportion-data-ro" -#define BPC_DISASS_ERROR "binportion-disassembly-error" - - -#define G_TYPE_BIN_PORTION (g_binary_portion_get_type()) -#define G_BIN_PORTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_PORTION, GBinPortion)) -#define G_IS_BIN_PORTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_PORTION)) -#define G_BIN_PORTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_PORTION, GBinPortionClass)) -#define G_IS_BIN_PORTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_PORTION)) -#define G_BIN_PORTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_PORTION, GBinPortionClass)) - - -/* Portion de données binaires quelconques (instance) */ -typedef struct _GBinPortion GBinPortion; - -/* Portion de données binaires quelconques (classe) */ -typedef struct _GBinPortionClass GBinPortionClass; - - -/* Droits d'accès à une portion */ -typedef enum _PortionAccessRights -{ - PAC_NONE = (0 << 0), /* Aucun */ - PAC_READ = (1 << 0), /* Lecture */ - PAC_WRITE = (1 << 1), /* Ecriture */ - PAC_EXEC = (1 << 2) /* Exécution */ - -} PortionAccessRights; +#define G_TYPE_BINARY_PORTION (g_binary_portion_get_type()) +DECLARE_GTYPE(GBinaryPortion, g_binary_portion, G, BINARY_PORTION); -#define PAC_ALL ((PortionAccessRights)(PAC_READ | PAC_WRITE | PAC_EXEC)) - - -/* Indique le type défini par la GLib pour les portions de données binaires. */ -GType g_binary_portion_get_type(void); /* Crée une description de partie de code vierge. */ -GBinPortion *g_binary_portion_new(const char *, const vmpa2t *, phys_t); +GBinaryPortion *g_binary_portion_new(const vmpa2t *, phys_t); /* Etablit la comparaison ascendante entre deux portions. */ -int g_binary_portion_compare(const GBinPortion **, const GBinPortion **); - -#ifdef INCLUDE_GTK_SUPPORT - -/* Attribue à la portion une éventuelle image de représentation. */ -void g_binary_portion_set_icon(GBinPortion *, cairo_surface_t *); - -/* Fournit une éventuelle image de représentation de portion. */ -cairo_surface_t *g_binary_portion_get_icon(const GBinPortion *); - -#endif +int g_binary_portion_compare(const GBinaryPortion **, const GBinaryPortion **); /* Attribue une description humaine à une partie de code. */ -void g_binary_portion_set_desc(GBinPortion *, const char *); +void g_binary_portion_set_desc(GBinaryPortion *, const char *); /* Fournit la description attribuée à une partie de code. */ -const char *g_binary_portion_get_desc(const GBinPortion *); +const char *g_binary_portion_get_desc(const GBinaryPortion *); /* Fournit l'emplacement d'une partie de code binaire. */ -const mrange_t *g_binary_portion_get_range(const GBinPortion *); +const mrange_t *g_binary_portion_get_range(const GBinaryPortion *); /* Assure qu'une portion ne dépasse pas une position donnée. */ -bool g_binary_portion_limit_range(GBinPortion *, phys_t); +bool g_binary_portion_limit_range(GBinaryPortion *, phys_t); /* Définit la nature de la portion en terme d'originalité. */ -void g_binary_portion_mark_as_continued(GBinPortion *, bool); +void g_binary_portion_mark_as_continued(GBinaryPortion *, bool); /* Indique la nature de la portion en terme d'originalité. */ -bool g_binary_portion_is_continuation(const GBinPortion *); - -/* Définit les droits associés à une partie de code. */ -void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights); +bool g_binary_portion_is_continuation(const GBinaryPortion *); -/* Fournit les droits associés à une partie de code. */ -PortionAccessRights g_binary_portion_get_rights(const GBinPortion *); +/* Droits d'accès à une portion */ +typedef enum _PortionAccessRights +{ + PAC_NONE = (0 << 0), /* Aucun */ + PAC_READ = (1 << 0), /* Lecture */ + PAC_WRITE = (1 << 1), /* Ecriture */ + PAC_EXEC = (1 << 2) /* Exécution */ -#ifdef INCLUDE_GTK_SUPPORT +} PortionAccessRights; -/* Prépare une astuce concernant une portion pour son affichage. */ -void g_binary_portion_query_tooltip(GBinPortion *, GtkTooltip *); +#define PAC_ALL ((PortionAccessRights)(PAC_READ | PAC_WRITE | PAC_EXEC)) -/* Représente la portion sur une bande dédiée. */ -void g_binary_portion_draw(const GBinPortion *, GtkStyleContext *, cairo_t *, const GdkRectangle *); +/* Définit les droits associés à une partie de code. */ +void g_binary_portion_set_rights(GBinaryPortion *, PortionAccessRights); -#endif +/* Fournit les droits associés à une partie de code. */ +PortionAccessRights g_binary_portion_get_rights(const GBinaryPortion *); /* Procède à l'inclusion d'une portion dans une autre. */ -void g_binary_portion_include(GBinPortion *, GBinPortion *); +bool g_binary_portion_include(GBinaryPortion *, GBinaryPortion *); /* Sens des visites */ typedef enum _BinaryPortionVisit @@ -147,47 +97,24 @@ typedef enum _BinaryPortionVisit /* Fonction appelée à chaque visite de portion.*/ -typedef bool (* visit_portion_fc) (GBinPortion *, GBinPortion *, BinaryPortionVisit, void *); +typedef bool (* visit_portion_fc) (GBinaryPortion *, GBinaryPortion *, BinaryPortionVisit, void *); /* Parcourt un ensemble de portions binaires. */ -bool g_binary_portion_visit(GBinPortion *, visit_portion_fc, void *); +bool g_binary_portion_visit(GBinaryPortion *, visit_portion_fc, void *); /* ------------------------ PARCOURS D'ENSEMBLES DE PORTIONS ------------------------ */ -#ifdef INCLUDE_GTK_SUPPORT - -/* Compte le nombre de portions présentes dans une arborescence. */ -size_t g_binary_portion_count(const GBinPortion *); - -/* Recherche la portion présente à un point donné. */ -GBinPortion *g_binary_portion_find_at_pos(GBinPortion *, gint, GdkRectangle *); - -#endif - /* Recherche la portion présente à une adresse donnée. */ -GBinPortion *g_binary_portion_find_at_addr(GBinPortion *, const vmpa2t *); - -#ifdef INCLUDE_GTK_SUPPORT - -/* Fournit la position correspondant à une adresse donnée. */ -bool get_binary_portion_addr_from_pos(GBinPortion *, gint, const GdkRectangle *, vmpa2t *); - -/* Fournit l'adresse correspondant à une position donnée. */ -bool get_binary_portion_pos_from_addr(GBinPortion *, const vmpa2t *, const GdkRectangle *, gint *); - -/* Prépare une astuce concernant une portion pour son affichage. */ -gboolean query_tooltip_for_binary_portion(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *); - -#endif +GBinaryPortion *g_binary_portion_find_at_addr(GBinaryPortion *, const vmpa2t *); /* Fournit l'emplacement correspondant à une position physique. */ -bool g_binary_portion_translate_offset_into_vmpa(const GBinPortion *, phys_t, vmpa2t *); +bool g_binary_portion_translate_offset_into_vmpa(const GBinaryPortion *, phys_t, vmpa2t *); /* Fournit l'emplacement correspondant à une adresse virtuelle. */ -bool g_binary_portion_translate_address_into_vmpa(const GBinPortion *, virt_t, vmpa2t *); +bool g_binary_portion_translate_address_into_vmpa(const GBinaryPortion *, virt_t, vmpa2t *); diff --git a/tests/format/executable.py b/tests/format/executable.py new file mode 100644 index 0000000..ec42ccd --- /dev/null +++ b/tests/format/executable.py @@ -0,0 +1,59 @@ + +from chrysacase import ChrysalideTestCase +from pychrysalide.analysis.contents import MemoryContent +from pychrysalide.arch import vmpa +from pychrysalide.format import ExecutableFormat + + +class TestExecutableFormat(ChrysalideTestCase): + """TestCase for format.ExecutableFormat.""" + + + def testMainAddresses(self): + """Provide several kinds of main addresses.""" + + data = b'\x00\x00\x00\xef' + cnt = MemoryContent(data) + + + class CustomFormatVmpa(ExecutableFormat): + + def _get_main_address(self): + return vmpa(246, 357) + + cf = CustomFormatVmpa(cnt) + + self.assertEqual(cf.main_address.phys, 246) + self.assertEqual(cf.main_address.virt, 357) + + + class CustomFormatInt(ExecutableFormat): + + def _get_main_address(self): + return 123 + + cf = CustomFormatInt(cnt) + + self.assertIsNone(cf.main_address.phys) + self.assertEqual(cf.main_address.virt, 123) + + + class CustomFormatNone(ExecutableFormat): + + def _get_main_address(self): + return None + + cf = CustomFormatNone(cnt) + + self.assertIsNone(cf.main_address) + + + class CustomFormatBad(ExecutableFormat): + + def _get_main_address(self): + return 'bad' + + cf = CustomFormatBad(cnt) + + with self.assertRaisesRegex(Exception, 'unable to define a value for the main address'): + ma = cf.main_address diff --git a/tests/glibext/portion.py b/tests/glibext/portion.py new file mode 100644 index 0000000..3e91969 --- /dev/null +++ b/tests/glibext/portion.py @@ -0,0 +1,17 @@ + +from chrysacase import ChrysalideTestCase +from pychrysalide.arch import vmpa +from pychrysalide.glibext import BinaryPortion + + +class TestWorks(ChrysalideTestCase): + """TestCase for pychrysalide.glibext.BinaryPortion""" + + def testBasicBinaryPortion(self): + """Implement a basic binary portion.""" + + addr = vmpa(0, vmpa.VmpaSpecialValue.NO_VIRTUAL) + + p = BinaryPortion(addr, 10) + + self.assertEqual(p.range.addr, addr) -- cgit v0.11.2-87-g4458