From de2cb8e2fad4a3031d7b7c2cb189a6dbdaf8d5a9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 3 Jul 2018 00:39:25 +0200 Subject: Extented the types definitions. --- configure.ac | 1 + plugins/dalvik/operands/pool.c | 6 +- plugins/dexbnf/type.c | 3 +- plugins/pychrysalide/analysis/Makefile.am | 5 +- plugins/pychrysalide/analysis/routine.c | 2 +- plugins/pychrysalide/analysis/type.c | 2 +- plugins/pychrysalide/analysis/types/Makefile.am | 29 ++ plugins/pychrysalide/analysis/types/array.c | 414 ++++++++++++++++++++++ plugins/pychrysalide/analysis/types/array.h | 42 +++ plugins/pychrysalide/analysis/types/basic.c | 250 ++++++++++++++ plugins/pychrysalide/analysis/types/basic.h | 42 +++ plugins/pychrysalide/analysis/types/cse.c | 269 +++++++++++++++ plugins/pychrysalide/analysis/types/cse.h | 42 +++ plugins/pychrysalide/analysis/types/encaps.c | 262 ++++++++++++++ plugins/pychrysalide/analysis/types/encaps.h | 42 +++ plugins/pychrysalide/analysis/types/expr.c | 185 ++++++++++ plugins/pychrysalide/analysis/types/expr.h | 42 +++ plugins/pychrysalide/analysis/types/literal.c | 135 ++++++++ plugins/pychrysalide/analysis/types/literal.h | 42 +++ plugins/pychrysalide/analysis/types/module.c | 107 ++++++ plugins/pychrysalide/analysis/types/module.h | 39 +++ plugins/pychrysalide/analysis/types/override.c | 247 +++++++++++++ plugins/pychrysalide/analysis/types/override.h | 42 +++ plugins/pychrysalide/analysis/types/proto.c | 314 +++++++++++++++++ plugins/pychrysalide/analysis/types/proto.h | 42 +++ plugins/pychrysalide/analysis/types/template.c | 311 +++++++++++++++++ plugins/pychrysalide/analysis/types/template.h | 42 +++ src/analysis/routine.c | 73 ++-- src/analysis/routine.h | 15 +- src/analysis/type-int.h | 24 +- src/analysis/type.c | 213 ++++++++---- src/analysis/type.h | 27 +- src/analysis/types/Makefile.am | 5 +- src/analysis/types/array.c | 429 +++++++++++++++++++++++ src/analysis/types/array.h | 76 ++++ src/analysis/types/basic.c | 118 ++++--- src/analysis/types/basic.h | 15 +- src/analysis/types/cse-int.h | 59 ---- src/analysis/types/cse.c | 167 +++++++-- src/analysis/types/cse.h | 29 +- src/analysis/types/encaps.c | 238 +++++++------ src/analysis/types/encaps.h | 20 +- src/analysis/types/expr.c | 258 ++++++++++++++ src/analysis/types/expr.h | 61 ++++ src/analysis/types/literal.c | 155 +++++---- src/analysis/types/literal.h | 14 +- src/analysis/types/override.c | 365 ++++++++++++++++++++ src/analysis/types/override.h | 78 +++++ src/analysis/types/proto.c | 441 ++++++++++++++++++++++++ src/analysis/types/proto.h | 73 ++++ src/analysis/types/template.c | 264 +++++++++----- src/analysis/types/template.h | 28 +- src/analysis/variable.c | 47 +-- src/analysis/variable.h | 3 - src/mangling/java_gram.y | 6 +- tests/mangling/dex.py | 2 +- 56 files changed, 5642 insertions(+), 620 deletions(-) create mode 100644 plugins/pychrysalide/analysis/types/Makefile.am create mode 100644 plugins/pychrysalide/analysis/types/array.c create mode 100644 plugins/pychrysalide/analysis/types/array.h create mode 100644 plugins/pychrysalide/analysis/types/basic.c create mode 100644 plugins/pychrysalide/analysis/types/basic.h create mode 100644 plugins/pychrysalide/analysis/types/cse.c create mode 100644 plugins/pychrysalide/analysis/types/cse.h create mode 100644 plugins/pychrysalide/analysis/types/encaps.c create mode 100644 plugins/pychrysalide/analysis/types/encaps.h create mode 100644 plugins/pychrysalide/analysis/types/expr.c create mode 100644 plugins/pychrysalide/analysis/types/expr.h create mode 100644 plugins/pychrysalide/analysis/types/literal.c create mode 100644 plugins/pychrysalide/analysis/types/literal.h create mode 100644 plugins/pychrysalide/analysis/types/module.c create mode 100644 plugins/pychrysalide/analysis/types/module.h create mode 100644 plugins/pychrysalide/analysis/types/override.c create mode 100644 plugins/pychrysalide/analysis/types/override.h create mode 100644 plugins/pychrysalide/analysis/types/proto.c create mode 100644 plugins/pychrysalide/analysis/types/proto.h create mode 100644 plugins/pychrysalide/analysis/types/template.c create mode 100644 plugins/pychrysalide/analysis/types/template.h create mode 100644 src/analysis/types/array.c create mode 100644 src/analysis/types/array.h delete mode 100644 src/analysis/types/cse-int.h create mode 100644 src/analysis/types/expr.c create mode 100644 src/analysis/types/expr.h create mode 100644 src/analysis/types/override.c create mode 100644 src/analysis/types/override.h create mode 100644 src/analysis/types/proto.c create mode 100644 src/analysis/types/proto.h diff --git a/configure.ac b/configure.ac index cdaa458..400818b 100644 --- a/configure.ac +++ b/configure.ac @@ -361,6 +361,7 @@ AC_CONFIG_FILES([Makefile plugins/pychrysalide/analysis/contents/Makefile plugins/pychrysalide/analysis/db/Makefile plugins/pychrysalide/analysis/db/items/Makefile + plugins/pychrysalide/analysis/types/Makefile plugins/pychrysalide/arch/Makefile plugins/pychrysalide/common/Makefile plugins/pychrysalide/core/Makefile diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index 6bb1323..821ca5b 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -281,7 +281,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff if (type != NULL) { - tmp = g_data_type_to_string(type); + tmp = g_data_type_to_string(type, true); g_object_unref(G_OBJECT(type)); g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); @@ -313,7 +313,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff if (field != NULL) { - tmp = g_binary_variable_to_string(field, false); + tmp = g_binary_variable_to_string(field, true); g_object_unref(G_OBJECT(field)); g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); @@ -346,7 +346,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff if (routine != NULL) { - tmp = g_binary_routine_to_string(routine); + tmp = g_binary_routine_to_string(routine, true); g_object_unref(G_OBJECT(routine)); g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL); diff --git a/plugins/dexbnf/type.c b/plugins/dexbnf/type.c index 29ba0a8..ff9af09 100644 --- a/plugins/dexbnf/type.c +++ b/plugins/dexbnf/type.c @@ -113,8 +113,7 @@ static GDataType *dtd_full_class_name(input_buffer *buffer) result = g_class_enum_type_new(CET_CLASS, name); - g_data_type_set_namespace(result, ns); - g_object_unref(ns); + g_data_type_set_namespace(result, ns, "."); } while (1); diff --git a/plugins/pychrysalide/analysis/Makefile.am b/plugins/pychrysalide/analysis/Makefile.am index edac3c0..3d7ac51 100644 --- a/plugins/pychrysalide/analysis/Makefile.am +++ b/plugins/pychrysalide/analysis/Makefile.am @@ -15,7 +15,8 @@ libpychrysaanalysis_la_SOURCES = \ libpychrysaanalysis_la_LIBADD = \ contents/libpychrysaanalysiscontents.la \ - db/libpychrysaanalysisdb.la + db/libpychrysaanalysisdb.la \ + types/libpychrysaanalysistypes.la libpychrysaanalysis_la_LDFLAGS = @@ -30,4 +31,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = contents db +SUBDIRS = contents db types diff --git a/plugins/pychrysalide/analysis/routine.c b/plugins/pychrysalide/analysis/routine.c index d0abd72..f8bc009 100644 --- a/plugins/pychrysalide/analysis/routine.c +++ b/plugins/pychrysalide/analysis/routine.c @@ -79,7 +79,7 @@ static PyObject *py_binary_routine_to_str(PyObject *self) routine = G_BIN_ROUTINE(pygobject_get(self)); - desc = g_binary_routine_to_string(routine); + desc = g_binary_routine_to_string(routine, true); result = PyUnicode_FromString(desc); diff --git a/plugins/pychrysalide/analysis/type.c b/plugins/pychrysalide/analysis/type.c index 1d9e9f0..146e490 100644 --- a/plugins/pychrysalide/analysis/type.c +++ b/plugins/pychrysalide/analysis/type.c @@ -61,7 +61,7 @@ static PyObject *py_data_type_to_str(PyObject *self) type = G_DATA_TYPE(pygobject_get(self)); - desc = _g_data_type_to_string(type, false); + desc = g_data_type_to_string(type, true); result = PyUnicode_FromString(desc); diff --git a/plugins/pychrysalide/analysis/types/Makefile.am b/plugins/pychrysalide/analysis/types/Makefile.am new file mode 100644 index 0000000..53ae320 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/Makefile.am @@ -0,0 +1,29 @@ + +noinst_LTLIBRARIES = libpychrysaanalysistypes.la + +libpychrysaanalysistypes_la_SOURCES = \ + array.h array.c \ + basic.h basic.c \ + cse.h cse.c \ + encaps.h encaps.c \ + expr.h expr.c \ + literal.h literal.c \ + module.h module.c \ + override.h override.c \ + proto.h proto.c \ + template.h template.c + +libpychrysaanalysistypes_la_LDFLAGS = + + +devdir = $(includedir)/chrysalide-$(subdir) + +dev_HEADERS = $(libpychrysaanalysistypes_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I$(top_srcdir)/src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/plugins/pychrysalide/analysis/types/array.c b/plugins/pychrysalide/analysis/types/array.c new file mode 100644 index 0000000..d021e16 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/array.c @@ -0,0 +1,414 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * array.c - équivalent Python du fichier "analysis/types/array.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "array.h" + + +#include +#include + + +#include +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'ArrayType'. */ +static PyObject *py_array_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Fournit le type des membres du tableau. */ +static PyObject *py_array_type_get_members_type(PyObject *, void *); + +/* Indique si la dimension du tableau est chiffrée. */ +static PyObject *py_array_type_is_numbered(PyObject *, void *); + +/* Fournit la dimension associée au tableau. */ +static PyObject *py_array_type_get_dimension(PyObject *, void *); + +/* Fournit la dimension associée au tableau. */ +static PyObject *py_array_type_get_dimension_number(PyObject *, void *); + +/* Définit la dimension associée au tableau. */ +static int py_array_type_set_dimension_number(PyObject *, PyObject *, void *); + +/* Fournit la dimension associée au tableau. */ +static PyObject *py_array_type_get_dimension_expression(PyObject *, void *); + +/* Définit la dimension associée au tableau. */ +static int py_array_type_set_dimension_expression(PyObject *, PyObject *, void *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ArrayType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_array_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + PyObject *members_obj; /* Objet du type d'éléments */ + int ret; /* Bilan de lecture des args. */ + GDataType *members; /* Version GLib du type */ + GDataType *dtype; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "O!", get_python_data_type_type(), &members_obj); + if (!ret) return NULL; + + members = G_DATA_TYPE(pygobject_get(members_obj)); + + dtype = g_array_type_new(members); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type des membres du tableau. * +* * +* Retour : Instance d'un autre type. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_array_type_get_members_type(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GArrayType *type; /* Version GLib du type */ + GDataType *members; /* Type des membres du tableau */ + + type = G_ARRAY_TYPE(pygobject_get(self)); + + members = g_array_type_get_members_type(type); + + result = pygobject_new(G_OBJECT(members)); + + g_object_unref(members); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique si la dimension du tableau est chiffrée. * +* * +* Retour : Py_True si la dimension est chiffrée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_array_type_is_numbered(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GArrayType *type; /* Version GLib du type */ + bool status; /* Nature de la dimension liée */ + + type = G_ARRAY_TYPE(pygobject_get(self)); + + status = g_array_type_is_dimension_numbered(type); + + result = status ? Py_True : Py_False; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Dimension de nature variable. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_array_type_get_dimension(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GArrayType *type; /* Version GLib du type */ + bool status; /* Nature de la dimension liée */ + + type = G_ARRAY_TYPE(pygobject_get(self)); + + status = g_array_type_is_dimension_numbered(type); + + if (status) + result = py_array_type_get_dimension_number(self, NULL); + else + result = py_array_type_get_dimension_expression(self, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Dimension positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_array_type_get_dimension_number(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GArrayType *type; /* Version GLib du type */ + ssize_t dim; /* Taille du tableau */ + + type = G_ARRAY_TYPE(pygobject_get(self)); + + dim = g_array_type_get_dimension_number(type); + + result = PyLong_FromSsize_t(dim); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit la dimension associée au tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_array_type_set_dimension_number(PyObject *self, PyObject *value, void *closure) +{ + GArrayType *type; /* Version GLib du type */ + + if (!PyLong_Check(value)) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a number.")); + return -1; + } + + type = G_ARRAY_TYPE(pygobject_get(self)); + + g_array_type_set_dimension_number(type, PyLong_AsSsize_t(value)); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Expression de dimension. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_array_type_get_dimension_expression(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GArrayType *type; /* Version GLib du type */ + const char *dim; /* Taille du tableau */ + + type = G_ARRAY_TYPE(pygobject_get(self)); + + dim = g_array_type_get_dimension_expression(type); + + result = PyUnicode_FromString(dim); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit la dimension associée au tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_array_type_set_dimension_expression(PyObject *self, PyObject *value, void *closure) +{ + GArrayType *type; /* Version GLib du type */ + + if (!PyUnicode_Check(value)) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string.")); + return -1; + } + + type = G_ARRAY_TYPE(pygobject_get(self)); + + g_array_type_set_dimension_expression(type, strdup(PyUnicode_DATA(value))); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_array_type_type(void) +{ + static PyMethodDef py_array_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_array_type_getseters[] = { + { + "members", py_array_type_get_members_type, NULL, + "Provide the type of each members of the array.", NULL + }, + { + "numbered", py_array_type_is_numbered, NULL, + "Tell if the dimension of the array is a number.", NULL + }, + { + "dimension", py_array_type_get_dimension, NULL, + "Provide the array dimension.", NULL + }, + { + "dimension_number", py_array_type_get_dimension_number, py_array_type_set_dimension_number, + "Give access to the array dimension as number.", NULL + }, + { + "dimension_expression", py_array_type_get_dimension_expression, py_array_type_set_dimension_expression, + "Give access to the array dimension as expression.", NULL + }, + { NULL } + }; + + static PyTypeObject py_array_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.ArrayType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide array type", + + .tp_methods = py_array_type_methods, + .tp_getset = py_array_type_getseters, + .tp_new = (newfunc)py_array_type_new + + }; + + return &py_array_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....types.ArrayType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_array_type(PyObject *module) +{ + PyTypeObject *py_array_type_type; /* Type Python 'ArrayType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_array_type_type = get_python_array_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_ARRAY_TYPE, py_array_type_type, get_python_data_type_type())) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/array.h b/plugins/pychrysalide/analysis/types/array.h new file mode 100644 index 0000000..8762548 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/array.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * array.h - prototypes pour l'équivalent Python du fichier "analysis/types/array.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_ARRAY_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_ARRAY_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_array_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.ArrayType'. */ +bool register_python_array_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_ARRAY_H */ diff --git a/plugins/pychrysalide/analysis/types/basic.c b/plugins/pychrysalide/analysis/types/basic.c new file mode 100644 index 0000000..e3bde6e --- /dev/null +++ b/plugins/pychrysalide/analysis/types/basic.c @@ -0,0 +1,250 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * basic.c - équivalent Python du fichier "analysis/types/basic.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "basic.h" + + +#include + + +#include +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'BasicType'. */ +static PyObject *py_basic_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Fournit le type de base géré par le type. */ +static PyObject *py_basic_type_get_base_type(PyObject *, void *); + +/* Définit les constantes pour les types de base. */ +static bool py_basic_type_define_constants(PyTypeObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'BasicType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_basic_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + unsigned long base; /* Type de base à créer */ + int ret; /* Bilan de lecture des args. */ + GDataType *dtype; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "k", &base); + if (!ret) return NULL; + + if (base >= BTP_INVALID) + { + PyErr_SetString(PyExc_TypeError, _("Bad basic type.")); + return NULL; + } + + dtype = g_basic_type_new(base); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type de base géré par le type. * +* * +* Retour : Type basique. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_basic_type_get_base_type(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GBasicType *type; /* Version GLib du type */ + BaseType base; /* Type de base à renvoyer */ + + type = G_BASIC_TYPE(pygobject_get(self)); + + base = g_basic_type_get_base_type(type); + + result = PyLong_FromUnsignedLong(base); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_basic_type_type(void) +{ + static PyMethodDef py_basic_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_basic_type_getseters[] = { + { + "base", py_basic_type_get_base_type, NULL, + "Provide the internal identifier of the basic type.", NULL + }, + { NULL } + }; + + static PyTypeObject py_basic_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.BasicType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide basic type", + + .tp_methods = py_basic_type_methods, + .tp_getset = py_basic_type_getseters, + .tp_new = (newfunc)py_basic_type_new + + }; + + return &py_basic_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes pour les types de base. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_basic_type_define_constants(PyTypeObject *obj_type) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= PyDict_AddIntMacro(obj_type, BTP_VOID); + result &= PyDict_AddIntMacro(obj_type, BTP_WCHAR_T); + result &= PyDict_AddIntMacro(obj_type, BTP_BOOL); + result &= PyDict_AddIntMacro(obj_type, BTP_CHAR); + result &= PyDict_AddIntMacro(obj_type, BTP_SCHAR); + result &= PyDict_AddIntMacro(obj_type, BTP_UCHAR); + result &= PyDict_AddIntMacro(obj_type, BTP_SHORT); + result &= PyDict_AddIntMacro(obj_type, BTP_USHORT); + result &= PyDict_AddIntMacro(obj_type, BTP_INT); + result &= PyDict_AddIntMacro(obj_type, BTP_UINT); + result &= PyDict_AddIntMacro(obj_type, BTP_LONG); + result &= PyDict_AddIntMacro(obj_type, BTP_ULONG); + result &= PyDict_AddIntMacro(obj_type, BTP_LONG_LONG); + result &= PyDict_AddIntMacro(obj_type, BTP_ULONG_LONG); + result &= PyDict_AddIntMacro(obj_type, BTP_INT128); + result &= PyDict_AddIntMacro(obj_type, BTP_UINT128); + result &= PyDict_AddIntMacro(obj_type, BTP_FLOAT); + result &= PyDict_AddIntMacro(obj_type, BTP_DOUBLE); + result &= PyDict_AddIntMacro(obj_type, BTP_LONG_DOUBLE); + result &= PyDict_AddIntMacro(obj_type, BTP_FLOAT128); + result &= PyDict_AddIntMacro(obj_type, BTP_ELLIPSIS); + result &= PyDict_AddIntMacro(obj_type, BTP_754R_64); + result &= PyDict_AddIntMacro(obj_type, BTP_754R_128); + result &= PyDict_AddIntMacro(obj_type, BTP_754R_32); + result &= PyDict_AddIntMacro(obj_type, BTP_754R_16); + result &= PyDict_AddIntMacro(obj_type, BTP_CHAR32_T); + result &= PyDict_AddIntMacro(obj_type, BTP_CHAR16_T); + + result &= PyDict_AddIntMacro(obj_type, BTP_INVALID); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....types.BasicType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_basic_type(PyObject *module) +{ + PyTypeObject *py_basic_type_type; /* Type Python 'BasicType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_basic_type_type = get_python_basic_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_BASIC_TYPE, py_basic_type_type, get_python_data_type_type())) + return false; + + if (!py_basic_type_define_constants(py_basic_type_type)) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/basic.h b/plugins/pychrysalide/analysis/types/basic.h new file mode 100644 index 0000000..ced9312 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/basic.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * basic.h - prototypes pour l'équivalent Python du fichier "analysis/types/basic.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_BASIC_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_BASIC_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_basic_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.BasicType'. */ +bool register_python_basic_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_BASIC_H */ diff --git a/plugins/pychrysalide/analysis/types/cse.c b/plugins/pychrysalide/analysis/types/cse.c new file mode 100644 index 0000000..ff3984f --- /dev/null +++ b/plugins/pychrysalide/analysis/types/cse.c @@ -0,0 +1,269 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * cse.c - équivalent Python du fichier "analysis/types/cse.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "cse.h" + + +#include + + +#include +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'ClassEnumType'. */ +static PyObject *py_class_enum_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Fournit le type pris en compte géré par le type. */ +static PyObject *py_class_enum_type_get_base_type(PyObject *, void *); + +/* Donne la désignation de la classe / structure / énumération. */ +static PyObject *py_class_enum_type_get_name(PyObject *, void *); + +/* Définit les constantes pour les types de classe/énumération. */ +static bool py_class_enum_type_define_constants(PyTypeObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ClassEnumType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_class_enum_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + unsigned long base; /* Type de base à créer */ + const char *name; /* Désignation humaine */ + int ret; /* Bilan de lecture des args. */ + GDataType *dtype; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "ks", &base, &name); + if (!ret) return NULL; + + if (base >= CET_COUNT) + { + PyErr_SetString(PyExc_TypeError, _("Bad basic type.")); + return NULL; + } + + dtype = g_class_enum_type_new(base, strdup(name)); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type pris en compte géré par le type. * +* * +* Retour : Type pris en compte. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_class_enum_type_get_base_type(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GClassEnumType *type; /* Version GLib du type */ + ClassEnumType base; /* Type de base à renvoyer */ + + type = G_CLASS_ENUM_TYPE(pygobject_get(self)); + + base = g_class_enum_type_get_base(type); + + result = PyLong_FromUnsignedLong(base); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Donne la désignation de la classe / structure / énumération. * +* * +* Retour : Chaîne de caractères. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_class_enum_type_get_name(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GClassEnumType *type; /* Version GLib du type */ + const char *name; /* Désignation humaine */ + + type = G_CLASS_ENUM_TYPE(pygobject_get(self)); + + name = g_class_enum_type_get_name(type); + + result = PyUnicode_FromString(name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_class_enum_type_type(void) +{ + static PyMethodDef py_class_enum_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_class_enum_type_getseters[] = { + { + "base", py_class_enum_type_get_base_type, NULL, + "Provide the internal identifier of the type.", NULL + }, + { + "name", py_class_enum_type_get_name, NULL, + "Provide the name of the type.", NULL + }, + { NULL } + }; + + static PyTypeObject py_class_enum_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.ClassEnumType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide basic type", + + .tp_methods = py_class_enum_type_methods, + .tp_getset = py_class_enum_type_getseters, + .tp_new = (newfunc)py_class_enum_type_new + + }; + + return &py_class_enum_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes pour les types de classe/énumération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_class_enum_type_define_constants(PyTypeObject *obj_type) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= PyDict_AddIntMacro(obj_type, CET_UNKNOWN); + result &= PyDict_AddIntMacro(obj_type, CET_STRUCT); + result &= PyDict_AddIntMacro(obj_type, CET_ENUM); + result &= PyDict_AddIntMacro(obj_type, CET_CLASS); + result &= PyDict_AddIntMacro(obj_type, CET_NAMESPACE); + result &= PyDict_AddIntMacro(obj_type, CET_VIRTUAL_TABLE); + result &= PyDict_AddIntMacro(obj_type, CET_VIRTUAL_STRUCT); + + result &= PyDict_AddIntMacro(obj_type, CET_COUNT); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....ClassEnumType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_class_enum_type(PyObject *module) +{ + PyTypeObject *py_class_enum_type_type; /* Type Python 'ClassEnumType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_class_enum_type_type = get_python_class_enum_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_CLASS_ENUM_TYPE, + py_class_enum_type_type, get_python_data_type_type())) + return false; + + if (!py_class_enum_type_define_constants(py_class_enum_type_type)) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/cse.h b/plugins/pychrysalide/analysis/types/cse.h new file mode 100644 index 0000000..26d25d6 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/cse.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * cse.h - prototypes pour l'équivalent Python du fichier "analysis/types/cse.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CSE_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CSE_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_class_enum_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.ClassEnumType'. */ +bool register_python_class_enum_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_CSE_H */ diff --git a/plugins/pychrysalide/analysis/types/encaps.c b/plugins/pychrysalide/analysis/types/encaps.c new file mode 100644 index 0000000..6fa1487 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/encaps.c @@ -0,0 +1,262 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * encaps.c - équivalent Python du fichier "analysis/types/encaps.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "encaps.h" + + +#include + + +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'EncapsulatedType'. */ +static PyObject *py_encapsulated_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Fournit le type encapsulée dans le type. */ +static PyObject *py_encapsulated_type_get_item(PyObject *, void *); + +/* Définit les constantes pour les types d'encapsulation. */ +static bool py_encapsulated_type_define_constants(PyTypeObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'EncapsulatedType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_encapsulated_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + EncapsulationType encapsulation; /* Type d'encapsulation */ + PyObject *encaps_obj; /* Objet du type encapsulé */ + int ret; /* Bilan de lecture des args. */ + GDataType *encapsulated; /* Type encapsulé */ + GDataType *dtype; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "kO!", &encapsulation, get_python_data_type_type(), &encaps_obj); + if (!ret) return NULL; + + encapsulated = G_DATA_TYPE(pygobject_get(encaps_obj)); + + dtype = g_encapsulated_type_new(encapsulation, encapsulated); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type d'encapsulation gérée par le type. * +* * +* Retour : Type d'encapsulation gérée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_encapsulated_type_get_etype(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GEncapsulatedType *type; /* Version GLib du type */ + EncapsulationType encapsulation; /* Type d'encapsulation */ + + type = G_ENCAPSULATED_TYPE(pygobject_get(self)); + + encapsulation = g_encapsulated_type_get_etype(type); + + result = PyLong_FromUnsignedLong(encapsulation); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type encapsulée dans le type. * +* * +* Retour : Sous-type encapsulé dans le type. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_encapsulated_type_get_item(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GEncapsulatedType *type; /* Version GLib du type */ + GDataType *encapsulated; /* Type encapsulé */ + + type = G_ENCAPSULATED_TYPE(pygobject_get(self)); + + encapsulated = g_encapsulated_type_get_item(type); + + result = pygobject_new(G_OBJECT(encapsulated)); + + g_object_unref(encapsulated); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_encapsulated_type_type(void) +{ + static PyMethodDef py_encapsulated_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_encapsulated_type_getseters[] = { + { + "etype", py_encapsulated_type_get_etype, NULL, + "Provide the encapsultion type.", NULL + }, + { + "item", py_encapsulated_type_get_item, NULL, + "Provide the encapsulted type.", NULL + }, + { NULL } + }; + + static PyTypeObject py_encapsulated_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.EncapsulatedType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide encapsulated type", + + .tp_methods = py_encapsulated_type_methods, + .tp_getset = py_encapsulated_type_getseters, + .tp_new = (newfunc)py_encapsulated_type_new + + }; + + return &py_encapsulated_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes pour les types d'encapsulation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_encapsulated_type_define_constants(PyTypeObject *obj_type) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= PyDict_AddIntMacro(obj_type, ECT_POINTER); + result &= PyDict_AddIntMacro(obj_type, ECT_REFERENCE); + result &= PyDict_AddIntMacro(obj_type, ECT_RVALUE_REF); + result &= PyDict_AddIntMacro(obj_type, ECT_COMPLEX); + result &= PyDict_AddIntMacro(obj_type, ECT_IMAGINARY); + + result &= PyDict_AddIntMacro(obj_type, ECT_COUNT); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....EncapsulatedType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_encapsulated_type(PyObject *module) +{ + PyTypeObject *py_encapsulated_type_type;/* Type 'EncapsulatedType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_encapsulated_type_type = get_python_encapsulated_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_ENCAPSULATED_TYPE, + py_encapsulated_type_type, get_python_data_type_type())) + return false; + + if (!py_encapsulated_type_define_constants(py_encapsulated_type_type)) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/encaps.h b/plugins/pychrysalide/analysis/types/encaps.h new file mode 100644 index 0000000..227527e --- /dev/null +++ b/plugins/pychrysalide/analysis/types/encaps.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * encaps.h - prototypes pour l'équivalent Python du fichier "analysis/types/encaps.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_ENCAPS_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_ENCAPS_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_encapsulated_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.EncapsulatedType'. */ +bool register_python_encapsulated_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_ENCAPS_H */ diff --git a/plugins/pychrysalide/analysis/types/expr.c b/plugins/pychrysalide/analysis/types/expr.c new file mode 100644 index 0000000..2988af9 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/expr.c @@ -0,0 +1,185 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * expr.c - équivalent Python du fichier "analysis/types/expr.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "expr.h" + + +#include +#include + + +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'ExprType'. */ +static PyObject *py_expr_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Fournit la valeur d'un type fourni sous forme de caractères. */ +static PyObject *py_expr_type_get_value(PyObject *, void *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ExprType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_expr_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + const char *value; /* Valeur brute de l'expression*/ + int ret; /* Bilan de lecture des args. */ + GDataType *dtype; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "s", &value); + if (!ret) return NULL; + + dtype = g_expr_type_new(strdup(value)); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la valeur d'un type fourni sous forme de caractères. * +* * +* Retour : Chaîne formant une expression. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_expr_type_get_value(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GExprType *type; /* Version GLib du type */ + const char *value; /* Valeur exprimée */ + + type = G_EXPR_TYPE(pygobject_get(self)); + + value = g_expr_type_get_value(type); + + result = PyUnicode_FromString(value); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_expr_type_type(void) +{ + static PyMethodDef py_expr_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_expr_type_getseters[] = { + { + "value", py_expr_type_get_value, NULL, + "Provide the value of the expression type.", NULL + }, + { NULL } + }; + + static PyTypeObject py_expr_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.ExprType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide expr type", + + .tp_methods = py_expr_type_methods, + .tp_getset = py_expr_type_getseters, + .tp_new = (newfunc)py_expr_type_new + + }; + + return &py_expr_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....types.ExprType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_expr_type(PyObject *module) +{ + PyTypeObject *py_expr_type_type; /* Type Python 'ExprType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_expr_type_type = get_python_expr_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_EXPR_TYPE, py_expr_type_type, get_python_data_type_type())) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/expr.h b/plugins/pychrysalide/analysis/types/expr.h new file mode 100644 index 0000000..4764892 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/expr.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * expr.h - prototypes pour l'équivalent Python du fichier "analysis/types/expr.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_EXPR_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_EXPR_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_expr_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.ExprType'. */ +bool register_python_expr_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_EXPR_H */ diff --git a/plugins/pychrysalide/analysis/types/literal.c b/plugins/pychrysalide/analysis/types/literal.c new file mode 100644 index 0000000..7523153 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/literal.c @@ -0,0 +1,135 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * literal.c - équivalent Python du fichier "analysis/types/literal.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "literal.h" + + +#include + + +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'LiteralType'. */ +static PyObject *py_literal_type_new(PyTypeObject *, PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'LiteralType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_literal_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_literal_type_type(void) +{ + static PyMethodDef py_literal_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_literal_type_getseters[] = { + { NULL } + }; + + static PyTypeObject py_literal_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.LiteralType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide literal type", + + .tp_methods = py_literal_type_methods, + .tp_getset = py_literal_type_getseters, + .tp_new = (newfunc)py_literal_type_new + + }; + + return &py_literal_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....types.LiteralType'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_literal_type(PyObject *module) +{ + PyTypeObject *py_literal_type_type; /* Type 'LiteralType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_literal_type_type = get_python_literal_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_LITERAL_TYPE, py_literal_type_type, get_python_data_type_type())) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/literal.h b/plugins/pychrysalide/analysis/types/literal.h new file mode 100644 index 0000000..8340093 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/literal.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * literal.h - prototypes pour l'équivalent Python du fichier "analysis/types/literal.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_LITERAL_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_LITERAL_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_literal_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.LiteralType'. */ +bool register_python_literal_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_LITERAL_H */ diff --git a/plugins/pychrysalide/analysis/types/module.c b/plugins/pychrysalide/analysis/types/module.c new file mode 100644 index 0000000..1566014 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/module.c @@ -0,0 +1,107 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire types en tant que module + * + * Copyright (C) 2014-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "module.h" + + +#include + + +#include "array.h" +#include "basic.h" +#include "cse.h" +#include "encaps.h" +#include "expr.h" +#include "literal.h" +#include "override.h" +#include "proto.h" +#include "template.h" +#include "../../access.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'types' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_analysis_types_module_to_python_module(PyObject *super) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Sous-module mis en place */ + int ret; /* Bilan d'un appel */ + + static PyModuleDef py_chrysalide_types_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.analysis.types", + .m_doc = "Python module for Chrysalide.analysis.types", + + .m_size = -1, + + }; + + result = false; + + module = PyModule_Create(&py_chrysalide_types_module); + if (module == NULL) return false; + + ret = PyState_AddModule(super, &py_chrysalide_types_module); + if (ret != 0) goto loading_failed; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.types"); + if (ret != 0) goto loading_failed; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "types", module); + if (ret != 0) goto loading_failed; + + result = register_python_array_type(module); + if (result) result = register_python_basic_type(module); + if (result) result = register_python_class_enum_type(module); + if (result) result = register_python_expr_type(module); + if (result) result = register_python_encapsulated_type(module); + if (result) result = register_python_literal_type(module); + if (result) result = register_python_override_type(module); + if (result) result = register_python_proto_type(module); + if (result) result = register_python_template_type(module); + + if (result) + register_access_to_python_module("pychrysalide.analysis.types", module); + + loading_failed: + + assert(result); + + return result; + +} diff --git a/plugins/pychrysalide/analysis/types/module.h b/plugins/pychrysalide/analysis/types/module.h new file mode 100644 index 0000000..2c6824d --- /dev/null +++ b/plugins/pychrysalide/analysis/types/module.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire types en tant que module + * + * Copyright (C) 2014-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_MODULE_H + + +#include +#include + + + +/* Ajoute le module 'types' au module Python. */ +bool add_analysis_types_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_MODULE_H */ diff --git a/plugins/pychrysalide/analysis/types/override.c b/plugins/pychrysalide/analysis/types/override.c new file mode 100644 index 0000000..17e32e3 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/override.c @@ -0,0 +1,247 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * override.c - équivalent Python du fichier "analysis/types/override.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "override.h" + + +#include + + +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'OverrideType'. */ +static PyObject *py_override_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Fournit le type de base comportant la fonction virtuelle. */ +static PyObject *py_override_type_get_base(PyObject *, void *); + +/* Fournit les décalages appliquée pour une fonction virtuelle. */ +static PyObject *py_override_type_get_offsets(PyObject *, void *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'OverrideType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_override_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type de base comportant la fonction virtuelle. * +* * +* Retour : Type de base traité. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_override_type_get_base(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GOverrideType *type; /* Version GLib du type */ + GDataType *base; /* Base du type */ + + type = G_OVERRIDE_TYPE(pygobject_get(self)); + + base = g_override_type_get_base(type); + + result = pygobject_new(G_OBJECT(base)); + + g_object_unref(base); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit les décalages appliquée pour une fonction virtuelle. * +* * +* Retour : Liste des décalages. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_override_type_get_offsets(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GOverrideType *type; /* Version GLib du type */ + call_offset_t off0; /* Infos du premier décalage */ + call_offset_t off1; /* Infos du second décalage */ + bool with_covariant; /* Validité du second champ */ + PyObject *offset; /* Transcription intermédiaire */ + + type = G_OVERRIDE_TYPE(pygobject_get(self)); + + with_covariant = g_override_type_get_offsets(type, &off0, &off1);; + + result = PyTuple_New(with_covariant ? 2 : 1); + + if (off0.virtual) + { + offset = PyTuple_New(2); + PyTuple_SetItem(result, 0, PyLong_FromSsize_t(off0.values[0])); + PyTuple_SetItem(result, 1, PyLong_FromSsize_t(off0.values[1])); + } + else + { + offset = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyLong_FromSsize_t(off0.values[0])); + } + + PyTuple_SetItem(result, 0, offset); + + if (with_covariant) + { + if (off1.virtual) + { + offset = PyTuple_New(2); + PyTuple_SetItem(result, 0, PyLong_FromSsize_t(off1.values[0])); + PyTuple_SetItem(result, 1, PyLong_FromSsize_t(off1.values[1])); + } + else + { + offset = PyTuple_New(1); + PyTuple_SetItem(result, 0, PyLong_FromSsize_t(off1.values[0])); + } + + PyTuple_SetItem(result, 1, offset); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_override_type_type(void) +{ + static PyMethodDef py_override_type_methods[] = { + { NULL } + }; + + static PyGetSetDef py_override_type_getseters[] = { + { + "base", py_override_type_get_base, NULL, + "Provide the base of the override type.", NULL + }, + { + "offsets", py_override_type_get_offsets, NULL, + "Provide the offsets of the override type.", NULL + }, + { NULL } + }; + + static PyTypeObject py_override_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.OverrideType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide override type", + + .tp_methods = py_override_type_methods, + .tp_getset = py_override_type_getseters, + .tp_new = (newfunc)py_override_type_new + + }; + + return &py_override_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....OverrideType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_override_type(PyObject *module) +{ + PyTypeObject *py_override_type_type;/* Type 'OverrideType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_override_type_type = get_python_override_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_OVERRIDE_TYPE, + py_override_type_type, get_python_data_type_type())) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/override.h b/plugins/pychrysalide/analysis/types/override.h new file mode 100644 index 0000000..2e874ca --- /dev/null +++ b/plugins/pychrysalide/analysis/types/override.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * override.h - prototypes pour l'équivalent Python du fichier "analysis/types/override.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_OVERRIDE_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_OVERRIDE_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_override_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.OverrideType'. */ +bool register_python_override_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_OVERRIDE_H */ diff --git a/plugins/pychrysalide/analysis/types/proto.c b/plugins/pychrysalide/analysis/types/proto.c new file mode 100644 index 0000000..ac60deb --- /dev/null +++ b/plugins/pychrysalide/analysis/types/proto.c @@ -0,0 +1,314 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * proto.c - équivalent Python du fichier "analysis/types/proto.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "proto.h" + + +#include + + +#include +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'ProtoType'. */ +static PyObject *py_proto_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Ajoute un argument à un prototype. */ +static PyObject *py_proto_type_add_arg(PyObject *, PyObject *); + +/* Fournit le type de retour d'un prototype. */ +static PyObject *py_proto_type_get_return_type(PyObject *, void *); + +/* Définit le type de retour d'un prototype. */ +static int py_proto_type_set_return_type(PyObject *, PyObject *, void *); + +/* Fournit les arguments du prototype. */ +static PyObject *py_proto_type_get_args(PyObject *, void *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ProtoType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_proto_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + GDataType *dtype; /* Version GLib du type */ + + dtype = g_proto_type_new(); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = projet d'étude à manipuler. * +* args = arguments accompagnant l'appel. * +* * +* Description : Ajoute un argument à un prototype. * +* * +* Retour : Py_None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_proto_type_add_arg(PyObject *self, PyObject *args) +{ + PyObject *arg_obj; /* Objet du type d'argument */ + int ret; /* Bilan de lecture des args. */ + GDataType *arg; /* Version GLib du type */ + GProtoType *type; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "O!", get_python_data_type_type(), &arg_obj); + if (!ret) return NULL; + + type = G_PROTO_TYPE(pygobject_get(self)); + + arg = G_DATA_TYPE(pygobject_get(arg_obj)); + + g_object_ref(G_OBJECT(arg)); + g_proto_type_add_arg(type, arg); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit le type de retour d'un prototype. * +* * +* Retour : Indication sur le type de retour en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_proto_type_get_return_type(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GProtoType *type; /* Version GLib du type */ + GDataType *ret; /* Type de retour du prototype */ + + type = G_PROTO_TYPE(pygobject_get(self)); + + ret = g_proto_type_get_return_type(type); + + result = pygobject_new(G_OBJECT(ret)); + + g_object_unref(ret); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Définit le type de retour d'un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_proto_type_set_return_type(PyObject *self, PyObject *value, void *closure) +{ + GProtoType *type; /* Version GLib du type */ + GDataType *ret; /* Type de retour du prototype */ + + if (!PyObject_IsInstance(value, (PyObject *)get_python_data_type_type())) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a GDataType.")); + return -1; + } + + type = G_PROTO_TYPE(pygobject_get(self)); + + ret = G_DATA_TYPE(pygobject_get(value)); + + g_object_ref(ret); + g_proto_type_set_return_type(type, ret); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit les arguments du prototype. * +* * +* Retour : Liste de types d'arguments. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_proto_type_get_args(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GProtoType *type; /* Version GLib du type */ + size_t count; /* Nombre d'arguments */ + size_t i; /* Boucle de parcours */ + GDataType *arg; /* Argument du prototype */ + + type = G_PROTO_TYPE(pygobject_get(self)); + + count = g_proto_type_count_args(type); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + arg = g_proto_type_get_arg(type, i); + + PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(arg))); + + g_object_unref(arg); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_proto_type_type(void) +{ + static PyMethodDef py_proto_type_methods[] = { + { + "add_arg", py_proto_type_add_arg, + METH_VARARGS, + "add_arg($self, type, /)\n--\n\nAdd an extra argument to the prototype." + }, + { NULL } + }; + + static PyGetSetDef py_proto_type_getseters[] = { + { + "return", py_proto_type_get_return_type, py_proto_type_set_return_type, + "Provide the return type of the prototype.", NULL + }, + { + "args", py_proto_type_get_args, NULL, + "Give all arguments of the prototype.", NULL + }, + { NULL } + }; + + static PyTypeObject py_proto_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.ProtoType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide proto type", + + .tp_methods = py_proto_type_methods, + .tp_getset = py_proto_type_getseters, + .tp_new = (newfunc)py_proto_type_new + + }; + + return &py_proto_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....types.ProtoType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_proto_type(PyObject *module) +{ + PyTypeObject *py_proto_type_type; /* Type Python 'ProtoType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_proto_type_type = get_python_proto_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_PROTO_TYPE, py_proto_type_type, get_python_data_type_type())) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/proto.h b/plugins/pychrysalide/analysis/types/proto.h new file mode 100644 index 0000000..4e98df2 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/proto.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * proto.h - prototypes pour l'équivalent Python du fichier "analysis/types/proto.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_PROTO_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_PROTO_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_proto_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.ProtoType'. */ +bool register_python_proto_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_PROTO_H */ diff --git a/plugins/pychrysalide/analysis/types/template.c b/plugins/pychrysalide/analysis/types/template.c new file mode 100644 index 0000000..b8b13fb --- /dev/null +++ b/plugins/pychrysalide/analysis/types/template.c @@ -0,0 +1,311 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * template.c - équivalent Python du fichier "analysis/types/template.c" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "template.h" + + +#include +#include + + +#include +#include + + +#include "../type.h" +#include "../../helpers.h" + + + +/* Crée un nouvel objet Python de type 'TemplateType'. */ +static PyObject *py_template_type_new(PyTypeObject *, PyObject *, PyObject *); + +/* Ajoute un paramètre à un gabarit. */ +static PyObject *py_template_type_add_param(PyObject *, PyObject *); + +/* Indique la désignation principale du type. */ +static PyObject *py_template_type_get_name(PyObject *, void *); + +/* Précise la désignation principale du type. */ +static int py_template_type_set_name(PyObject *, PyObject *, void *); + +/* Fournit les arguments du gabarit. */ +static PyObject *py_template_type_get_params(PyObject *, void *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'TemplateType'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_template_type_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + GDataType *dtype; /* Version GLib du type */ + + dtype = g_template_type_new(); + result = pygobject_new(G_OBJECT(dtype)); + g_object_unref(dtype); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = projet d'étude à manipuler. * +* args = arguments accompagnant l'appel. * +* * +* Description : Ajoute un paramètre à un gabarit. * +* * +* Retour : Py_None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_template_type_add_param(PyObject *self, PyObject *args) +{ + PyObject *param_obj; /* Objet du type de paramètre */ + int ret; /* Bilan de lecture des args. */ + GDataType *param; /* Version GLib du type */ + GTemplateType *type; /* Version GLib du type */ + + ret = PyArg_ParseTuple(args, "O!", get_python_data_type_type(), ¶m_obj); + if (!ret) return NULL; + + type = G_TEMPLATE_TYPE(pygobject_get(self)); + + param = G_DATA_TYPE(pygobject_get(param_obj)); + + g_object_ref(G_OBJECT(param)); + g_template_type_add_param(type, param); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique la désignation principale du type. * +* * +* Retour : Désignation humaine du type. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_template_type_get_name(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GTemplateType *type; /* Version GLib du type */ + const char *name; /* Désignation humaine */ + + type = G_TEMPLATE_TYPE(pygobject_get(self)); + + name = g_template_type_get_name(type); + + result = PyUnicode_FromString(name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* value = valeur fournie à intégrer ou prendre en compte. * +* closure = non utilisé ici. * +* * +* Description : Précise la désignation principale du type. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_template_type_set_name(PyObject *self, PyObject *value, void *closure) +{ + GTemplateType *type; /* Version GLib du type */ + + if (!PyUnicode_Check(value)) + { + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string.")); + return -1; + } + + type = G_TEMPLATE_TYPE(pygobject_get(self)); + + g_template_type_set_name(type, strdup(PyUnicode_DATA(value))); + + return 0; + +} + + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit les arguments du gabarit. * +* * +* Retour : Liste de types de paramètres. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_template_type_get_params(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GTemplateType *type; /* Version GLib du type */ + size_t count; /* Nombre de paramètres */ + size_t i; /* Boucle de parcours */ + GDataType *param; /* Paramètre du gabarit */ + + type = G_TEMPLATE_TYPE(pygobject_get(self)); + + count = g_template_type_count_params(type); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + param = g_template_type_get_param(type, i); + + PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(param))); + + g_object_unref(param); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_template_type_type(void) +{ + static PyMethodDef py_template_type_methods[] = { + { + "add_param", py_template_type_add_param, + METH_VARARGS, + "add_param($self, type, /)\n--\n\nAdd an extra parameter to the template type." + }, + { NULL } + }; + + static PyGetSetDef py_template_type_getseters[] = { + { + "name", py_template_type_get_name, py_template_type_set_name, + "Give access to the name of the template type.", NULL + }, + { + "params", py_template_type_get_params, NULL, + "Give all parameters of the template type.", NULL + }, + { NULL } + }; + + static PyTypeObject py_template_type_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.analysis.types.TemplateType", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide template type", + + .tp_methods = py_template_type_methods, + .tp_getset = py_template_type_getseters, + .tp_new = (newfunc)py_template_type_new + + }; + + return &py_template_type_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.....TemplateType'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_template_type(PyObject *module) +{ + PyTypeObject *py_template_type_type; /* Type Python 'TemplateType' */ + PyObject *dict; /* Dictionnaire du module */ + + py_template_type_type = get_python_template_type_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_TEMPLATE_TYPE, + py_template_type_type, get_python_data_type_type())) + return false; + + return true; + +} diff --git a/plugins/pychrysalide/analysis/types/template.h b/plugins/pychrysalide/analysis/types/template.h new file mode 100644 index 0000000..d5665e1 --- /dev/null +++ b/plugins/pychrysalide/analysis/types/template.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * template.h - templatetypes pour l'équivalent Python du fichier "analysis/types/template.h" + * + * Copyright (C) 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_TEMPLATE_H +#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_TEMPLATE_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_template_type_type(void); + +/* Prend en charge l'objet 'pychrysalide.analysis.types.TemplateType'. */ +bool register_python_template_type(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_TYPES_TEMPLATE_H */ diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 6e56e2d..08160b8 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -183,7 +183,7 @@ GBinRoutine *g_binary_routine_new_constructor(GDataType *type) result = g_object_new(G_TYPE_BIN_ROUTINE, NULL); - g_binary_routine_set_name(result, _g_data_type_to_string(type, true)); + g_binary_routine_set_name(result, g_data_type_to_string(type, true)); return result; @@ -257,6 +257,9 @@ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, const char *sep) { + if (routine->namespace != NULL) + g_object_unref(G_OBJECT(routine->namespace)); + routine->namespace = namespace; routine->ns_sep = sep; @@ -267,11 +270,11 @@ void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, /****************************************************************************** * * -* Paramètres : routine = routine à mettre à jour. * +* Paramètres : routine = routine à consulter. * * * * Description : Fournit le groupe d'appartenance d'une routine donnée. * * * -* Retour : éventuelle instance d'appartenance ou NULL. * +* Retour : Eventuelle instance d'appartenance ou NULL. * * * * Remarques : - * * * @@ -279,7 +282,14 @@ void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, GDataType *g_binary_routine_get_namespace(const GBinRoutine *routine) { - return routine->namespace; + GDataType *result; /* Espace à renvoyer */ + + result = routine->namespace; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } @@ -375,7 +385,7 @@ GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *routine) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* type = indication sur le type de retour. * +* ret = indication sur le type de retour. * * * * Description : Définit le type de retour d'une routine. * * * @@ -385,15 +395,12 @@ GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *routine) * * ******************************************************************************/ -void g_binary_routine_set_return_type(GBinRoutine *routine, GDataType *type) +void g_binary_routine_set_return_type(GBinRoutine *routine, GDataType *ret) { if (routine->ret_type != NULL) g_object_unref(G_OBJECT(routine->ret_type)); - routine->ret_type = type; - - if (type != NULL) - g_object_ref(G_OBJECT(type)); + routine->ret_type = ret; } @@ -412,7 +419,14 @@ void g_binary_routine_set_return_type(GBinRoutine *routine, GDataType *type) GDataType *g_binary_routine_get_return_type(const GBinRoutine *routine) { - return routine->ret_type; + GDataType *result; /* Type de retour à renvoyer */ + + result = routine->ret_type; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } @@ -544,7 +558,7 @@ static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* full = indique si la liste des arguments est à ajouter. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Fournit le nom humain d'une routine. * * * @@ -554,7 +568,7 @@ static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full) * * ******************************************************************************/ -const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) +const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool include) { char *new; /* Nouvelle description */ char *namespace; /* Groupe d'appartenance */ @@ -564,13 +578,13 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) if (routine->cached_decl == NULL) { if (routine->full_name != NULL) - new = _g_data_type_to_string(routine->full_name, false); + new = g_data_type_to_string(routine->full_name, include); else new = strdup(routine->name != NULL ? routine->name : ""); if (routine->namespace != NULL) { - namespace = _g_data_type_to_string(routine->namespace, false); + namespace = g_data_type_to_string(routine->namespace, include); new = strprep(new, routine->ns_sep); new = strprep(new, namespace); @@ -585,7 +599,7 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) } - if (full && routine->cached_full_decl == NULL) + if (include && routine->cached_full_decl == NULL) { /* Type de retour */ @@ -593,9 +607,11 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) new = strdup("??? "); else { - new = _g_data_type_to_string(routine->ret_type, true); - if (!g_data_type_is_pointer(routine->ret_type, true)) + new = g_data_type_to_string(routine->ret_type, include); + + if (!(g_data_type_is_pointer(routine->ret_type) || g_data_type_is_reference(routine->ret_type))) new = stradd(new, " "); + } /* Nom de la routine */ @@ -610,7 +626,7 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) { if (i > 0) new = stradd(new, ", "); - typestr = g_binary_variable_to_string(routine->args[i], true); + typestr = g_binary_variable_to_string(routine->args[i], include); new = stradd(new, typestr); free(typestr); @@ -624,7 +640,7 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) } - return (full ? routine->cached_full_decl : routine->cached_decl); + return (include ? routine->cached_full_decl : routine->cached_decl); } @@ -844,6 +860,7 @@ void g_binary_routine_set_decomp_instructions(GBinRoutine *routine, GDecInstruct /****************************************************************************** * * * Paramètres : routine = routine à consulter. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le prototype de la routine sous forme de caractères. * * * @@ -853,7 +870,7 @@ void g_binary_routine_set_decomp_instructions(GBinRoutine *routine, GDecInstruct * * ******************************************************************************/ -char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOptions options) +char *g_binary_routine_to_string(const GBinRoutine *routine, bool include) { char *result; /* Chaîne à renvoyer */ char *namespace; /* Groupe d'appartenance */ @@ -880,9 +897,11 @@ char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOpti if (routine->ret_type == NULL) result = strdup("??? "); else { - result = _g_data_type_to_string(routine->ret_type, !(options & RSO_LONG_TYPE)); - if (!g_data_type_is_pointer(routine->ret_type, true)) + result = g_data_type_to_string(routine->ret_type, include); + + if (!(g_data_type_is_pointer(routine->ret_type) || g_data_type_is_reference(routine->ret_type))) result = stradd(result, " "); + } break; @@ -890,12 +909,12 @@ char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOpti /* Nom de la routine */ - if (options & RSO_NAMESPACE && routine->namespace != NULL) + if (routine->namespace != NULL) { - namespace = g_data_type_to_string(routine->namespace); + namespace = g_data_type_to_string(routine->namespace, include); result = stradd(result, namespace); - result = stradd(result, "." /* FIXME */); + result = stradd(result, routine->ns_sep); free(namespace); @@ -914,7 +933,7 @@ char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOpti { if (i > 0) result = stradd(result, ", "); - typestr = g_binary_variable_to_string(routine->args[i], !(options & RSO_LONG_TYPE)); + typestr = g_binary_variable_to_string(routine->args[i], include); result = stradd(result, typestr); free(typestr); diff --git a/src/analysis/routine.h b/src/analysis/routine.h index e364c93..e1a3523 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -62,17 +62,6 @@ typedef struct _GBinRoutine GBinRoutine; typedef struct _GBinRoutineClass GBinRoutineClass; -/* Modalités de représentation en chaîne */ -typedef enum _Routine2StringOptions -{ - RSO_LONG_TYPE = (1 << 0), /* Type avec espace de noms */ - RSO_NAMESPACE = (1 << 1) /* Affichage de l'appartenance */ - -} Routine2StringOptions; - -#define RSO_ALL (RSO_LONG_TYPE | RSO_NAMESPACE) - - /* Indique le type définit pour une représentation de routine. */ GType g_bin_routine_get_type(void); @@ -143,9 +132,7 @@ void g_binary_routine_set_basic_blocks(GBinRoutine *, GBlockList *); //void g_binary_routine_set_decomp_instructions(GBinRoutine *, GDecInstruction *); /* Décrit le prototype de la routine sous forme de caractères. */ -char *_g_binary_routine_to_string(const GBinRoutine *, Routine2StringOptions); - -#define g_binary_routine_to_string(r) _g_binary_routine_to_string((r), RSO_ALL) +char *g_binary_routine_to_string(const GBinRoutine *, bool); /* Procède à l'impression de la description d'une routine. */ //void g_binary_routine_output_info(const GBinRoutine *, GLangOutput *, GCodeBuffer *); diff --git a/src/analysis/type-int.h b/src/analysis/type-int.h index 51e4954..3c34680 100644 --- a/src/analysis/type-int.h +++ b/src/analysis/type-int.h @@ -33,10 +33,14 @@ typedef GDataType * (* type_dup_fc) (const GDataType *); /* Décrit le type fourni sous forme de caractères. */ -typedef char * (* type_to_string_fc) (const GDataType *); +typedef char * (* type_to_string_fc) (const GDataType *, bool); + +/* Indique si le type est un pointeur. */ +typedef bool (* type_is_pointer_fc) (const GDataType *); + +/* Indique si le type est une référence. */ +typedef bool (* type_is_reference_fc) (const GDataType *); -/* Procède à l'impression de la description d'un type. */ -//typedef void (* output_type_fc) (const GDataType *, GLangOutput *, GBufferLine *, bool, bool); /* Description de type quelconque (instance) */ @@ -44,11 +48,9 @@ struct _GDataType { GObject parent; /* A laisser en premier */ - type_dup_fc dup; /* Copie d'instance existante */ - type_to_string_fc to_string; /* Conversion au format texte */ - //output_type_fc output; /* Impression à l'écran */ - GDataType *namespace; /* Espace de noms / classe */ + const char *ns_sep; /* Séparateur d'éléments */ + TypeQualifier qualifiers; /* Eventuels qualificatifs */ }; @@ -58,6 +60,14 @@ struct _GDataTypeClass { GObjectClass parent; /* A laisser en premier */ + bool handle_ns; /* Gestion au niveau de base ? */ + + type_dup_fc dup; /* Copie d'instance existante */ + type_to_string_fc to_string; /* Conversion au format texte */ + + type_is_pointer_fc is_pointer; /* Représentation de pointeur ?*/ + type_is_reference_fc is_reference; /* Représentation de référence?*/ + }; diff --git a/src/analysis/type.c b/src/analysis/type.c index 6d09f4b..cc446cb 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -24,29 +24,26 @@ #include "type.h" -#include +#include -#include "routine.h" #include "type-int.h" #include "../common/extstr.h" -/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */ - - /* Initialise la classe des types quelconques. */ static void g_data_type_class_init(GDataTypeClass *); /* Initialise l'instance d'un type quelconque. */ static void g_data_type_init(GDataType *); +/* Supprime toutes les références externes. */ +static void g_data_type_dispose(GDataType *); +/* Procède à la libération totale de la mémoire. */ +static void g_data_type_finalize(GDataType *); -/* ---------------------------------------------------------------------------------- */ -/* REPRESENTATION INTERNE DES TYPES */ -/* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour un type quelconque. */ @@ -67,6 +64,14 @@ G_DEFINE_TYPE(GDataType, g_data_type, G_TYPE_OBJECT); static void g_data_type_class_init(GDataTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_data_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_data_type_finalize; + + klass->handle_ns = true; } @@ -91,29 +96,31 @@ static void g_data_type_init(GDataType *type) /****************************************************************************** * * -* Paramètres : type = type à dupliquer. * +* Paramètres : type = instance d'objet GLib à traiter. * * * -* Description : Crée un copie d'un type existant. * +* Description : Supprime toutes les références externes. * * * -* Retour : Nouvelle instance de type identique à celle fournie. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GDataType *g_data_type_dup(const GDataType *type) +static void g_data_type_dispose(GDataType *type) { - return type->dup(type); + if (type->namespace != NULL) + g_object_unref(G_OBJECT(type->namespace)); + + G_OBJECT_CLASS(g_data_type_parent_class)->dispose(G_OBJECT(type)); } /****************************************************************************** * * -* Paramètres : type = type à mettre à jour. * -* namespace = instance d'appartenance. * +* Paramètres : type = instance d'objet GLib à traiter. * * * -* Description : Définit le groupe d'appartenance d'un type donné. * +* Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * @@ -121,19 +128,52 @@ GDataType *g_data_type_dup(const GDataType *type) * * ******************************************************************************/ -void g_data_type_set_namespace(GDataType *type, GDataType *namespace) +static void g_data_type_finalize(GDataType *type) { - g_object_ref(G_OBJECT(namespace)); + G_OBJECT_CLASS(g_data_type_parent_class)->finalize(G_OBJECT(type)); - type->namespace = namespace; +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_data_type_dup(const GDataType *type) +{ + GDataType *result; /* Copie à retourner */ + GDataTypeClass *class; /* Classe du type */ + GDataType *ns; /* Eventuel espace de noms */ + + class = G_DATA_TYPE_GET_CLASS(type); + + result = class->dup(type); + + if (type->namespace != NULL) + { + ns = g_data_type_dup(type->namespace); + g_data_type_set_namespace(result, ns, type->ns_sep); + } + + result->qualifiers = type->qualifiers; + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * -* simple = indique si l'espace de noms doit être exclus ou non.* +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -143,25 +183,26 @@ void g_data_type_set_namespace(GDataType *type, GDataType *namespace) * * ******************************************************************************/ -char *_g_data_type_to_string(const GDataType *type, bool simple) +char *g_data_type_to_string(const GDataType *type, bool include) { char *result; /* Chaîne à retourner */ - const GDataType *parent; /* Espace supérieur */ + GDataTypeClass *class; /* Classe du type */ char *namespace; /* Groupe d'appartenance */ - result = type->to_string(type); + class = G_DATA_TYPE_GET_CLASS(type); + + result = class->to_string(type, include); - if (!simple) - for (parent = type->namespace; parent != NULL; parent = parent->namespace) - { - namespace = g_data_type_to_string(parent); + if (include && type->namespace != NULL && class->handle_ns) + { + namespace = g_data_type_to_string(type->namespace, true); - result = strprep(result, "." /* FIXME */); - result = strprep(result, namespace); + result = strprep(result, type->ns_sep); + result = strprep(result, namespace); - free(namespace); + free(namespace); - } + } if (type->qualifiers & TQF_RESTRICT) result = strprep(result, "restrict "); @@ -179,26 +220,53 @@ char *_g_data_type_to_string(const GDataType *type, bool simple) /****************************************************************************** * * -* Paramètres : type = routine à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à mettre à jour. * +* namespace = instance d'appartenance. * +* sep = séparateur à utiliser entre les éléments. * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Définit le groupe d'appartenance d'un type donné. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ -/* -void g_data_type_output(const GDataType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +void g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char *sep) { - type->output(type, lang, line, info, full); + if (type->namespace != NULL) + g_object_unref(G_OBJECT(type->namespace)); + + type->namespace = namespace; + type->ns_sep = sep; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le groupe d'appartenance d'un type donné. * +* * +* Retour : Eventuelle instance d'appartenance ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_data_type_get_namespace(const GDataType *type) +{ + GDataType *result; /* Espace à renvoyer */ + + result = type->namespace; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } -*/ /****************************************************************************** @@ -223,37 +291,56 @@ void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) /****************************************************************************** * * -* Paramètres : type = type à analyser. * -* large = doit-on aussi inclure les types 'référence' ? * +* Paramètres : type = type à consulter. * * * -* Description : Indique la terminaison de la représentation du type. * +* Description : Indique si le type est un pointeur. * * * -* Retour : true ou false, selon le type fourni. * +* Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ -bool g_data_type_is_pointer(const GDataType *type, bool large) +bool g_data_type_is_pointer(const GDataType *type) { bool result; /* Bilan à retourner */ + GDataTypeClass *class; /* Classe du type */ + + class = G_DATA_TYPE_GET_CLASS(type); + + if (class->is_pointer != NULL) + result = class->is_pointer(type); + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique si le type est une référence. * +* * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_data_type_is_reference(const GDataType *type) +{ + bool result; /* Bilan à retourner */ + GDataTypeClass *class; /* Classe du type */ + + class = G_DATA_TYPE_GET_CLASS(type); - result = G_IS_ENCAPSULATED_TYPE(type); - - if (result) - switch (g_encapsulated_type_get_etype(G_ENCAPSULATED_TYPE(type))) - { - case ECT_POINTER: - result = true; - break; - case ECT_REFERENCE: - case ECT_RVALUE_REF: - result = large; - break; - default: - result = false; - break; - } + if (class->is_reference != NULL) + result = class->is_reference(type); + else + result = false; return result; diff --git a/src/analysis/type.h b/src/analysis/type.h index 1ea1b2f..bd80f18 100644 --- a/src/analysis/type.h +++ b/src/analysis/type.h @@ -25,18 +25,10 @@ #define _ANALYSIS_TYPE_H -#include #include #include -#include "../arch/archbase.h" -#include "../glibext/gbufferline.h" - - - -/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */ - #define G_TYPE_DATA_TYPE g_data_type_get_type() #define G_DATA_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DATA_TYPE, GDataType)) @@ -70,22 +62,23 @@ GType g_data_type_get_type(void); /* Crée un copie d'un type existant. */ GDataType *g_data_type_dup(const GDataType *); -/* Définit le groupe d'appartenance d'un type donné. */ -void g_data_type_set_namespace(GDataType *, GDataType *); - /* Décrit le type fourni sous forme de caractères. */ -char *_g_data_type_to_string(const GDataType *, bool); +char *g_data_type_to_string(const GDataType *, bool); + +/* Définit le groupe d'appartenance d'un type donné. */ +void g_data_type_set_namespace(GDataType *, GDataType *, const char *); -#define g_data_type_to_string(t) _g_data_type_to_string((t), true) +/* Fournit le groupe d'appartenance d'un type donné. */ +GDataType *g_data_type_get_namespace(const GDataType *); /* Ajoute un qualificatif à une instance de type. */ void g_data_type_add_qualifier(GDataType *, TypeQualifier); -/* Indique la terminaison de la représentation du type. */ -bool g_data_type_is_pointer(const GDataType *, bool); +/* Indique si le type est un pointeur. */ +bool g_data_type_is_pointer(const GDataType *); -/* Procède à l'impression de la description d'un type. */ -//void g_data_type_output(const GDataType *, GLangOutput *, GBufferLine *, bool, bool); +/* Indique si le type est une référence. */ +bool g_data_type_is_reference(const GDataType *); diff --git a/src/analysis/types/Makefile.am b/src/analysis/types/Makefile.am index 13215f2..2d11642 100644 --- a/src/analysis/types/Makefile.am +++ b/src/analysis/types/Makefile.am @@ -2,11 +2,14 @@ noinst_LTLIBRARIES = libanalysistypes.la libanalysistypes_la_SOURCES = \ + array.h array.c \ basic.h basic.c \ - cse-int.h \ cse.h cse.c \ encaps.h encaps.c \ + expr.h expr.c \ literal.h literal.c \ + override.h override.c \ + proto.h proto.c \ template.h template.c libanalysistypes_la_LIBADD = diff --git a/src/analysis/types/array.c b/src/analysis/types/array.c new file mode 100644 index 0000000..714ab58 --- /dev/null +++ b/src/analysis/types/array.c @@ -0,0 +1,429 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * array.c - manipulation des types de tableaux + * + * Copyright (C) 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 "array.h" + + +#include +#include +#include + + +#include "../type-int.h" +#include "../../common/extstr.h" + + + +/* Description de tableau (instance) */ +struct _GArrayType +{ + GDataType parent; /* A laisser en premier */ + + bool numbered; /* Dimension chiffrée ? */ + + union + { + ssize_t dim_number; /* Taille en chiffre */ + char *dim_expr; /* Taille via expression */ + + }; + + GDataType *members; /* Type des membres */ + +}; + +/* Description de tableau (classe) */ +struct _GArrayTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des tableaux. */ +static void g_array_type_class_init(GArrayTypeClass *); + +/* Initialise l'instance d'un tableau. */ +static void g_array_type_init(GArrayType *); + +/* Supprime toutes les références externes. */ +static void g_array_type_dispose(GArrayType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_array_type_finalize(GArrayType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_array_type_dup(const GArrayType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_array_type_to_string(const GArrayType *, bool); + + + +/* Indique le type défini pour un tableau. */ +G_DEFINE_TYPE(GArrayType, g_array_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des tableaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_class_init(GArrayTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_array_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_array_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_array_type_dup; + type->to_string = (type_to_string_fc)g_array_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'un tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_init(GArrayType *type) +{ + type->numbered = true; + + type->dim_number = -1; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_dispose(GArrayType *type) +{ + if (type->members != NULL) + g_object_unref(G_OBJECT(type->members)); + + G_OBJECT_CLASS(g_array_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_finalize(GArrayType *type) +{ + if (!type->numbered && type->dim_expr != NULL) + free(type->dim_expr); + + G_OBJECT_CLASS(g_array_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : members = type des membres du tableau. * +* * +* Description : Crée une représentation de tableau. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_array_type_new(GDataType *members) +{ + GArrayType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARRAY_TYPE, NULL); + + result->members = members; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_array_type_dup(const GArrayType *type) +{ + GDataType *result; /* Nouvelle instance à renvoyer*/ + GDataType *members; /* Copie du type interne */ + + members = g_data_type_dup(type->members); + result = g_array_type_new(members); + + if (type->numbered) + g_array_type_set_dimension_number(G_ARRAY_TYPE(result), type->dim_number); + + else if (type->dim_expr != NULL) + g_array_type_set_dimension_expression(G_ARRAY_TYPE(result), strdup(type->dim_expr)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_array_type_to_string(const GArrayType *type, bool include) +{ + char *result; /* Chaîne finale à renvoyer */ + char *tmp; /* Transcription temporaire */ + + result = g_data_type_to_string(type->members, include); + if (result == NULL) goto exit; + + result = stradd(result, "["); + + if (type->numbered) + { + if (type->dim_number != -1) + { + asprintf(&tmp, "%zd", type->dim_number); + result = stradd(result, tmp); + free(tmp); + } + } + + else + result = stradd(result, type->dim_expr); + + result = stradd(result, "]"); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le type des membres du tableau. * +* * +* Retour : Instance d'un autre type. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_array_type_get_members_type(const GArrayType *type) +{ + GDataType *result; /* Type à retourner */ + + result = type->members; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique si la dimension du tableau est chiffrée. * +* * +* Retour : true si la dimension est chiffrée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_array_type_is_dimension_numbered(const GArrayType *type) +{ + bool result; /* Etat à retourner */ + + result = type->numbered; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Dimension positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ssize_t g_array_type_get_dimension_number(const GArrayType *type) +{ + ssize_t result; /* Taille à retourner */ + + assert(type->numbered); + + result = (type->numbered ? type->dim_number : 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* dim = dimension positive ou nulle. * +* * +* Description : Définit la dimension associée au tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_array_type_set_dimension_number(GArrayType *type, ssize_t dim) +{ + if (!type->numbered && type->dim_expr != NULL) + free(type->dim_expr); + + type->numbered = true; + + type->dim_number = dim; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Expression de dimension. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_array_type_get_dimension_expression(const GArrayType *type) +{ + char *result; /* Expression à retourner */ + + assert(!type->numbered); + + result = (type->numbered ? NULL : type->dim_expr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* expr = expression de dimension. * +* * +* Description : Définit la dimension associée au tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_array_type_set_dimension_expression(GArrayType *type, char *expr) +{ + if (!type->numbered && type->dim_expr != NULL) + free(type->dim_expr); + + type->numbered = false; + + type->dim_expr = expr; + +} diff --git a/src/analysis/types/array.h b/src/analysis/types/array.h new file mode 100644 index 0000000..d432c22 --- /dev/null +++ b/src/analysis/types/array.h @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * array.h - prototypes pour la manipulation des types de tableaux + * + * Copyright (C) 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 . + */ + + +#ifndef _ANALYSIS_TYPES_ARRAY_H +#define _ANALYSIS_TYPES_ARRAY_H + + +#include + + +#include "../type.h" + + + +#define G_TYPE_ARRAY_TYPE g_array_type_get_type() +#define G_ARRAY_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARRAY_TYPE, GArrayType)) +#define G_IS_ARRAY_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARRAY_TYPE)) +#define G_ARRAY_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARRAY_TYPE, GArrayTypeClass)) +#define G_IS_ARRAY_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARRAY_TYPE)) +#define G_ARRAY_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARRAY_TYPE, GArrayTypeClass)) + + +/* Description de tableau (instance) */ +typedef struct _GArrayType GArrayType; + +/* Description de tableau (classe) */ +typedef struct _GArrayTypeClass GArrayTypeClass; + + +/* Indique le type défini pour un tableau. */ +GType g_array_type_get_type(void); + +/* Crée une représentation de tableau. */ +GDataType *g_array_type_new(GDataType *); + +/* Fournit le type des membres du tableau. */ +GDataType *g_array_type_get_members_type(const GArrayType *); + +/* Indique si la dimension du tableau est chiffrée. */ +bool g_array_type_is_dimension_numbered(const GArrayType *); + +/* Fournit la dimension associée au tableau. */ +ssize_t g_array_type_get_dimension_number(const GArrayType *); + +/* Définit la dimension associée au tableau. */ +void g_array_type_set_dimension_number(GArrayType *, ssize_t); + +/* Fournit la dimension associée au tableau. */ +const char *g_array_type_get_dimension_expression(const GArrayType *); + +/* Définit la dimension associée au tableau. */ +void g_array_type_set_dimension_expression(GArrayType *, char *); + + + +#endif /* _ANALYSIS_TYPES_ARRAY_H */ diff --git a/src/analysis/types/basic.c b/src/analysis/types/basic.c index 9e0239a..4ac7f2a 100644 --- a/src/analysis/types/basic.c +++ b/src/analysis/types/basic.c @@ -24,7 +24,7 @@ #include "basic.h" -#include +#include #include @@ -55,14 +55,17 @@ static void g_basic_type_class_init(GBasicTypeClass *); /* Initialise l'instance d'un type basique. */ static void g_basic_type_init(GBasicType *); +/* Supprime toutes les références externes. */ +static void g_basic_type_dispose(GBasicType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_basic_type_finalize(GBasicType *); + /* Crée un copie d'un type existant. */ static GDataType *g_basic_type_dup(const GBasicType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_basic_type_to_string(const GBasicType *); - -/* Procède à l'impression de la description d'un type. */ -//static void g_basic_type_output(const GBasicType *, GLangOutput *, GBufferLine *, bool, bool); +static char *g_basic_type_to_string(const GBasicType *, bool); @@ -84,6 +87,18 @@ G_DEFINE_TYPE(GBasicType, g_basic_type, G_TYPE_DATA_TYPE); static void g_basic_type_class_init(GBasicTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_basic_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_basic_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_basic_type_dup; + type->to_string = (type_to_string_fc)g_basic_type_to_string; } @@ -102,13 +117,45 @@ static void g_basic_type_class_init(GBasicTypeClass *klass) static void g_basic_type_init(GBasicType *type) { - GDataType *data_type; /* Version basique */ + type->type = BTP_INVALID; - data_type = G_DATA_TYPE(type); +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_basic_type_dispose(GBasicType *type) +{ + G_OBJECT_CLASS(g_basic_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - data_type->dup = (type_dup_fc)g_basic_type_dup; - data_type->to_string = (type_to_string_fc)g_basic_type_to_string; - //data_type->output = (output_type_fc)g_basic_type_output; +static void g_basic_type_finalize(GBasicType *type) +{ + G_OBJECT_CLASS(g_basic_type_parent_class)->finalize(G_OBJECT(type)); } @@ -152,14 +199,19 @@ GDataType *g_basic_type_new(BaseType type) static GDataType *g_basic_type_dup(const GBasicType *type) { - return g_basic_type_new(type->type); + GDataType *result; /* Copie à retourner */ + + result = g_basic_type_new(type->type); + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -169,7 +221,7 @@ static GDataType *g_basic_type_dup(const GBasicType *type) * * ******************************************************************************/ -static char *g_basic_type_to_string(const GBasicType *type) +static char *g_basic_type_to_string(const GBasicType *type, bool include) { const char *desc; /* Représentation à copier */ @@ -284,47 +336,15 @@ static char *g_basic_type_to_string(const GBasicType *type) break; default: - case BTP_OTHER: - desc = "user"; + assert(false); + desc = NULL; break; } - return strdup(desc); - -} - - -/****************************************************************************** -* * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * -* * -* Description : Procède à l'impression de la description d'un type. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -static void g_basic_type_output(const GBasicType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) -{ - char *text; /* Version humaine à imprimer */ - size_t len; /* Taille de cette version */ - - text = g_basic_type_to_string(type); - len = strlen(text); - - g_buffer_line_append_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW, NULL); - - free(text); + return (desc != NULL ? strdup(desc) : NULL); } -#endif /****************************************************************************** @@ -339,7 +359,7 @@ static void g_basic_type_output(const GBasicType *type, GLangOutput *lang, GBuff * * ******************************************************************************/ -BaseType g_basic_type_get_btype(const GBasicType *type) +BaseType g_basic_type_get_base_type(const GBasicType *type) { return type->type; diff --git a/src/analysis/types/basic.h b/src/analysis/types/basic.h index 6dba6ae..29d14b1 100644 --- a/src/analysis/types/basic.h +++ b/src/analysis/types/basic.h @@ -62,19 +62,18 @@ typedef enum _BaseType BTP_754R_16, /* IEEE 754r float (16 bits) */ BTP_CHAR32_T, /* char32_t */ BTP_CHAR16_T, /* char16_t */ - BTP_OTHER, /* Extension utilisateur */ BTP_INVALID } BaseType; -#define G_TYPE_BASIC_TYPE g_basic_type_get_type() -#define G_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_basic_type_get_type(), GBasicType)) -#define G_IS_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_basic_type_get_type())) -#define G_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_TYPE, GBasicTypeClass)) -#define G_IS_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_TYPE)) -#define G_BASIC_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_TYPE, GBasicTypeClass)) +#define G_TYPE_BASIC_TYPE g_basic_type_get_type() +#define G_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BASIC_TYPE, GBasicType)) +#define G_IS_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BASIC_TYPE)) +#define G_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_TYPE, GBasicTypeClass)) +#define G_IS_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_TYPE)) +#define G_BASIC_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_TYPE, GBasicTypeClass)) /* Description de type basique (instance) */ @@ -91,7 +90,7 @@ GType g_basic_type_get_type(void); GDataType *g_basic_type_new(BaseType); /* Fournit le type de base géré par le type. */ -BaseType g_basic_type_get_btype(const GBasicType *); +BaseType g_basic_type_get_base_type(const GBasicType *); diff --git a/src/analysis/types/cse-int.h b/src/analysis/types/cse-int.h deleted file mode 100644 index 0272435..0000000 --- a/src/analysis/types/cse-int.h +++ /dev/null @@ -1,59 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * cse-int.h - prototypes pour la définition interne des types classes / structures / énumérations - * - * Copyright (C) 2012-2017 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 . - */ - - -#ifndef _ANALYSIS_TYPES_CSE_INT_H -#define _ANALYSIS_TYPES_CSE_INT_H - - -#include "cse.h" -#include "../type-int.h" - - - -/* Description de type classe/structure et enumeration (instance) */ -struct _GClassEnumType -{ - GDataType parent; /* A laisser en premier */ - - ClassEnumType type; /* Type représenté si connu */ - char *name; /* Description humaine */ - -}; - -/* Description de type classe/structure et enumeration (classe) */ -struct _GClassEnumTypeClass -{ - GDataTypeClass parent; /* A laisser en premier */ - -}; - - -/* Décrit le type fourni sous forme de caractères. */ -char *g_class_enum_type_to_string(const GClassEnumType *); - -/* Procède à l'impression de la description d'un type. */ -//void g_class_enum_type_output(const GClassEnumType *, GLangOutput *, GBufferLine *, bool, bool); - - - -#endif /* _ANALYSIS_TYPES_CSE_INT_H */ diff --git a/src/analysis/types/cse.c b/src/analysis/types/cse.c index f20f340..a543630 100644 --- a/src/analysis/types/cse.c +++ b/src/analysis/types/cse.c @@ -24,22 +24,50 @@ #include "cse.h" +#include #include -#include "cse-int.h" +#include "../type-int.h" +/* Description de type classe/structure et énumération (instance) */ +struct _GClassEnumType +{ + GDataType parent; /* A laisser en premier */ + + ClassEnumType type; /* Type représenté si connu */ + char *name; /* Description humaine */ + +}; + +/* Description de type classe/structure et énumération (classe) */ +struct _GClassEnumTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + /* Initialise la classe des types classe ou assimilés. */ static void g_class_enum_type_class_init(GClassEnumTypeClass *); /* Initialise l'instance d'un type classe ou assimilé. */ static void g_class_enum_type_init(GClassEnumType *); +/* Supprime toutes les références externes. */ +static void g_class_enum_type_dispose(GClassEnumType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_class_enum_type_finalize(GClassEnumType *); + /* Crée un copie d'un type existant. */ static GDataType *g_class_enum_type_dup(const GClassEnumType *); +/* Décrit le type fourni sous forme de caractères. */ +static char *g_class_enum_type_to_string(const GClassEnumType *, bool); + /* Indique le type défini pour un type classe ou assimilé. */ @@ -60,6 +88,18 @@ G_DEFINE_TYPE(GClassEnumType, g_class_enum_type, G_TYPE_DATA_TYPE); static void g_class_enum_type_class_init(GClassEnumTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_class_enum_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_class_enum_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_class_enum_type_dup; + type->to_string = (type_to_string_fc)g_class_enum_type_to_string; } @@ -78,13 +118,49 @@ static void g_class_enum_type_class_init(GClassEnumTypeClass *klass) static void g_class_enum_type_init(GClassEnumType *type) { - GDataType *data_type; /* Version basique */ + type->type = CET_COUNT; + type->name = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_class_enum_type_dispose(GClassEnumType *type) +{ + G_OBJECT_CLASS(g_class_enum_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - data_type = G_DATA_TYPE(type); +static void g_class_enum_type_finalize(GClassEnumType *type) +{ + if (type->name != NULL) + free(type->name); - data_type->dup = (type_dup_fc)g_class_enum_type_dup; - data_type->to_string = (type_to_string_fc)g_class_enum_type_to_string; - //data_type->output = (output_type_fc)g_class_enum_type_output; + G_OBJECT_CLASS(g_class_enum_type_parent_class)->finalize(G_OBJECT(type)); } @@ -130,14 +206,22 @@ GDataType *g_class_enum_type_new(ClassEnumType type, char *name) static GDataType *g_class_enum_type_dup(const GClassEnumType *type) { - return g_class_enum_type_new(type->type, type->name); + GDataType *result; /* Copie à retourner */ + char *name; /* Nouveau nom copié */ + + name = (type->name != NULL ? strdup(type->name) : NULL); + + result = g_class_enum_type_new(type->type, name); + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -147,33 +231,72 @@ static GDataType *g_class_enum_type_dup(const GClassEnumType *type) * * ******************************************************************************/ -char *g_class_enum_type_to_string(const GClassEnumType *type) +static char *g_class_enum_type_to_string(const GClassEnumType *type, bool include) { - return strdup(type->name); + char *result; /* Valeur à renvoyer */ + + switch (type->type) + { + case CET_VIRTUAL_TABLE: + result = strdup("vtable"); + break; + + case CET_VIRTUAL_STRUCT: + result = strdup("vstruct"); + break; + + default: + result = (type->name != NULL ? strdup(type->name) : NULL); + break; + + } + + return result; } /****************************************************************************** * * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à consulter. * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Fournit le type pris en compte géré par le type. * * * -* Retour : - * +* Retour : Type pris en compte. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ClassEnumType g_class_enum_type_get_base(const GClassEnumType *type) +{ + ClassEnumType result; /* Type de base à renvoyer */ + + result = type->type; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Donne la désignation de la classe / structure / énumération. * +* * +* Retour : Chaîne de caractères. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -void g_class_enum_type_output(const GClassEnumType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +const char *g_class_enum_type_get_name(const GClassEnumType *type) { - g_buffer_line_append_text(line, BLC_LAST_USED, type->name, strlen(type->name), - info ? RTT_COMMENT : RTT_RAW, NULL); + char *result; /* Valeur à renvoyer */ + + result = type->name; + + return result; } -#endif diff --git a/src/analysis/types/cse.h b/src/analysis/types/cse.h index 184062d..cb4b228 100644 --- a/src/analysis/types/cse.h +++ b/src/analysis/types/cse.h @@ -32,18 +32,18 @@ -#define G_TYPE_CLASS_ENUM_TYPE g_class_enum_type_get_type() -#define G_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_class_enum_type_get_type(), GClassEnumType)) -#define G_IS_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_class_enum_type_get_type())) -#define G_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) -#define G_IS_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CLASS_ENUM_TYPE)) -#define G_CLASS_ENUM_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) +#define G_TYPE_CLASS_ENUM_TYPE g_class_enum_type_get_type() +#define G_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumType)) +#define G_IS_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CLASS_ENUM_TYPE)) +#define G_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) +#define G_IS_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CLASS_ENUM_TYPE)) +#define G_CLASS_ENUM_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) -/* Description de type classe/structure et enumeration (instance) */ +/* Description de type classe/structure et énumération (instance) */ typedef struct _GClassEnumType GClassEnumType; -/* Description de type classe/structure et enumeration (classe) */ +/* Description de type classe/structure et énumération (classe) */ typedef struct _GClassEnumTypeClass GClassEnumTypeClass; @@ -53,7 +53,12 @@ typedef enum _ClassEnumType CET_UNKNOWN, /* Statut inconnu */ CET_STRUCT, /* Structure */ CET_ENUM, /* Enumération */ - CET_CLASS /* Classe */ + CET_CLASS, /* Classe */ + CET_NAMESPACE, /* Espace de nom */ + CET_VIRTUAL_TABLE, /* Table virtuelle */ + CET_VIRTUAL_STRUCT, /* Indice de construction VT */ + + CET_COUNT } ClassEnumType; @@ -64,6 +69,12 @@ GType g_class_enum_type_get_type(void); /* Crée une représentation de classe, structure ou énumération. */ GDataType *g_class_enum_type_new(ClassEnumType, char *); +/* Fournit le type pris en compte géré par le type. */ +ClassEnumType g_class_enum_type_get_base(const GClassEnumType *); + +/* Donne la désignation de la classe / structure / énumération. */ +const char *g_class_enum_type_get_name(const GClassEnumType *); + #endif /* _ANALYSIS_TYPES_CSE_H */ diff --git a/src/analysis/types/encaps.c b/src/analysis/types/encaps.c index 36dc71a..dc1bb3e 100644 --- a/src/analysis/types/encaps.c +++ b/src/analysis/types/encaps.c @@ -25,9 +25,9 @@ #include +#include -#include "../routine.h" #include "../type-int.h" #include "../../common/extstr.h" @@ -40,7 +40,6 @@ struct _GEncapsulatedType EncapsulationType type; /* Encapsulation utilisée */ GDataType *child; /* Sous-type encadré */ - GBinRoutine *routine; /* Routine pointée */ size_t dimension; /* Dimension quand applicable */ @@ -60,14 +59,23 @@ static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *); /* Initialise l'instance d'un type encapsulé. */ static void g_encapsulated_type_init(GEncapsulatedType *); +/* Supprime toutes les références externes. */ +static void g_encapsulated_type_dispose(GEncapsulatedType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_encapsulated_type_finalize(GEncapsulatedType *); + /* Crée un copie d'un type existant. */ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_encapsulated_type_to_string(const GEncapsulatedType *); +static char *g_encapsulated_type_to_string(const GEncapsulatedType *, bool); -/* Procède à l'impression de la description d'un type. */ -//static void g_encapsulated_type_output(const GEncapsulatedType *, GLangOutput *, GBufferLine *, bool, bool); +/* Indique si le type est un pointeur. */ +static bool g_encapsulated_type_is_pointer(const GEncapsulatedType *); + +/* Indique si le type est une référence. */ +static bool g_encapsulated_type_is_reference(const GEncapsulatedType *); @@ -89,6 +97,21 @@ G_DEFINE_TYPE(GEncapsulatedType, g_encapsulated_type, G_TYPE_DATA_TYPE); static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_encapsulated_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_encapsulated_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_encapsulated_type_dup; + type->to_string = (type_to_string_fc)g_encapsulated_type_to_string; + + type->is_pointer = (type_is_pointer_fc)g_encapsulated_type_is_pointer; + type->is_reference = (type_is_reference_fc)g_encapsulated_type_is_reference; } @@ -107,13 +130,51 @@ static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *klass) static void g_encapsulated_type_init(GEncapsulatedType *type) { - GDataType *data_type; /* Version basique */ + type->type = ECT_COUNT; + type->child = NULL; + + type->dimension = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_encapsulated_type_dispose(GEncapsulatedType *type) +{ + if (type->child != NULL) + g_object_unref(G_OBJECT(type->child)); + + G_OBJECT_CLASS(g_encapsulated_type_parent_class)->dispose(G_OBJECT(type)); + +} - data_type = G_DATA_TYPE(type); - data_type->dup = (type_dup_fc)g_encapsulated_type_dup; - data_type->to_string = (type_to_string_fc)g_encapsulated_type_to_string; - //data_type->output = (output_type_fc)g_encapsulated_type_output; +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_encapsulated_type_finalize(GEncapsulatedType *type) +{ + G_OBJECT_CLASS(g_encapsulated_type_parent_class)->finalize(G_OBJECT(type)); } @@ -121,7 +182,7 @@ static void g_encapsulated_type_init(GEncapsulatedType *type) /****************************************************************************** * * * Paramètres : type = type d'extension à représenter. * -* child = variable dont on doit dériver. * +* child = base dont on doit dériver. * * * * Description : Crée une représentation de variable dérivée. * * * @@ -131,33 +192,14 @@ static void g_encapsulated_type_init(GEncapsulatedType *type) * * ******************************************************************************/ -GDataType *g_encapsulated_type_new(EncapsulationType type, ...) +GDataType *g_encapsulated_type_new(EncapsulationType type, GDataType *child) { GEncapsulatedType *result; /* Structure à retourner */ - va_list ap; /* Liste variable d'arguments */ result = g_object_new(G_TYPE_ENCAPSULATED_TYPE, NULL); result->type = type; - - va_start(ap, type); - - switch (type) - { - case ECT_ROUTINE: - result->routine = va_arg(ap, GBinRoutine *); - assert(result->routine != NULL); - g_binary_routine_set_name(result->routine, "(*)"); - break; - - default: - result->child = va_arg(ap, GDataType *); - assert(result->child != NULL); - break; - - } - - va_end(ap); + result->child = child; return G_DATA_TYPE(result); @@ -181,19 +223,8 @@ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *type) GDataType *result; /* Nouvelle instance à renvoyer*/ GDataType *child; /* Copie du type interne */ - switch (type->type) - { - case ECT_ROUTINE: - g_object_ref(G_OBJECT(type->routine)); - result = g_encapsulated_type_new(type->type, type->routine); - break; - - default: - child = g_data_type_dup(type->child); - result = g_encapsulated_type_new(type->type, child); - break; - - } + child = g_data_type_dup(type->child); + result = g_encapsulated_type_new(type->type, child); return result; @@ -202,7 +233,8 @@ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *type) /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -212,34 +244,20 @@ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *type) * * ******************************************************************************/ -static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) +static char *g_encapsulated_type_to_string(const GEncapsulatedType *type, bool include) { char *result; /* Chaîne finale à renvoyer */ size_t i; /* Boucle de parcours */ - switch (type->type) - { - case ECT_ROUTINE: - result = g_binary_routine_to_string(type->routine); - break; - - default: - result = g_data_type_to_string(type->child); - break; - - } + result = g_data_type_to_string(type->child, include); + if (result == NULL) goto exit; switch (type->type) { case ECT_POINTER: - - if (G_IS_ENCAPSULATED_TYPE(type->child) - && G_ENCAPSULATED_TYPE(type->child)->type == ECT_ROUTINE) break; - - if (!g_data_type_is_pointer(type->child, false)) + if (!g_data_type_is_pointer(type->child)) result = stradd(result, " "); result = stradd(result, "*"); - break; case ECT_ARRAY: @@ -247,25 +265,37 @@ static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) for (i = 0; i < type->dimension; i++) result = stradd(result, "[]"); break; + case ECT_REFERENCE: - result = stradd(result, " &"); + if (!g_data_type_is_reference(type->child)) + result = stradd(result, " "); + result = stradd(result, "&"); break; + case ECT_RVALUE_REF: - result = stradd(result, " &&"); + if (!g_data_type_is_reference(type->child)) + result = stradd(result, " "); + result = stradd(result, "&&"); break; + case ECT_COMPLEX: result = stradd(result, " complex"); break; + case ECT_IMAGINARY: result = stradd(result, " imaginary"); break; - case ECT_ROUTINE: /* Pour GCC */ default: + assert(false); + free(result); + result = NULL; break; } + exit: + return result; } @@ -273,26 +303,48 @@ static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) /****************************************************************************** * * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à consulter. * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Indique si le type est un pointeur. * * * -* Retour : - * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_encapsulated_type_is_pointer(const GEncapsulatedType *type) +{ + bool result; /* Bilan à retourner */ + + result = (type->type == ECT_POINTER); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique si le type est une référence. * +* * +* Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -static void g_encapsulated_type_output(const GEncapsulatedType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +static bool g_encapsulated_type_is_reference(const GEncapsulatedType *type) { - g_buffer_line_append_text(line, BLC_LAST_USED, "!TODO!", 6, info ? RTT_COMMENT : RTT_RAW, NULL); + bool result; /* Bilan à retourner */ + + result = (type->type == ECT_REFERENCE || type->type == ECT_RVALUE_REF); + + return result; } -#endif /****************************************************************************** @@ -317,39 +369,25 @@ EncapsulationType g_encapsulated_type_get_etype(const GEncapsulatedType *type) /****************************************************************************** * * * Paramètres : type = type à consulter. * -* ... = sous-type ou routine encapsulée dans le type. [OUT] * * * -* Description : Fournit la routine encapsulée dans le type. * +* Description : Fournit le type encapsulée dans le type. * * * -* Retour : - * +* Retour : Sous-type encapsulé dans le type. * * * * Remarques : - * * * ******************************************************************************/ -void g_encapsulated_type_get_item(const GEncapsulatedType *type, ...) +GDataType *g_encapsulated_type_get_item(const GEncapsulatedType *type) { - va_list ap; /* Liste variable d'arguments */ - GDataType **child; /* Adresse pour sous-type */ - GBinRoutine **routine; /* Adresse pour routine */ + GDataType *result; /* Type à retourner */ - va_start(ap, type); + result = type->child; - switch (type->type) - { - case ECT_ROUTINE: - routine = va_arg(ap, GBinRoutine **); - *routine = type->routine; - break; + if (result != NULL) + g_object_ref(G_OBJECT(result)); - default: - child = va_arg(ap, GDataType **); - *child = type->child; - break; - - } - - va_end(ap); + return result; } diff --git a/src/analysis/types/encaps.h b/src/analysis/types/encaps.h index 7ea8b9e..d8b70b0 100644 --- a/src/analysis/types/encaps.h +++ b/src/analysis/types/encaps.h @@ -32,12 +32,12 @@ -#define G_TYPE_ENCAPSULATED_TYPE g_encapsulated_type_get_type() -#define G_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_encapsulated_type_get_type(), GEncapsulatedType)) -#define G_IS_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_encapsulated_type_get_type())) -#define G_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) -#define G_IS_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENCAPSULATED_TYPE)) -#define G_ENCAPSULATED_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) +#define G_TYPE_ENCAPSULATED_TYPE g_encapsulated_type_get_type() +#define G_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedType)) +#define G_IS_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ENCAPSULATED_TYPE)) +#define G_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) +#define G_IS_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENCAPSULATED_TYPE)) +#define G_ENCAPSULATED_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) /* Description de type encapsulé (instance) */ @@ -57,7 +57,7 @@ typedef enum _EncapsulationType ECT_COMPLEX, /* Complexe (C 2000) */ ECT_IMAGINARY, /* Imaginaire (C 2000) */ - ECT_ROUTINE /* Pointeur vers une routine */ + ECT_COUNT } EncapsulationType; @@ -66,13 +66,13 @@ typedef enum _EncapsulationType GType g_encapsulated_type_get_type(void); /* Crée une représentation de variable dérivée. */ -GDataType *g_encapsulated_type_new(EncapsulationType, ...); +GDataType *g_encapsulated_type_new(EncapsulationType, GDataType *); /* Fournit le type d'encapsulation gérée par le type. */ EncapsulationType g_encapsulated_type_get_etype(const GEncapsulatedType *); -/* Fournit la routine encapsulée dans le type. */ -void g_encapsulated_type_get_item(const GEncapsulatedType *, ...); +/* Fournit le type encapsulée dans le type. */ +GDataType *g_encapsulated_type_get_item(const GEncapsulatedType *); /* Fournit la dimension éventuellement associée au type. */ size_t g_encapsulated_type_get_dimension(const GEncapsulatedType *); diff --git a/src/analysis/types/expr.c b/src/analysis/types/expr.c new file mode 100644 index 0000000..376b0b4 --- /dev/null +++ b/src/analysis/types/expr.c @@ -0,0 +1,258 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * expr.c - manipulation de types sous forme d'expressions + * + * Copyright (C) 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 "expr.h" + + +#include +#include + + +#include "../type-int.h" + + + +/* Description de type sous forme d'expressions (instance) */ +struct _GExprType +{ + GDataType parent; /* A laisser en premier */ + + char *value; /* Valeur brute de l'expression*/ + +}; + +/* Description de type sous forme d'expressions (classe) */ +struct _GExprTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des types sous forme d'expressions. */ +static void g_expr_type_class_init(GExprTypeClass *); + +/* Initialise l'instance d'un type sous forme d'expressions. */ +static void g_expr_type_init(GExprType *); + +/* Supprime toutes les références externes. */ +static void g_expr_type_dispose(GExprType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_expr_type_finalize(GExprType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_expr_type_dup(const GExprType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_expr_type_to_string(const GExprType *, bool); + + + +/* Indique le type défini pour un type sous forme d'expressions. */ +G_DEFINE_TYPE(GExprType, g_expr_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des types sous forme d'expressions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_class_init(GExprTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_expr_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_expr_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_expr_type_dup; + type->to_string = (type_to_string_fc)g_expr_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'un type sous forme d'expressions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_init(GExprType *type) +{ + type->value = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_dispose(GExprType *type) +{ + G_OBJECT_CLASS(g_expr_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_finalize(GExprType *type) +{ + if (type->value != NULL) + free(type->value); + + G_OBJECT_CLASS(g_expr_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : value = valeur brute de l'expression. * +* * +* Description : Crée une représentation de type sous forme d'expressions. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_expr_type_new(char *value) +{ + GExprType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_EXPR_TYPE, NULL); + + result->value = value; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_expr_type_dup(const GExprType *type) +{ + GDataType *result; /* Copie à retourner */ + + result = g_expr_type_new(strdup(type->value)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_expr_type_to_string(const GExprType *type, bool include) +{ + char *result; /* Valeur à renvoyer */ + + result = strdup(type->value); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit la valeur d'un type fourni sous forme de caractères. * +* * +* Retour : Chaîne formant une expression. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_expr_type_get_value(const GExprType *type) +{ + char *result; /* Valeur à renvoyer */ + + result = type->value; + + return result; + +} diff --git a/src/analysis/types/expr.h b/src/analysis/types/expr.h new file mode 100644 index 0000000..3f7c953 --- /dev/null +++ b/src/analysis/types/expr.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * expr.h - prototypes pour la manipulation de types sous forme d'expressions + * + * Copyright (C) 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 . + */ + + +#ifndef _ANALYSIS_TYPES_EXPR_H +#define _ANALYSIS_TYPES_EXPR_H + + +#include + + +#include "../type.h" + + + +#define G_TYPE_EXPR_TYPE g_expr_type_get_type() +#define G_EXPR_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_EXPR_TYPE, GExprType)) +#define G_IS_EXPR_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_EXPR_TYPE)) +#define G_EXPR_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_EXPR_TYPE, GExprTypeClass)) +#define G_IS_EXPR_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_EXPR_TYPE)) +#define G_EXPR_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_EXPR_TYPE, GExprTypeClass)) + + +/* Description de type sous forme d'expressions (instance) */ +typedef struct _GExprType GExprType; + +/* Description de type sous forme d'expressions (classe) */ +typedef struct _GExprTypeClass GExprTypeClass; + + +/* Indique le type défini pour un type sous forme d'expressions. */ +GType g_expr_type_get_type(void); + +/* Crée une représentation de type sous forme d'expressions. */ +GDataType *g_expr_type_new(char *); + +/* Fournit la valeur d'un type fourni sous forme de caractères. */ +const char *g_expr_type_get_value(const GExprType *); + + + +#endif /* _ANALYSIS_TYPES_EXPR_H */ diff --git a/src/analysis/types/literal.c b/src/analysis/types/literal.c index 7a0c4f7..f284310 100644 --- a/src/analysis/types/literal.c +++ b/src/analysis/types/literal.c @@ -58,14 +58,17 @@ static void g_literal_type_class_init(GLiteralTypeClass *); /* Initialise l'instance d'un type instancié avec une valeur. */ static void g_literal_type_init(GLiteralType *); +/* Supprime toutes les références externes. */ +static void g_literal_type_dispose(GLiteralType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_literal_type_finalize(GLiteralType *); + /* Crée un copie d'un type existant. */ static GDataType *g_literal_type_dup(const GLiteralType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_literal_type_to_string(const GLiteralType *); - -/* Procède à l'impression de la description d'un type. */ -//static void g_literal_type_output(const GLiteralType *, GLangOutput *, GBufferLine *, bool, bool); +static char *g_literal_type_to_string(const GLiteralType *, bool); @@ -87,6 +90,18 @@ G_DEFINE_TYPE(GLiteralType, g_literal_type, G_TYPE_DATA_TYPE); static void g_literal_type_class_init(GLiteralTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_literal_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_literal_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_literal_type_dup; + type->to_string = (type_to_string_fc)g_literal_type_to_string; } @@ -105,13 +120,48 @@ static void g_literal_type_class_init(GLiteralTypeClass *klass) static void g_literal_type_init(GLiteralType *type) { - GDataType *data_type; /* Version basique */ + type->orig = NULL; - data_type = G_DATA_TYPE(type); +} - data_type->dup = (type_dup_fc)g_literal_type_dup; - data_type->to_string = (type_to_string_fc)g_literal_type_to_string; - //data_type->output = (output_type_fc)g_literal_type_output; + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_literal_type_dispose(GLiteralType *type) +{ + if (type->orig != NULL) + g_object_unref(G_OBJECT(type->orig)); + + G_OBJECT_CLASS(g_literal_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_literal_type_finalize(GLiteralType *type) +{ + G_OBJECT_CLASS(g_literal_type_parent_class)->finalize(G_OBJECT(type)); } @@ -129,18 +179,23 @@ static void g_literal_type_init(GLiteralType *type) * * ******************************************************************************/ -GDataType *g_literal_type_new(GDataType *orig, literal_value value) +GDataType *g_literal_type_new(GDataType *orig, const literal_value *value) { GLiteralType *result; /* Structure à retourner */ - result = g_object_new(G_TYPE_LITERAL_TYPE, NULL); + if (!G_IS_BASIC_TYPE(orig)) + result = NULL; - result->orig = orig; - result->value = value; + else + { + result = g_object_new(G_TYPE_LITERAL_TYPE, NULL); - g_object_ref(orig); + result->orig = orig; + result->value = *value; - return G_DATA_TYPE(result); + } + + return (result != NULL ? G_DATA_TYPE(result) : NULL); } @@ -159,18 +214,22 @@ GDataType *g_literal_type_new(GDataType *orig, literal_value value) static GDataType *g_literal_type_dup(const GLiteralType *type) { + GDataType *result; /* Copie à retourner */ GDataType *orig; /* Copie du type interne */ orig = g_data_type_dup(type->orig); - return g_literal_type_new(orig, type->value); + result = g_literal_type_new(orig, &type->value); + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -180,63 +239,27 @@ static GDataType *g_literal_type_dup(const GLiteralType *type) * * ******************************************************************************/ -static char *g_literal_type_to_string(const GLiteralType *type) +static char *g_literal_type_to_string(const GLiteralType *type, bool include) { char *result; /* Valeur à renvoyer */ - size_t max; /* Longueur totale du texte */ - if (G_IS_BASIC_TYPE(type->orig)) - switch (g_basic_type_get_btype(G_BASIC_TYPE(type->orig))) - { - case BTP_BOOL: - result = strdup(type->value.int_val ? "true" : "false"); - break; + switch (g_basic_type_get_base_type(G_BASIC_TYPE(type->orig))) + { + case BTP_BOOL: + result = strdup(type->value.int_val ? "true" : "false"); + break; - case BTP_INT: - max = strlen("2147483647" /* INT_MAX */) + 1; - result = (char *)calloc(max, sizeof(char)); - snprintf(result, max, "%d", type->value.int_val); - break; + case BTP_INT: + default: + asprintf(&result, "%d", type->value.int_val); + break; - default: - result = strdup("TODO"); - break; + case BTP_FLOAT: + asprintf(&result, "%f", type->value.float_val); + break; } - else result = strdup("???"); return result; } - - -/****************************************************************************** -* * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * -* * -* Description : Procède à l'impression de la description d'un type. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -static void g_literal_type_output(const GLiteralType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) -{ - char *text; /* Version humaine à imprimer */ - size_t len; /* Taille de cette version */ - - text = g_literal_type_to_string(type); - len = strlen(text); - - g_buffer_line_append_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW, NULL); - - free(text); - -} -#endif diff --git a/src/analysis/types/literal.h b/src/analysis/types/literal.h index 032ba8b..48a543a 100644 --- a/src/analysis/types/literal.h +++ b/src/analysis/types/literal.h @@ -32,12 +32,12 @@ -#define G_TYPE_LITERAL_TYPE g_literal_type_get_type() -#define G_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_literal_type_get_type(), GLiteralType)) -#define G_IS_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_literal_type_get_type())) -#define G_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) -#define G_IS_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_TYPE)) -#define G_LITERAL_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) +#define G_TYPE_LITERAL_TYPE g_literal_type_get_type() +#define G_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LITERAL_TYPE, GLiteralType)) +#define G_IS_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LITERAL_TYPE)) +#define G_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) +#define G_IS_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_TYPE)) +#define G_LITERAL_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) /* Description de type instancié avec une valeur litérale (instance) */ @@ -60,7 +60,7 @@ typedef union _literal_value GType g_literal_type_get_type(void); /* Crée une représentation de type instancié avec une valeur. */ -GDataType *g_literal_type_new(GDataType *, literal_value); +GDataType *g_literal_type_new(GDataType *, const literal_value *); diff --git a/src/analysis/types/override.c b/src/analysis/types/override.c new file mode 100644 index 0000000..a535e80 --- /dev/null +++ b/src/analysis/types/override.c @@ -0,0 +1,365 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * override.c - manipulation des types pointant sur une fonction virtuelle + * + * Copyright (C) 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 "override.h" + + +#include +#include +#include + + +#include "../type-int.h" +#include "../../common/extstr.h" + + + +/* Description de fonction virtuelle (instance) */ +struct _GOverrideType +{ + GDataType parent; /* A laisser en premier */ + + GDataType *base; /* Type de base à traiter */ + call_offset_t offsets[2]; /* Décalages à appliquer */ + bool with_covariant; /* Variation avec covariant */ + +}; + +/* Description de fonction virtuelle (classe) */ +struct _GOverrideTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des fonctions virtuelles. */ +static void g_override_type_class_init(GOverrideTypeClass *); + +/* Initialise l'instance d'une fonction virtuelle. */ +static void g_override_type_init(GOverrideType *); + +/* Supprime toutes les références externes. */ +static void g_override_type_dispose(GOverrideType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_override_type_finalize(GOverrideType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_override_type_dup(const GOverrideType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_override_type_to_string(const GOverrideType *, bool); + + + +/* Indique le type défini pour une fonction virtuelle. */ +G_DEFINE_TYPE(GOverrideType, g_override_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des fonctions virtuelles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_class_init(GOverrideTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_override_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_override_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_override_type_dup; + type->to_string = (type_to_string_fc)g_override_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'une fonction virtuelle. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_init(GOverrideType *type) +{ + type->base = NULL; + memset(type->offsets, 0, sizeof(type->offsets)); + type->with_covariant = false; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_dispose(GOverrideType *type) +{ + if (type->base != NULL) + g_object_unref(G_OBJECT(type->base)); + + G_OBJECT_CLASS(g_override_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_finalize(GOverrideType *type) +{ + G_OBJECT_CLASS(g_override_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : base = type de base sur lequel s'appuyer. * +* offset = décalage à appliquer. * +* * +* Description : Crée une représentation de fonction virtuelle. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_override_type_new(GDataType *base, const call_offset_t *offset) +{ + GOverrideType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_OVERRIDE_TYPE, NULL); + + result->base = base; + result->offsets[0] = *offset; + result->with_covariant = false; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : base = type de base sur lequel s'appuyer. * +* off0 = premier décalage à appliquer. * +* off1 = second décalage à appliquer. * +* * +* Description : Crée une représentation de fonction virtuelle avec covariant.* +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_override_type_new_with_covariant(GDataType *base, const call_offset_t *off0, const call_offset_t *off1) +{ + GOverrideType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_OVERRIDE_TYPE, NULL); + + result->base = base; + result->offsets[0] = *off0; + result->offsets[1] = *off1; + result->with_covariant = true; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_override_type_dup(const GOverrideType *type) +{ + GDataType *result; /* Nouvelle instance à renvoyer*/ + GDataType *base; /* Copie du type interne */ + + base = g_data_type_dup(type->base); + + if (type->with_covariant) + result = g_override_type_new_with_covariant(base, &type->offsets[0], &type->offsets[1]); + + else + result = g_override_type_new(base, &type->offsets[0]); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_override_type_to_string(const GOverrideType *type, bool include) +{ + char *result; /* Chaîne finale à renvoyer */ + + result = g_data_type_to_string(type->base, include); + if (result == NULL) goto exit; + + char *offset_to_string(const call_offset_t *off, char *base) + { + char *tmp; /* Conversion temporaire */ + + asprintf(&tmp, "%zd", off->values[0]); + base = stradd(base, tmp); + free(tmp); + + if (off->virtual) + { + base = stradd(base, "_"); + + asprintf(&tmp, "%zd", off->values[1]); + base = stradd(base, tmp); + free(tmp); + + } + + return base; + + } + + result = offset_to_string(&type->offsets[0], result); + + if (type->with_covariant) + result = offset_to_string(&type->offsets[0], result); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le type de base comportant la fonction virtuelle. * +* * +* Retour : Type de base traité. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_override_type_get_base(const GOverrideType *type) +{ + GDataType *result; /* Type à retourner */ + + result = type->base; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* off0 = premier décalage à appliquer. [OUT] * +* off1 = second décalage à appliquer. [OUT] * +* * +* Description : Fournit les décalages appliquée pour une fonction virtuelle. * +* * +* Retour : true si un covariant est pris en compte, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_override_type_get_offsets(const GOverrideType *type, call_offset_t *off0, call_offset_t *off1) +{ + bool result; /* Nature à retourner */ + + result = type->with_covariant; + + *off0 = type->offsets[0]; + *off1 = type->offsets[1]; + + return result; + +} diff --git a/src/analysis/types/override.h b/src/analysis/types/override.h new file mode 100644 index 0000000..7136e40 --- /dev/null +++ b/src/analysis/types/override.h @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * override.h - prototypes pour la manipulation des types pointant sur une fonction virtuelle + * + * Copyright (C) 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 . + */ + + +#ifndef _ANALYSIS_TYPES_OVERRIDE_H +#define _ANALYSIS_TYPES_OVERRIDE_H + + +#include +#include +#include + + +#include "../type.h" + + + +#define G_TYPE_OVERRIDE_TYPE g_override_type_get_type() +#define G_OVERRIDE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_OVERRIDE_TYPE, GOverrideType)) +#define G_IS_OVERRIDE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_OVERRIDE_TYPE)) +#define G_OVERRIDE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_OVERRIDE_TYPE, GOverrideTypeClass)) +#define G_IS_OVERRIDE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_OVERRIDE_TYPE)) +#define G_OVERRIDE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_OVERRIDE_TYPE, GOverrideTypeClass)) + + +/* Description de fonction virtuelle (instance) */ +typedef struct _GOverrideType GOverrideType; + +/* Description de fonction virtuelle (classe) */ +typedef struct _GOverrideTypeClass GOverrideTypeClass; + + +/* Indications de sauts */ +typedef struct _call_offset_t +{ + ssize_t values[2]; /* Décalages à appliquer */ + bool virtual; /* Appel virtuel ? */ + +} call_offset_t; + + +/* Indique le type défini pour une fonction virtuelle. */ +GType g_override_type_get_type(void); + +/* Crée une représentation de fonction virtuelle. */ +GDataType *g_override_type_new(GDataType *, const call_offset_t *); + +/* Crée une représentation de fonction virtuelle avec covariant. */ +GDataType *g_override_type_new_with_covariant(GDataType *, const call_offset_t *, const call_offset_t *); + +/* Fournit le type de base comportant la fonction virtuelle. */ +GDataType *g_override_type_get_base(const GOverrideType *); + +/* Fournit les décalages appliquée pour une fonction virtuelle. */ +bool g_override_type_get_offsets(const GOverrideType *, call_offset_t *, call_offset_t *); + + + +#endif /* _ANALYSIS_TYPES_OVERRIDE_H */ diff --git a/src/analysis/types/proto.c b/src/analysis/types/proto.c new file mode 100644 index 0000000..362bd88 --- /dev/null +++ b/src/analysis/types/proto.c @@ -0,0 +1,441 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * proto.c - manipulation des prototypes + * + * Copyright (C) 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 "proto.h" + + +#include +#include +#include + + +#include "../type-int.h" +#include "../../common/extstr.h" + + + +/* Description de prototype (instance) */ +struct _GProtoType +{ + GDataType parent; /* A laisser en premier */ + + GDataType *ret_type; /* Type retourné */ + + GDataType **args; /* Sous-types associés */ + size_t count; /* Quantité de ces arguments */ + +}; + +/* Description de prototype (classe) */ +struct _GProtoTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des prototypes. */ +static void g_proto_type_class_init(GProtoTypeClass *); + +/* Initialise l'instance d'un prototype. */ +static void g_proto_type_init(GProtoType *); + +/* Supprime toutes les références externes. */ +static void g_proto_type_dispose(GProtoType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_proto_type_finalize(GProtoType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_proto_type_dup(const GProtoType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_proto_type_to_string(const GProtoType *, bool); + + + +/* Indique le type défini pour un prototype. */ +G_DEFINE_TYPE(GProtoType, g_proto_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des prototypes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_class_init(GProtoTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_proto_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_proto_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->handle_ns = false; + + type->dup = (type_dup_fc)g_proto_type_dup; + type->to_string = (type_to_string_fc)g_proto_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_init(GProtoType *type) +{ + type->ret_type = NULL; + + type->args = NULL; + type->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_dispose(GProtoType *type) +{ + size_t i; /* Boucle de parcours */ + + if (type->ret_type != NULL) + g_object_unref(G_OBJECT(type->ret_type)); + + for (i = 0; i < type->count; i++) + g_object_unref(G_OBJECT(type->args[i])); + + G_OBJECT_CLASS(g_proto_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_finalize(GProtoType *type) +{ + if (type->args != NULL) + free(type->args); + + G_OBJECT_CLASS(g_proto_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une représentation de prototype. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_proto_type_new(void) +{ + GProtoType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_PROTO_TYPE, NULL); + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_proto_type_dup(const GProtoType *type) +{ + GProtoType *result; /* Copie à retourner */ + GDataType *ret_type; /* Type de retour */ + size_t i; /* Boucle de parcours */ + GDataType *arg; /* Argument copié */ + + result = G_PROTO_TYPE(g_proto_type_new()); + + if (type->ret_type != NULL) + { + ret_type = g_data_type_dup(type->ret_type); + g_proto_type_set_return_type(result, ret_type); + } + + for (i = 0; i < type->count; i++) + { + arg = g_data_type_dup(type->args[i]); + g_proto_type_add_arg(result, arg); + } + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_proto_type_to_string(const GProtoType *type, bool include) +{ + char *result; /* Valeur à renvoyer */ + GDataType *base; /* Version d'instance parente */ + char *namespace; /* Groupe d'appartenance */ + size_t i; /* Boucle de parcours */ + char *arg; /* Argument à décrire */ + + if (type->ret_type != NULL) + { + result = g_data_type_to_string(type->ret_type, include); + if (result == NULL) goto exit; + + result = stradd(result, " "); + + } + else + result = NULL; + + result = stradd(result, "("); + + base = G_DATA_TYPE(type); + + if (include && base->namespace != NULL) + { + namespace = g_data_type_to_string(base->namespace, true); + if (namespace == NULL) goto error; + + result = stradd(result, namespace); + result = stradd(result, base->ns_sep); + + free(namespace); + + } + + result = stradd(result, "*) ("); + + for (i = 0; i < type->count; i++) + { + if (i > 0) result = stradd(result, ", "); + + arg = g_data_type_to_string(type->args[i], include); + if (arg == NULL) goto error; + + result = stradd(result, arg); + free(arg); + + } + + result = stradd(result, ")"); + + exit: + + return result; + + error: + + free(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à mettre à jour. * +* ret = indication sur le type de retour. * +* * +* Description : Définit le type de retour d'un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proto_type_set_return_type(GProtoType *type, GDataType *ret) +{ + if (type->ret_type != NULL) + g_object_unref(G_OBJECT(type->ret_type)); + + type->ret_type = ret; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le type de retour d'un prototype. * +* * +* Retour : Indication sur le type de retour en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_proto_type_get_return_type(const GProtoType *type) +{ + GDataType *result; /* Type de retour à renvoyer */ + + result = type->ret_type; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à mettre à jour. * +* arg = nouvel argument à intégrer au prototype. * +* * +* Description : Ajoute un argument à un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proto_type_add_arg(GProtoType *type, GDataType *arg) +{ + type->args = (GDataType **)realloc(type->args, ++type->count * sizeof(GDataType *)); + type->args[type->count - 1] = arg; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique le nombre d'arguments associés au prototype. * +* * +* Retour : Nombre de paramètres inclus dans le gabarit. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_proto_type_count_args(const GProtoType *type) +{ + return type->count; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* index = indice du type d'argument à retourner. * +* * +* Description : Fournit un argument donné du prototype. * +* * +* Retour : Type d'argument ou NULL si mauvais indice. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_proto_type_get_arg(const GProtoType *type, size_t index) +{ + GDataType *result; /* Argument à retourner */ + + assert(index < type->count); + + if (index < type->count) + { + result = type->args[index]; + g_object_ref(G_OBJECT(result)); + } + + else + result = NULL; + + return result; + +} diff --git a/src/analysis/types/proto.h b/src/analysis/types/proto.h new file mode 100644 index 0000000..a0dedb0 --- /dev/null +++ b/src/analysis/types/proto.h @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * proto.h - prototypes pour la manipulation des prototypes + * + * Copyright (C) 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 . + */ + + +#ifndef _ANALYSIS_TYPES_PROTO_H +#define _ANALYSIS_TYPES_PROTO_H + + +#include + + +#include "../type.h" + + + +#define G_TYPE_PROTO_TYPE g_proto_type_get_type() +#define G_PROTO_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PROTO_TYPE, GProtoType)) +#define G_IS_PROTO_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PROTO_TYPE)) +#define G_PROTO_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PROTO_TYPE, GProtoTypeClass)) +#define G_IS_PROTO_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PROTO_TYPE)) +#define G_PROTO_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PROTO_TYPE, GProtoTypeClass)) + + +/* Description de prototype (instance) */ +typedef struct _GProtoType GProtoType; + +/* Description de prototype (classe) */ +typedef struct _GProtoTypeClass GProtoTypeClass; + + +/* Indique le type défini pour un prototype. */ +GType g_proto_type_get_type(void); + +/* Crée une représentation de prototype. */ +GDataType *g_proto_type_new(void); + +/* Définit le type de retour d'un prototype. */ +void g_proto_type_set_return_type(GProtoType *, GDataType *); + +/* Fournit le type de retour d'un prototype. */ +GDataType *g_proto_type_get_return_type(const GProtoType *); + +/* Ajoute un argument à un prototype. */ +void g_proto_type_add_arg(GProtoType *, GDataType *); + +/* Indique le nombre d'arguments associés au prototype. */ +size_t g_proto_type_count_args(const GProtoType *); + +/* Fournit un argument donné du prototype. */ +GDataType *g_proto_type_get_arg(const GProtoType *, size_t); + + + +#endif /* _ANALYSIS_TYPES_PROTO_H */ diff --git a/src/analysis/types/template.c b/src/analysis/types/template.c index 5e6e95f..5555985 100644 --- a/src/analysis/types/template.c +++ b/src/analysis/types/template.c @@ -24,11 +24,11 @@ #include "template.h" +#include #include #include -#include "cse-int.h" #include "../type-int.h" #include "../../common/extstr.h" @@ -37,17 +37,19 @@ /* Description de type reposant sur des gabarits (instance) */ struct _GTemplateType { - GClassEnumType parent; /* A laisser en premier */ + GDataType parent; /* A laisser en premier */ - GDataType **models; /* Sous-types associés */ - size_t models_count; /* Quantité de ces modèles */ + char *name; /* Désignation de la base */ + + GDataType **params; /* Sous-types associés */ + size_t count; /* Quantité de ces paramètres */ }; /* Description de type reposant sur des gabarits (classe) */ struct _GTemplateTypeClass { - GClassEnumTypeClass parent; /* A laisser en premier */ + GDataTypeClass parent; /* A laisser en premier */ }; @@ -58,19 +60,22 @@ static void g_template_type_class_init(GTemplateTypeClass *); /* Initialise l'instance d'un type reposant sur des gabarits. */ static void g_template_type_init(GTemplateType *); +/* Supprime toutes les références externes. */ +static void g_template_type_dispose(GTemplateType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_template_type_finalize(GTemplateType *); + /* Crée un copie d'un type existant. */ static GDataType *g_template_type_dup(const GTemplateType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_template_type_to_string(const GTemplateType *); - -/* Procède à l'impression de la description d'un type. */ -//static void g_template_type_output(const GTemplateType *, GLangOutput *, GBufferLine *, bool, bool); +static char *g_template_type_to_string(const GTemplateType *, bool); /* Indique le type défini pour un type reposant sur des gabarits. */ -G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_CLASS_ENUM_TYPE); +G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_DATA_TYPE); /****************************************************************************** @@ -87,6 +92,18 @@ G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_CLASS_ENUM_TYPE); static void g_template_type_class_init(GTemplateTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_template_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_template_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_template_type_dup; + type->to_string = (type_to_string_fc)g_template_type_to_string; } @@ -105,26 +122,66 @@ static void g_template_type_class_init(GTemplateTypeClass *klass) static void g_template_type_init(GTemplateType *type) { - GDataType *data_type; /* Version basique */ - GClassEnumType *ce_type; /* Version basique #2 */ + type->name = NULL; + + type->params = NULL; + type->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_template_type_dispose(GTemplateType *type) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < type->count; i++) + g_object_unref(G_OBJECT(type->params[i])); - data_type = G_DATA_TYPE(type); + G_OBJECT_CLASS(g_template_type_parent_class)->dispose(G_OBJECT(type)); - data_type->dup = (type_dup_fc)g_template_type_dup; - data_type->to_string = (type_to_string_fc)g_template_type_to_string; - //data_type->output = (output_type_fc)g_template_type_output; +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_template_type_finalize(GTemplateType *type) +{ + if (type->name != NULL) + free(type->name); - ce_type = G_CLASS_ENUM_TYPE(type); + if (type->params != NULL) + free(type->params); - ce_type->type = CET_CLASS; + G_OBJECT_CLASS(g_template_type_parent_class)->finalize(G_OBJECT(type)); } /****************************************************************************** * * -* Paramètres : name = désignation humaine du type. * -* list = élements du modèle sur lequel doit reposer le type. * +* Paramètres : - * * * * Description : Crée une représentation de type reposant sur des gabarits. * * * @@ -134,16 +191,12 @@ static void g_template_type_init(GTemplateType *type) * * ******************************************************************************/ -GDataType *g_template_type_new(const char *name, GSList *list) +GDataType *g_template_type_new(void) { GTemplateType *result; /* Structure à retourner */ result = g_object_new(G_TYPE_TEMPLATE_TYPE, NULL); - G_CLASS_ENUM_TYPE(result)->name = strdup(name); - - g_template_type_add_params(result, list); - return G_DATA_TYPE(result); } @@ -151,138 +204,152 @@ GDataType *g_template_type_new(const char *name, GSList *list) /****************************************************************************** * * -* Paramètres : type = type à dupliquer. * +* Paramètres : type = type base sur des gabarits à modifier. * * * -* Description : Crée un copie d'un type existant. * +* Description : Indique la désignation principale du type. * * * -* Retour : Nouvelle instance de type identique à celle fournie. * +* Retour : Désignation humaine du type. * * * * Remarques : - * * * ******************************************************************************/ -static GDataType *g_template_type_dup(const GTemplateType *type) +const char *g_template_type_get_name(GTemplateType *type) { - GDataType *result; /* Copie à retourner */ - GSList *list; /* Format de liste à fournir */ - size_t i; /* Boucle de parcours */ + char *result; /* Désignation à retourner */ - list = NULL; + result = type->name; - for (i = 0; i < type->models_count; i++) - list = g_slist_prepend(list, type->models[i]); + return result; - result = g_template_type_new(G_CLASS_ENUM_TYPE(type)->name, list); +} - return G_DATA_TYPE(result); + +/****************************************************************************** +* * +* Paramètres : type = type base sur des gabarits à modifier. * +* name = désignation humaine du type. * +* * +* Description : Précise la désignation principale du type. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_template_type_set_name(GTemplateType *type, char *name) +{ + if (type->name != NULL) + free(type->name); + + type->name = name; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à dupliquer. * * * -* Description : Décrit le type fourni sous forme de caractères. * +* Description : Crée un copie d'un type existant. * * * -* Retour : Chaîne à libérer de la mémoire après usage. * +* Retour : Nouvelle instance de type identique à celle fournie. * * * * Remarques : - * * * ******************************************************************************/ -static char *g_template_type_to_string(const GTemplateType *type) +static GDataType *g_template_type_dup(const GTemplateType *type) { - char *result; /* Valeur à renvoyer */ + GTemplateType *result; /* Copie à retourner */ size_t i; /* Boucle de parcours */ - char *sub; /* Sous-type à décrire */ + GDataType *param; /* Paramètre copié */ - result = g_class_enum_type_to_string(G_CLASS_ENUM_TYPE(type)); + result = G_TEMPLATE_TYPE(g_template_type_new()); - result = stradd(result, "<"); + if (type->name != NULL) + g_template_type_set_name(result, strdup(type->name)); - for (i = 0; i < type->models_count; i++) + for (i = 0; i < type->count; i++) { - if (i > 0) result = stradd(result, ", "); - - sub = g_data_type_to_string(type->models[i]); - result = stradd(result, sub); - free(sub); - + param = g_data_type_dup(type->params[i]); + g_template_type_add_param(result, param); } - result = stradd(result, ">"); - - return result; + return G_DATA_TYPE(result); } /****************************************************************************** * * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Décrit le type fourni sous forme de caractères. * * * -* Retour : - * +* Retour : Chaîne à libérer de la mémoire après usage. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -static void g_template_type_output(const GTemplateType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +static char *g_template_type_to_string(const GTemplateType *type, bool include) { + char *result; /* Valeur à renvoyer */ size_t i; /* Boucle de parcours */ + char *param; /* Paramètre à décrire */ - g_class_enum_type_output(G_CLASS_ENUM_TYPE(type), lang, line, info, full); + if (type->name != NULL) + result = strdup(type->name); + else + result = NULL; - g_buffer_line_append_text(line, BLC_LAST_USED, "<", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); + result = stradd(result, "<"); - for (i = 0; i < type->models_count; i++) + for (i = 0; i < type->count; i++) { - if (i > 0) - g_buffer_line_append_text(line, BLC_LAST_USED, ", ", 2, info ? RTT_COMMENT : RTT_SIGNS, NULL); + if (i > 0) result = stradd(result, ", "); - g_data_type_output(type->models[i], lang, line, info, full); + param = g_data_type_to_string(type->params[i], include); + if (param == NULL) goto error; + + result = stradd(result, param); + free(param); } - g_buffer_line_append_text(line, BLC_LAST_USED, ">", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); + result = stradd(result, ">"); + + return result; + + error: + + free(result); + + return NULL; } -#endif /****************************************************************************** * * -* Paramètres : type = type à mettre à jour. * -* list = élements du modèle sur lequel doit reposer le type. * +* Paramètres : type = type à mettre à jour. * +* param = nouveau paramètre à intégrer au gabarit. * * * -* Description : Ajoute une série de paramètres à un gabarit. * +* Description : Ajoute un paramètre à un gabarit. * * * * Retour : - * * * -* Remarques : La liste doit contenir des éléments dans l'ordre inverse * -* d'apparition. De plus, elle est libérée dans cette fonction. * +* Remarques : - * * * ******************************************************************************/ -void g_template_type_add_params(GTemplateType *type, GSList *list) +void g_template_type_add_param(GTemplateType *type, GDataType *param) { - GSList *iter; /* Boucle de parcours */ - - list = g_slist_reverse(list); - for (iter = list; iter != NULL; iter = g_slist_next(iter)) - { - type->models = (GDataType **)realloc(type->models, - ++type->models_count * sizeof(GDataType *)); - type->models[type->models_count - 1] = G_DATA_TYPE(iter->data); - } - g_slist_free(list); + type->params = (GDataType **)realloc(type->params, ++type->count * sizeof(GDataType *)); + type->params[type->count - 1] = param; } @@ -291,7 +358,7 @@ void g_template_type_add_params(GTemplateType *type, GSList *list) * * * Paramètres : type = type à consulter. * * * -* Description : Indique le nombre de paramètres associés du gabarit. * +* Description : Indique le nombre de paramètres associés au gabarit. * * * * Retour : Nombre de paramètres inclus dans le gabarit. * * * @@ -299,9 +366,9 @@ void g_template_type_add_params(GTemplateType *type, GSList *list) * * ******************************************************************************/ -size_t g_template_type_count_param(const GTemplateType *type) +size_t g_template_type_count_params(const GTemplateType *type) { - return type->models_count; + return type->count; } @@ -321,6 +388,19 @@ size_t g_template_type_count_param(const GTemplateType *type) GDataType *g_template_type_get_param(const GTemplateType *type, size_t index) { - return (index < type->models_count ? type->models[index] : NULL); + GDataType *result; /* Paramètre à retourner */ + + assert(index < type->count); + + if (index < type->count) + { + result = type->params[index]; + g_object_ref(G_OBJECT(result)); + } + + else + result = NULL; + + return result; } diff --git a/src/analysis/types/template.h b/src/analysis/types/template.h index 567822e..fd9ad81 100644 --- a/src/analysis/types/template.h +++ b/src/analysis/types/template.h @@ -32,12 +32,12 @@ -#define G_TYPE_TEMPLATE_TYPE g_template_type_get_type() -#define G_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_template_type_get_type(), GTemplateType)) -#define G_IS_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_template_type_get_type())) -#define G_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) -#define G_IS_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TEMPLATE_TYPE)) -#define G_TEMPLATE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) +#define G_TYPE_TEMPLATE_TYPE g_template_type_get_type() +#define G_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TEMPLATE_TYPE, GTemplateType)) +#define G_IS_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TEMPLATE_TYPE)) +#define G_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) +#define G_IS_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TEMPLATE_TYPE)) +#define G_TEMPLATE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) /* Description de type reposant sur des gabarits (instance) */ @@ -51,13 +51,19 @@ typedef struct _GTemplateTypeClass GTemplateTypeClass; GType g_template_type_get_type(void); /* Crée une représentation de type reposant sur des gabarits. */ -GDataType *g_template_type_new(const char *, GSList *); +GDataType *g_template_type_new(void); -/* Ajoute une série de paramètres à un gabarit. */ -void g_template_type_add_params(GTemplateType *, GSList *); +/* Indique la désignation principale du type. */ +const char *g_template_type_get_name(GTemplateType *); -/* Indique le nombre de paramètres associés du gabarit. */ -size_t g_template_type_count_param(const GTemplateType *); +/* Précise la désignation principale du type. */ +void g_template_type_set_name(GTemplateType *, char *); + +/* Ajoute un paramètre à un gabarit. */ +void g_template_type_add_param(GTemplateType *, GDataType *); + +/* Indique le nombre de paramètres associés au gabarit. */ +size_t g_template_type_count_params(const GTemplateType *); /* Fournit un paramètre donné du gabarit. */ GDataType *g_template_type_get_param(const GTemplateType *, size_t); diff --git a/src/analysis/variable.c b/src/analysis/variable.c index b983b73..9fb2e81 100644 --- a/src/analysis/variable.c +++ b/src/analysis/variable.c @@ -25,6 +25,7 @@ #include +#include #include @@ -273,8 +274,8 @@ void g_binary_variable_set_owner(GBinVariable *var, GDataType *owner) /****************************************************************************** * * -* Paramètres : var = variable à convertir. * -* simple = indique si l'espace de noms doit être exclus ou non.* +* Paramètres : var = variable à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit la variable donnée sous forme de caractères. * * * @@ -284,18 +285,15 @@ void g_binary_variable_set_owner(GBinVariable *var, GDataType *owner) * * ******************************************************************************/ -char *g_binary_variable_to_string(const GBinVariable *var, bool simple) +char *g_binary_variable_to_string(const GBinVariable *var, bool include) { char *result; /* Valeur à retourner */ - /* FIXME : décompilation sans type ! */ - result = _g_data_type_to_string(var->type, simple); - - //result = strdup(""); + result = g_data_type_to_string(var->type, include); if (var->name != NULL) { - if (!g_data_type_is_pointer(var->type, true) /* FIXME */ && strlen(result) > 0 /* FIXME */) + if (!(g_data_type_is_pointer(var->type) || g_data_type_is_reference(var->type))) result = stradd(result, " "); result = stradd(result, var->name); @@ -307,39 +305,6 @@ char *g_binary_variable_to_string(const GBinVariable *var, bool simple) } -/****************************************************************************** -* * -* Paramètres : var = variable à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * -* * -* Description : Procède à l'impression de la description d'une variable. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -void g_binary_variable_output(const GBinVariable *var, GLangOutput *lang, GBufferLine *line, bool info, bool full) -{ - g_data_type_output(var->type, lang, line, info, full); - - if (var->name != NULL) - { - if (!g_data_type_is_pointer(var->type, true)) - g_buffer_line_append_text(line, BLC_LAST_USED, " ", 1, RTT_COMMENT, NULL); - - g_buffer_line_append_text(line, BLC_LAST_USED, var->name, strlen(var->name), RTT_COMMENT, NULL); - - } - -} -#endif - - /* ---------------------------------------------------------------------------------- */ /* BASE DE VARIABLES OU VARIABLES INCONNUES */ diff --git a/src/analysis/variable.h b/src/analysis/variable.h index 94ac432..b173f6d 100644 --- a/src/analysis/variable.h +++ b/src/analysis/variable.h @@ -76,9 +76,6 @@ void g_binary_variable_set_owner(GBinVariable *, GDataType *); /* Décrit la variable donnée sous forme de caractères. */ char *g_binary_variable_to_string(const GBinVariable *, bool); -/* Procède à l'impression de la description d'une variable. */ -//void g_binary_variable_output(const GBinVariable *, GLangOutput *, GBufferLine *, bool, bool); - /* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */ diff --git a/src/mangling/java_gram.y b/src/mangling/java_gram.y index cb60d82..9f167c2 100644 --- a/src/mangling/java_gram.y +++ b/src/mangling/java_gram.y @@ -128,13 +128,11 @@ full_class_name: TEXT { $$ = g_class_enum_type_new(CET_CLASS, $1); } | full_class_name SLASH TEXT { $$ = g_class_enum_type_new(CET_CLASS, $3); - g_data_type_set_namespace($$, $1); - g_object_unref($1); + g_data_type_set_namespace($$, $1, "."); } | full_class_name DOLLAR TEXT { $$ = g_class_enum_type_new(CET_CLASS, $3); - g_data_type_set_namespace($$, $1); - g_object_unref($1); + g_data_type_set_namespace($$, $1, "."); } ; diff --git a/tests/mangling/dex.py b/tests/mangling/dex.py index ad60953..b118eda 100644 --- a/tests/mangling/dex.py +++ b/tests/mangling/dex.py @@ -36,7 +36,7 @@ class TestDexMangling(ChrysalideTestCase): self.check_demangling(demangled, 'toto') demangled = demangler.decode_type('Ltiti/toto/tata;') - self.check_demangling(demangled, 'tata') + self.check_demangling(demangled, 'titi.toto.tata') def testDexBadTypeMangling(self): -- cgit v0.11.2-87-g4458