From 838ed83634c445e4ba1b15998f4ad50d1e7503c9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 17 Feb 2020 10:59:45 +0100 Subject: Relocated the undefined instructions. --- configure.ac | 2 + plugins/arm/v7/arm.c | 26 +- plugins/arm/v7/thumb_32.c | 16 +- plugins/pychrysalide/arch/Makefile.am | 4 +- plugins/pychrysalide/arch/instructions/Makefile.am | 24 ++ plugins/pychrysalide/arch/instructions/constants.c | 71 ++++ plugins/pychrysalide/arch/instructions/constants.h | 39 ++ plugins/pychrysalide/arch/instructions/module.c | 104 +++++ plugins/pychrysalide/arch/instructions/module.h | 42 ++ plugins/pychrysalide/arch/instructions/undefined.c | 352 +++++++++++++++++ plugins/pychrysalide/arch/instructions/undefined.h | 45 +++ plugins/pychrysalide/arch/module.c | 5 +- plugins/pychrysalide/arch/operands/module.c | 10 +- plugins/pychrysalide/arch/undefined.c | 367 ------------------ plugins/pychrysalide/arch/undefined.h | 45 --- src/arch/Makefile.am | 5 +- src/arch/instructions/Makefile.am | 23 ++ src/arch/instructions/undefined-int.h | 94 +++++ src/arch/instructions/undefined.c | 421 +++++++++++++++++++++ src/arch/instructions/undefined.h | 72 ++++ src/arch/undefined-int.h | 51 --- src/arch/undefined.c | 395 ------------------- src/arch/undefined.h | 72 ---- src/core/processors.c | 2 +- 24 files changed, 1323 insertions(+), 964 deletions(-) create mode 100644 plugins/pychrysalide/arch/instructions/Makefile.am create mode 100644 plugins/pychrysalide/arch/instructions/constants.c create mode 100644 plugins/pychrysalide/arch/instructions/constants.h create mode 100644 plugins/pychrysalide/arch/instructions/module.c create mode 100644 plugins/pychrysalide/arch/instructions/module.h create mode 100644 plugins/pychrysalide/arch/instructions/undefined.c create mode 100644 plugins/pychrysalide/arch/instructions/undefined.h delete mode 100644 plugins/pychrysalide/arch/undefined.c delete mode 100644 plugins/pychrysalide/arch/undefined.h create mode 100644 src/arch/instructions/Makefile.am create mode 100644 src/arch/instructions/undefined-int.h create mode 100644 src/arch/instructions/undefined.c create mode 100644 src/arch/instructions/undefined.h delete mode 100644 src/arch/undefined-int.h delete mode 100644 src/arch/undefined.c delete mode 100644 src/arch/undefined.h diff --git a/configure.ac b/configure.ac index 3991e72..3759c75 100644 --- a/configure.ac +++ b/configure.ac @@ -446,6 +446,7 @@ AC_CONFIG_FILES([Makefile plugins/pychrysalide/analysis/disass/Makefile plugins/pychrysalide/analysis/types/Makefile plugins/pychrysalide/arch/Makefile + plugins/pychrysalide/arch/instructions/Makefile plugins/pychrysalide/arch/operands/Makefile plugins/pychrysalide/common/Makefile plugins/pychrysalide/core/Makefile @@ -479,6 +480,7 @@ AC_CONFIG_FILES([Makefile src/analysis/human/asm/Makefile src/analysis/types/Makefile src/arch/Makefile + src/arch/instructions/Makefile src/arch/operands/Makefile src/common/Makefile src/core/Makefile diff --git a/plugins/arm/v7/arm.c b/plugins/arm/v7/arm.c index 3081f89..6cd40bb 100644 --- a/plugins/arm/v7/arm.c +++ b/plugins/arm/v7/arm.c @@ -27,7 +27,7 @@ #include -#include +#include #include @@ -2060,7 +2060,7 @@ static GArchInstruction *process_armv7_arm_coprocessor_instructions_and_supervis op = (raw >> 4) & 0x1; if ((op1 & b111110) == b000000) - result = g_undef_instruction_new(IBS_UNDEFINED); + result = g_undef_instruction_new(IEB_UNDEFINED); else if ((op1 & b110000) == b110000) result = armv7_read_arm_instr_a8_svc_previously_swi(raw); @@ -2246,20 +2246,20 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio result = process_armv7_arm_advanced_simd_element_or_structure_load_store_instructions(raw); else if ((op1 & b1110111) == b1000001) - result = g_undef_instruction_new(IBS_NOP); + result = g_undef_instruction_new(IEB_NOP); else if ((op1 & b1110111) == b1000101) result = armv7_read_arm_instr_a8_pli_immediate_literal(raw); else if ((op1 & b1110011) == b1000011) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); else if ((op1 & b1110111) == b1010101) { if (rn != b1111) result = armv7_read_arm_instr_a8_pld_pldw_immediate(raw); else - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); } @@ -2273,18 +2273,18 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio } else if (op1 == b1010011) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); else if (op1 == b1010111) { if (op2 == b0000) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); else if (op2 == b0001) result = armv7_read_arm_instr_a8_clrex(raw); else if ((op2 & b1110) == b0010) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); else if (op2 == b0100) result = armv7_read_arm_instr_a8_dsb(raw); @@ -2296,18 +2296,18 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio result = armv7_read_arm_instr_a8_isb(raw); else if (op2 == b0111) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); else if ((op2 & b1000) == b1000) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); } else if ((op1 & b1111011) == b1011011) - result = g_undef_instruction_new(IBS_UNPREDICTABLE); + result = g_undef_instruction_new(IEB_UNPREDICTABLE); else if ((op1 & b1110111) == b1100001 && (op2 & b0001) == b0000) - result = g_undef_instruction_new(IBS_NOP); + result = g_undef_instruction_new(IEB_NOP); else if ((op1 & b1110111) == b1100101 && (op2 & b0001) == b0000) result = armv7_read_arm_instr_a8_pli_register(raw); @@ -3157,7 +3157,7 @@ static GArchInstruction *process_armv7_arm_one_register_and_a_modified_immediate result = armv7_read_arm_instr_a8_vmov_immediate(raw); else if (cmode == b1111) - result = g_undef_instruction_new(IBS_UNDEFINED); + result = g_undef_instruction_new(IEB_UNDEFINED); } diff --git a/plugins/arm/v7/thumb_32.c b/plugins/arm/v7/thumb_32.c index 74c2a84..ae5f1fb 100644 --- a/plugins/arm/v7/thumb_32.c +++ b/plugins/arm/v7/thumb_32.c @@ -27,7 +27,7 @@ #include -#include +#include #include @@ -216,7 +216,7 @@ GArchInstruction *process_armv7_thumb_32_instruction_set_encoding(uint32_t raw) result = process_armv7_thumb_32_load_word(raw); else if ((op2 & b1100111) == b0000111) - result = g_undef_instruction_new(IBS_UNDEFINED); + result = g_undef_instruction_new(IEB_UNDEFINED); else if ((op2 & b1110001) == b0010000) result = process_armv7_thumb_32_advanced_simd_element_or_structure_load_store_instructions(raw); @@ -1023,7 +1023,7 @@ static GArchInstruction *process_armv7_thumb_32_load_halfword_memory_hints(uint3 result = armv7_read_thumb_32_instr_a8_ldrsh_literal(raw); else/* if (rt == b1111)*/ - result = g_undef_instruction_new(IBS_NOP); + result = g_undef_instruction_new(IEB_NOP); } @@ -1078,10 +1078,10 @@ static GArchInstruction *process_armv7_thumb_32_load_halfword_memory_hints(uint3 result = armv7_read_thumb_32_instr_a8_ldrsht(raw); else if (op2 == b000000 && rt == b1111) - result = g_undef_instruction_new(IBS_NOP); + result = g_undef_instruction_new(IEB_NOP); else if ((op2 & b111100) == b110000 && rt == b1111) - result = g_undef_instruction_new(IBS_NOP); + result = g_undef_instruction_new(IEB_NOP); } @@ -1091,7 +1091,7 @@ static GArchInstruction *process_armv7_thumb_32_load_halfword_memory_hints(uint3 result = armv7_read_thumb_32_instr_a8_ldrsh_immediate(raw); else/* if (rt == b1111)*/ - result = g_undef_instruction_new(IBS_NOP); + result = g_undef_instruction_new(IEB_NOP); } @@ -2243,7 +2243,7 @@ static GArchInstruction *process_armv7_thumb_32_coprocessor_advanced_simd_and_fl op = (raw >> 4) & 0x1; if ((op1 & b111110) == b000000) - result = g_undef_instruction_new(IBS_UNDEFINED); + result = g_undef_instruction_new(IEB_UNDEFINED); else if ((op1 & b110000) == b110000) result = process_armv7_thumb_32_advanced_simd_data_processing_instructions(raw); @@ -3142,7 +3142,7 @@ static GArchInstruction *process_armv7_thumb_32_one_register_and_a_modified_imme result = armv7_read_thumb_32_instr_a8_vmov_immediate(raw); else if (cmode == b1111) - result = g_undef_instruction_new(IBS_UNDEFINED); + result = g_undef_instruction_new(IEB_UNDEFINED); } diff --git a/plugins/pychrysalide/arch/Makefile.am b/plugins/pychrysalide/arch/Makefile.am index e167459..da78572 100644 --- a/plugins/pychrysalide/arch/Makefile.am +++ b/plugins/pychrysalide/arch/Makefile.am @@ -12,10 +12,10 @@ libpychrysaarch_la_SOURCES = \ processor.h processor.c \ raw.h raw.c \ register.h register.c \ - undefined.h undefined.c \ vmpa.h vmpa.c libpychrysaarch_la_LIBADD = \ + instructions/libpychrysaarchinstructions.la \ operands/libpychrysaarchoperands.la libpychrysaarch_la_LDFLAGS = @@ -31,4 +31,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = operands +SUBDIRS = instructions operands diff --git a/plugins/pychrysalide/arch/instructions/Makefile.am b/plugins/pychrysalide/arch/instructions/Makefile.am new file mode 100644 index 0000000..885f96e --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/Makefile.am @@ -0,0 +1,24 @@ + +noinst_LTLIBRARIES = libpychrysaarchinstructions.la + +libpychrysaarchinstructions_la_SOURCES = \ + constants.h constants.c \ + module.h module.c \ + undefined.h undefined.c + +libpychrysaarchinstructions_la_LIBADD = + +libpychrysaarchinstructions_la_LDFLAGS = + + +devdir = $(includedir)/chrysalide-$(subdir) + +dev_HEADERS = $(libpychrysaarchinstructions_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/arch/instructions/constants.c b/plugins/pychrysalide/arch/instructions/constants.c new file mode 100644 index 0000000..1f6a1d2 --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/constants.c @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.c - ajout des constantes de base pour les instructions + * + * Copyright (C) 2020 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "constants.h" + + +#include + + +#include "../../helpers.h" + + + +/****************************************************************************** +* * +* Paramètres : type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes liées aux comportements erratiques. * +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_undefined_instruction_constants(PyTypeObject *type) +{ + bool result; /* Bilan à retourner */ + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "NOP", IEB_NOP); + if (result) result = add_const_to_group(values, "UNDEFINED", IEB_UNDEFINED); + if (result) result = add_const_to_group(values, "UNPREDICTABLE", IEB_UNPREDICTABLE); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, false, "InstrExpectedBehavior", values, + "List of possible behaviors of undefined instructions."); + + exit: + + return result; + +} diff --git a/plugins/pychrysalide/arch/instructions/constants.h b/plugins/pychrysalide/arch/instructions/constants.h new file mode 100644 index 0000000..c25f3f8 --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/constants.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.h - prototypes pour l'ajout des constantes de base pour les instructions + * + * Copyright (C) 2020 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_CONSTANTS_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_CONSTANTS_H + + +#include +#include + + + +/* Définit les constantes liées aux comportements erratiques. */ +bool define_undefined_instruction_constants(PyTypeObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_CONSTANTS_H */ diff --git a/plugins/pychrysalide/arch/instructions/module.c b/plugins/pychrysalide/arch/instructions/module.c new file mode 100644 index 0000000..13a9c8e --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/module.c @@ -0,0 +1,104 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire instructions en tant que module + * + * Copyright (C) 2019-2020 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "module.h" + + +#include + + +#include "undefined.h" +#include "../../helpers.h" + + + +/****************************************************************************** +* * +* Paramètres : super = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'arch.instructions' à un module Python. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_arch_instructions_module(PyObject *super) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Sous-module mis en place */ + +#define PYCHRYSALIDE_ARCH_INSTRUCTIONS_DOC \ + "This module contains implementations for most basic instructions.\n" \ + "\n" \ + "Basic instructions include non executable instructions such as" \ + " pychrysalide.arch.RawInstruction, used for managing raw bytes in a" \ + " binary content." + + static PyModuleDef py_chrysalide_arch_instructions_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.arch.instructions", + .m_doc = PYCHRYSALIDE_ARCH_INSTRUCTIONS_DOC, + + .m_size = -1, + + }; + + module = build_python_module(super, &py_chrysalide_arch_instructions_module); + + result = (module != NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Intègre les objets du module 'arch.instructions'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool populate_arch_instructions_module(void) +{ + bool result; /* Bilan à retourner */ + + result = true; + + if (result) result = ensure_python_undefined_instruction_is_registered(); + + assert(result); + + return result; + +} diff --git a/plugins/pychrysalide/arch/instructions/module.h b/plugins/pychrysalide/arch/instructions/module.h new file mode 100644 index 0000000..42d6423 --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/module.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire instructions en tant que module + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_MODULE_H + + +#include +#include + + + +/* Ajoute le module 'arch.instructions' à un module Python. */ +bool add_arch_instructions_module(PyObject *); + +/* Intègre les objets du module 'arch.instructions'. */ +bool populate_arch_instructions_module(void); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_MODULE_H */ diff --git a/plugins/pychrysalide/arch/instructions/undefined.c b/plugins/pychrysalide/arch/instructions/undefined.c new file mode 100644 index 0000000..a2c989e --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/undefined.c @@ -0,0 +1,352 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * undefined.c - équivalent Python du fichier "arch/instructions/undefined.h" + * + * Copyright (C) 2019 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 "undefined.h" + + +#include + + +#include +#include +#include + + +#include "constants.h" +#include "../instruction.h" +#include "../../access.h" +#include "../../helpers.h" + + + +/* Accompagne la création d'une instance dérivée en Python. */ +static PyObject *py_undef_instruction_new(PyTypeObject *, PyObject *, PyObject *); + +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_undef_instruction_init(PyObject *, PyObject *, PyObject *); + +/* Indique le type de conséquences réél de l'instruction. */ +static PyObject *py_undef_instruction_get_behavior(PyObject *, void *); + + + +/****************************************************************************** +* * +* Paramètres : type = type du nouvel objet à mettre en place. * +* args = éventuelle liste d'arguments. * +* kwds = éventuel dictionnaire de valeurs mises à disposition. * +* * +* Description : Accompagne la création d'une instance dérivée en Python. * +* * +* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_undef_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Objet à retourner */ + PyTypeObject *base; /* Type de base à dériver */ + bool first_time; /* Evite les multiples passages*/ + GType gtype; /* Nouveau type de processeur */ + bool status; /* Bilan d'un enregistrement */ + + /* Validations diverses */ + + base = get_python_undefined_instruction_type(); + + if (type == base) + goto simple_way; + + /* Mise en place d'un type dédié */ + + first_time = (g_type_from_name(type->tp_name) == 0); + + gtype = build_dynamic_type(G_TYPE_UNDEF_INSTRUCTION, type->tp_name, NULL, NULL, NULL); + + if (first_time) + { + status = register_class_for_dynamic_pygobject(gtype, type, base); + + if (!status) + { + result = NULL; + goto exit; + } + + } + + /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + + simple_way: + + result = PyType_GenericNew(type, args, kwds); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet à initialiser (théoriquement). * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Initialise une instance sur la base du dérivé de GObject. * +* * +* Retour : 0. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + unsigned long behavior; /* Conséquence pour l'instruct°*/ + int ret; /* Bilan de lecture des args. */ + PyObject *new_args; /* Nouveaux arguments épurés */ + PyObject *new_kwds; /* Nouveau dictionnaire épuré */ + GUndefInstruction *instr; /* Instruction à manipuler */ + undef_obj_extra *extra; /* Données insérées à modifier */ + + static char *kwlist[] = { "behavior", NULL }; + +#define UNDEF_INSTRUCTION_DOC \ + "UndefInstruction represents all kinds of instructions which are" \ + " officially not part of a runnable instruction set.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " UndefInstruction(behavior)" \ + "\n" \ + "Where behavior is a" \ + " pychrysalide.arch.instructions.UndefInstruction.InstrExpectedBehavior" \ + " constant describing the state of the CPU once the instruction is run." + + /* Récupération des paramètres */ + + ret = PyArg_ParseTupleAndKeywords(args, kwds, "k", kwlist, &behavior); + if (!ret) return -1; + + /* Initialisation d'un objet GLib */ + + new_args = PyTuple_New(0); + new_kwds = PyDict_New(); + + ret = PyGObject_Type.tp_init(self, new_args, new_kwds); + + Py_DECREF(new_kwds); + Py_DECREF(new_args); + + if (ret == -1) return -1; + + /* Eléments de base */ + + instr = G_UNDEF_INSTRUCTION(pygobject_get(self)); + + extra = GET_UNDEF_INSTR_EXTRA(instr); + + extra->behavior = behavior; + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une instruction. * +* closure = adresse non utilisée ici. * +* * +* Description : Indique le type de conséquences réél de l'instruction. * +* * +* Retour : Etat réel du CPU après l'exécution de l'instruction. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_undef_instruction_get_behavior(PyObject *self, void *closure) +{ + PyObject *result; /* Conversion à retourner */ + GUndefInstruction *instr; /* Version native */ + InstrExpectedBehavior behavior; /* Comportement attendu */ + +#define UNDEF_INSTRUCTION_BEHAVIOR_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + behavior, py_undef_instruction, \ + "Consequence carried by the undefined instruction.\n" \ + "\n" \ + "The result is provided as a" \ + " pychrysalide.arch.instructions.UndefInstruction.InstrExpectedBehavior" \ + " constant." \ +) + + instr = G_UNDEF_INSTRUCTION(pygobject_get(self)); + behavior = g_undef_instruction_get_behavior(instr); + + result = cast_with_constants_group_from_type(get_python_undefined_instruction_type(), + "InstrExpectedBehavior", behavior); + + 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_undefined_instruction_type(void) +{ + static PyMethodDef py_undefined_instruction_methods[] = { + { NULL } + }; + + static PyGetSetDef py_undefined_instruction_getseters[] = { + UNDEF_INSTRUCTION_BEHAVIOR_ATTRIB, + { NULL } + }; + + static PyTypeObject py_undefined_instruction_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.arch.instructions.UndefInstruction", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = UNDEF_INSTRUCTION_DOC, + + .tp_methods = py_undefined_instruction_methods, + .tp_getset = py_undefined_instruction_getseters, + + .tp_init = py_undef_instruction_init, + .tp_new = py_undef_instruction_new, + + }; + + return &py_undefined_instruction_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_undefined_instruction_is_registered(void) +{ + PyTypeObject *type; /* Type Python 'UndefinedInstruction'*/ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_undefined_instruction_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.arch.instructions"); + + dict = PyModule_GetDict(module); + + if (!ensure_python_arch_instruction_is_registered()) + return false; + + if (!register_class_for_pygobject(dict, G_TYPE_UNDEF_INSTRUCTION, type, get_python_arch_instruction_type())) + return false; + + if (!define_undefined_instruction_constants(type)) + return false; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en instruction non définie. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_undefined_instruction(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_undefined_instruction_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to undefined instruction"); + break; + + case 1: + *((GUndefInstruction **)dst) = G_UNDEF_INSTRUCTION(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/pychrysalide/arch/instructions/undefined.h b/plugins/pychrysalide/arch/instructions/undefined.h new file mode 100644 index 0000000..4e9090c --- /dev/null +++ b/plugins/pychrysalide/arch/instructions/undefined.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * undefined.h - prototypes pour l'équivalent Python du fichier "arch/instructions/undefined.h" + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_UNDEFINED_H +#define _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_UNDEFINED_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_undefined_instruction_type(void); + +/* Prend en charge l'objet 'pychrysalide.arch.UndefinedInstruction'. */ +bool ensure_python_undefined_instruction_is_registered(void); + +/* Tente de convertir en instruction non définie. */ +int convert_to_undefined_instruction(PyObject *, void *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_INSTRUCTIONS_UNDEFINED_H */ diff --git a/plugins/pychrysalide/arch/module.c b/plugins/pychrysalide/arch/module.c index 093efe2..05942a5 100644 --- a/plugins/pychrysalide/arch/module.c +++ b/plugins/pychrysalide/arch/module.c @@ -40,8 +40,8 @@ #include "processor.h" #include "raw.h" #include "register.h" -#include "undefined.h" #include "vmpa.h" +#include "instructions/module.h" #include "operands/module.h" #include "../helpers.h" @@ -140,6 +140,7 @@ bool add_arch_module(PyObject *super) result = (module != NULL); + if (result) result = add_arch_instructions_module(module); if (result) result = add_arch_operands_module(module); if (result) result = py_base_define_constants(Py_TYPE(module)); @@ -175,10 +176,10 @@ bool populate_arch_module(void) if (result) result = ensure_python_arch_processor_is_registered(); if (result) result = ensure_python_raw_instruction_is_registered(); if (result) result = ensure_python_arch_register_is_registered(); - if (result) result = ensure_python_undefined_instruction_is_registered(); if (result) result = ensure_python_vmpa_is_registered(); if (result) result = ensure_python_mrange_is_registered(); + if (result) result = populate_arch_instructions_module(); if (result) result = populate_arch_operands_module(); assert(result); diff --git a/plugins/pychrysalide/arch/operands/module.c b/plugins/pychrysalide/arch/operands/module.c index 10477ed..cbd0bde 100644 --- a/plugins/pychrysalide/arch/operands/module.c +++ b/plugins/pychrysalide/arch/operands/module.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * module.c - intégration du répertoire arch en tant que module + * module.c - intégration du répertoire operands en tant que module * * Copyright (C) 2019-2020 Cyrille Bagard * @@ -53,10 +53,10 @@ bool add_arch_operands_module(PyObject *super) bool result; /* Bilan à retourner */ PyObject *module; /* Sous-module mis en place */ -#define PYCHRYSALIDE_ARCH_OPERANDS_DOC \ - "This module contains implementations for most common operand usages." \ - "\n" \ - "These operands are usually added to objects such as" \ +#define PYCHRYSALIDE_ARCH_OPERANDS_DOC \ + "This module contains implementations for most common operand usages.\n" \ + "\n" \ + "These operands are usually added to objects such as" \ " pychrysalide.arch.ArchInstruction when disassembling a binary." static PyModuleDef py_chrysalide_arch_operands_module = { diff --git a/plugins/pychrysalide/arch/undefined.c b/plugins/pychrysalide/arch/undefined.c deleted file mode 100644 index 1be5ccc..0000000 --- a/plugins/pychrysalide/arch/undefined.c +++ /dev/null @@ -1,367 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * undefined.c - équivalent Python du fichier "arch/undefined.h" - * - * Copyright (C) 2019 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 "undefined.h" - - -#include - - -#include -#include -#include - - -#include "instruction.h" -#include "../access.h" -#include "../helpers.h" - - - -/* Accompagne la création d'une instance dérivée en Python. */ -static PyObject *py_undef_instruction_new(PyTypeObject *, PyObject *, PyObject *); - -/* Initialise une instance sur la base du dérivé de GObject. */ -static int py_undef_instruction_init(PyObject *, PyObject *, PyObject *); - -/* Indique le type de conséquences réél de l'instruction. */ -static PyObject *py_undef_instruction_get_status(PyObject *, void *); - -/* Définit les constantes pour les instructions non définies. */ -static bool py_undefined_instruction_define_constants(PyTypeObject *); - - - -/****************************************************************************** -* * -* Paramètres : type = type du nouvel objet à mettre en place. * -* args = éventuelle liste d'arguments. * -* kwds = éventuel dictionnaire de valeurs mises à disposition. * -* * -* Description : Accompagne la création d'une instance dérivée en Python. * -* * -* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_undef_instruction_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Objet à retourner */ - PyTypeObject *base; /* Type de base à dériver */ - bool first_time; /* Evite les multiples passages*/ - GType gtype; /* Nouveau type de processeur */ - bool status; /* Bilan d'un enregistrement */ - - /* Validations diverses */ - - base = get_python_undefined_instruction_type(); - - if (type == base) - goto simple_way; - - /* Mise en place d'un type dédié */ - - first_time = (g_type_from_name(type->tp_name) == 0); - - gtype = build_dynamic_type(G_TYPE_UNDEF_INSTRUCTION, type->tp_name, NULL, NULL, NULL); - - if (first_time) - { - status = register_class_for_dynamic_pygobject(gtype, type, base); - - if (!status) - { - result = NULL; - goto exit; - } - - } - - /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ - - simple_way: - - result = PyType_GenericNew(type, args, kwds); - - exit: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet à initialiser (théoriquement). * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Initialise une instance sur la base du dérivé de GObject. * -* * -* Retour : 0. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_undef_instruction_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - unsigned long status; /* Conséquence pour l'instruct°*/ - int ret; /* Bilan de lecture des args. */ - PyObject *new_args; /* Nouveaux arguments épurés */ - PyObject *new_kwds; /* Nouveau dictionnaire épuré */ - GUndefInstruction *instr; /* Instruction à manipuler */ - - static char *kwlist[] = { "status", NULL }; - - /* Récupération des paramètres */ - - ret = PyArg_ParseTupleAndKeywords(args, kwds, "k", kwlist, &status); - if (!ret) return -1; - - /* Initialisation d'un objet GLib */ - - new_args = PyTuple_New(0); - new_kwds = PyDict_New(); - - ret = PyGObject_Type.tp_init(self, new_args, new_kwds); - - Py_DECREF(new_kwds); - Py_DECREF(new_args); - - if (ret == -1) return -1; - - /* Eléments de base */ - - instr = G_UNDEF_INSTRUCTION(pygobject_get(self)); - - instr->status = status; - - return 0; - -} - - -/****************************************************************************** -* * -* Paramètres : self = classe représentant une instruction. * -* closure = adresse non utilisée ici. * -* * -* Description : Indique le type de conséquences réél de l'instruction. * -* * -* Retour : Etat réel du CPU après l'exécution de l'instruction. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_undef_instruction_get_status(PyObject *self, void *closure) -{ - PyObject *result; /* Conversion à retourner */ - GUndefInstruction *instr; /* Version native */ - InstrBehaviorStatus status; /* Etat de la définition */ - - instr = G_UNDEF_INSTRUCTION(pygobject_get(self)); - - status = g_undef_instruction_get_status(instr); - - result = PyLong_FromLong(status); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : obj_type = type dont le dictionnaire est à compléter. * -* * -* Description : Définit les constantes pour les instructions non définies. * -* * -* Retour : true en cas de succès de l'opération, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool py_undefined_instruction_define_constants(PyTypeObject *obj_type) -{ - bool result; /* Bilan à retourner */ - - result = true; - - if (result) result = PyDict_AddStringMacro(obj_type, BPC_RAW); - if (result) result = PyDict_AddStringMacro(obj_type, BPC_CODE); - if (result) result = PyDict_AddStringMacro(obj_type, BPC_DATA); - if (result) result = PyDict_AddStringMacro(obj_type, BPC_DATA_RO); - if (result) result = PyDict_AddStringMacro(obj_type, BPC_DISASS_ERROR); - - if (result) result = PyDict_AddULongMacro(obj_type, PAC_NONE); - if (result) result = PyDict_AddULongMacro(obj_type, PAC_READ); - if (result) result = PyDict_AddULongMacro(obj_type, PAC_WRITE); - if (result) result = PyDict_AddULongMacro(obj_type, PAC_EXEC); - if (result) result = PyDict_AddULongMacro(obj_type, PAC_ALL); - - 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_undefined_instruction_type(void) -{ - static PyMethodDef py_undefined_instruction_methods[] = { - { NULL } - }; - - static PyGetSetDef py_undefined_instruction_getseters[] = { - { - "status", py_undef_instruction_get_status, NULL, - "Consequence carried by the undefined instruction.", NULL - }, - { NULL } - }; - - static PyTypeObject py_undefined_instruction_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.arch.UndefInstruction", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = "PyChrysalide undefined instruction for a all architectures.", - - .tp_methods = py_undefined_instruction_methods, - .tp_getset = py_undefined_instruction_getseters, - - .tp_init = py_undef_instruction_init, - .tp_new = py_undef_instruction_new, - - }; - - return &py_undefined_instruction_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.arch.ArchInstruction'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool ensure_python_undefined_instruction_is_registered(void) -{ - PyTypeObject *type; /* Type Python 'UndefinedInstruction'*/ - PyObject *module; /* Module à recompléter */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_undefined_instruction_type(); - - if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) - { - module = get_access_to_python_module("pychrysalide.arch"); - - dict = PyModule_GetDict(module); - - if (!ensure_python_arch_instruction_is_registered()) - return false; - - if (!register_class_for_pygobject(dict, G_TYPE_UNDEF_INSTRUCTION, type, get_python_arch_instruction_type())) - return false; - - if (!py_undefined_instruction_define_constants(type)) - return false; - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : arg = argument quelconque à tenter de convertir. * -* dst = destination des valeurs récupérées en cas de succès. * -* * -* Description : Tente de convertir en instruction non définie. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_undefined_instruction(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_undefined_instruction_type()); - - switch (result) - { - case -1: - /* L'exception est déjà fixée par Python */ - result = 0; - break; - - case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to undefined instruction"); - break; - - case 1: - *((GUndefInstruction **)dst) = G_UNDEF_INSTRUCTION(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/pychrysalide/arch/undefined.h b/plugins/pychrysalide/arch/undefined.h deleted file mode 100644 index 57b3839..0000000 --- a/plugins/pychrysalide/arch/undefined.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * undefined.h - prototypes pour l'équivalent Python du fichier "arch/undefined.h" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_UNDEFINED_H -#define _PLUGINS_PYCHRYSALIDE_ARCH_UNDEFINED_H - - -#include -#include - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_undefined_instruction_type(void); - -/* Prend en charge l'objet 'pychrysalide.arch.UndefinedInstruction'. */ -bool ensure_python_undefined_instruction_is_registered(void); - -/* Tente de convertir en instruction non définie. */ -int convert_to_undefined_instruction(PyObject *, void *); - - - -#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_UNDEFINED_H */ diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index e22c1d8..46f78e8 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -23,11 +23,10 @@ libarch_la_SOURCES = \ register.h register.c \ storage.h storage.c \ target.h target.c \ - undefined-int.h \ - undefined.h undefined.c \ vmpa.h vmpa.c libarch_la_LIBADD = \ + instructions/libarchinstructions.la \ operands/libarchoperands.la libarch_la_LDFLAGS = @@ -43,4 +42,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = operands +SUBDIRS = instructions operands diff --git a/src/arch/instructions/Makefile.am b/src/arch/instructions/Makefile.am new file mode 100644 index 0000000..c060c7e --- /dev/null +++ b/src/arch/instructions/Makefile.am @@ -0,0 +1,23 @@ + +noinst_LTLIBRARIES = libarchinstructions.la + +libarchinstructions_la_SOURCES = \ + undefined-int.h \ + undefined.h undefined.c + +libarchinstructions_la_LIBADD = + +libarchinstructions_la_LDFLAGS = + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=%) + +dev_HEADERS = $(libarchinstructions_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + + +SUBDIRS = diff --git a/src/arch/instructions/undefined-int.h b/src/arch/instructions/undefined-int.h new file mode 100644 index 0000000..8a648cf --- /dev/null +++ b/src/arch/instructions/undefined-int.h @@ -0,0 +1,94 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * undefined-int.h - prototypes pour la définition générique interne des instructions au comportement non défini + * + * Copyright (C) 2019 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 _ARCH_INSTRUCTIONS_UNDEFINED_INT_H +#define _ARCH_INSTRUCTIONS_UNDEFINED_INT_H + + +#include "undefined.h" +#include "../instruction-int.h" +#include "../../glibext/objhole.h" + + + +/* Informations glissées dans la structure GObject de GArchInstruction */ +typedef union _undef_obj_extra +{ + struct + { + InstrExpectedBehavior behavior; /* Conséquences réelles */ + + }; + + gint lock; /* Gestion d'accès aux fanions */ + +} undef_obj_extra; + +/* Définition générique d'une instruction au comportement non défini (instance) */ +struct _GUndefInstruction +{ + GArchInstruction parent; /* A laisser en premier */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + + /** + * L'inclusion des informations suivantes dépend de l'architecture. + * + * Si la structure GObject possède un trou, on remplit de préférence + * ce dernier. + */ + + undef_obj_extra extra; /* Externalisation embarquée */ + +#endif + +}; + +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define INIT_UNDEF_INSTR_EXTRA(ins) ins->extra.lock = 0 + +# define GET_UNDEF_INSTR_EXTRA(ins) &ins->extra + +#else + +# define INIT_UNDEF_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins)) + +# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_obj_extra) + +#endif + +/* Définition générique d'une instruction au comportement non défini (classe) */ +struct _GUndefInstructionClass +{ + GArchInstructionClass parent; /* A laisser en premier */ + +}; + + + +#endif /* _ARCH_INSTRUCTIONS_UNDEFINED_INT_H */ diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c new file mode 100644 index 0000000..da2f73e --- /dev/null +++ b/src/arch/instructions/undefined.c @@ -0,0 +1,421 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * undefined.c - instructions au comportement non défini + * + * Copyright (C) 2016-2019 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 "undefined.h" + + +#include + + +#include + + +#include "undefined-int.h" + + + +/* Initialise la classe des instructions non définies. */ +static void g_undef_instruction_class_init(GUndefInstructionClass *); + +/* Initialise une instance d'instruction non définie. */ +static void g_undef_instruction_init(GUndefInstruction *); + +/* Supprime toutes les références externes. */ +static void g_undef_instruction_dispose(GUndefInstruction *); + +/* Procède à la libération totale de la mémoire. */ +static void g_undef_instruction_finalize(GUndefInstruction *); + +/* Indique l'encodage d'une instruction de façon détaillée. */ +static const char *g_undef_instruction_get_encoding(const GUndefInstruction *); + +/* Fournit le nom humain de l'instruction manipulée. */ +static const char *g_undef_instruction_get_keyword(const GUndefInstruction *); + + + +/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ + + +/* Charge une instruction depuis une mémoire tampon. */ +static bool g_undef_instruction_unserialize(GUndefInstruction *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde une instruction dans une mémoire tampon. */ +static bool g_undef_instruction_serialize(GUndefInstruction *, GAsmStorage *, packed_buffer *); + + + +/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ + + +/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ +static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t, size_t, const GBinContent *); + + + +/* ---------------------------------------------------------------------------------- */ +/* INSTRUCTION INCONNUE / DONNEES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une instruction au comportement non défini. */ +G_DEFINE_TYPE(GUndefInstruction, g_undef_instruction, G_TYPE_ARCH_INSTRUCTION); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des instructions non définies. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_undef_instruction_class_init(GUndefInstructionClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_undef_instruction_dispose; + object->finalize = (GObjectFinalizeFunc)g_undef_instruction_finalize; + + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->get_encoding = (get_instruction_encoding_fc)g_undef_instruction_get_encoding; + instr->get_keyword = (get_instruction_keyword_fc)g_undef_instruction_get_keyword; + + instr->unserialize = (unserialize_instruction_fc)g_undef_instruction_unserialize; + instr->serialize = (serialize_instruction_fc)g_undef_instruction_serialize; + + instr->print = (print_instruction_fc)g_undef_instruction_print; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance à initialiser. * +* * +* Description : Initialise une instance d'instruction non définie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_undef_instruction_init(GUndefInstruction *instr) +{ + INIT_ARCH_INSTR_EXTRA(instr); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_undef_instruction_dispose(GUndefInstruction *instr) +{ + G_OBJECT_CLASS(g_undef_instruction_parent_class)->dispose(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_undef_instruction_finalize(GUndefInstruction *instr) +{ + G_OBJECT_CLASS(g_undef_instruction_parent_class)->finalize(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * +* Paramètres : behavior = état réel du CPU après une passe de l'instruction.* +* * +* Description : Crée une instruction au comportement nominalement indéfini. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior) +{ + GArchInstruction *result; /* Instruction à retourner */ + undef_obj_extra *extra; /* Données insérées à modifier */ + + result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL); + + extra = GET_UNDEF_INSTR_EXTRA(result); + + extra->behavior = behavior; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction quelconque à consulter. * +* * +* Description : Indique l'encodage d'une instruction de façon détaillée. * +* * +* Retour : Description humaine de l'encodage utilisé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_undef_instruction_get_encoding(const GUndefInstruction *instr) +{ + const char *result; /* Description à retourner */ + + result = _("Undefined"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* * +* Description : Fournit le nom humain de l'instruction manipulée. * +* * +* Retour : Mot clef de bas niveau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr) +{ + const char *result; /* Désignation à retourner */ + undef_obj_extra *extra; /* Données insérées à consulter*/ + + extra = GET_UNDEF_INSTR_EXTRA(instr); + + switch (extra->behavior) + { + case IEB_NOP: + result = "nop"; + break; + + case IEB_UNDEFINED: + result = "undefined"; + break; + + case IEB_UNPREDICTABLE: + result = "unpredictable"; + break; + + default: + assert(false); + result = NULL; + break; + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* format = format binaire chargé associé à l'architecture. * +* pbuf = zone tampon à remplir. * +* * +* Description : Charge une instruction depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + undef_obj_extra *extra; /* Données insérées à modifier */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); + + result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf); + + if (result) + { + extra = GET_UNDEF_INSTR_EXTRA(instr); + + result = extract_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à consulter. * +* storage = mécanisme de sauvegarde à manipuler. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde une instruction dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage *storage, packed_buffer *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + undef_obj_extra *extra; /* Données insérées à consulter*/ + + parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); + + result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf); + + if (result) + { + extra = GET_UNDEF_INSTR_EXTRA(instr); + + result = extend_packed_buffer(pbuf, &extra->behavior, sizeof(InstrExpectedBehavior), true); + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OFFRE DE CAPACITES DE GENERATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à représenter. * +* line = ligne de rendu à compléter. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* content = éventuel contenu binaire brut à imprimer. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content) +{ + GArchInstruction *base; /* Version de base */ + const char *key; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ + + base = G_ARCH_INSTRUCTION(instr); + + g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); + + g_buffer_line_fill_content(line, content, &base->range, VMPA_NO_PHYSICAL); + + /* Instruction proprement dite */ + + key = g_arch_instruction_get_keyword(base); + klen = strlen(key); + + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à consulter. * +* * +* Description : Indique le type de conséquences réél de l'instruction. * +* * +* Retour : Etat réel du CPU après l'exécution de l'instruction. * +* * +* Remarques : - * +* * +******************************************************************************/ + +InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *instr) +{ + InstrExpectedBehavior result; /* Comportement à retourner */ + undef_obj_extra *extra; /* Données insérées à consulter*/ + + extra = GET_UNDEF_INSTR_EXTRA(instr); + + result = extra->behavior; + + return result; + +} diff --git a/src/arch/instructions/undefined.h b/src/arch/instructions/undefined.h new file mode 100644 index 0000000..5aa9bec --- /dev/null +++ b/src/arch/instructions/undefined.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * undefined.h - prototypes pour les instructions au comportement non défini + * + * Copyright (C) 2016-2019 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 _ARCH_INSTRUCTIONS_UNDEFINED_H +#define _ARCH_INSTRUCTIONS_UNDEFINED_H + + +#include + + +#include "../instruction.h" +#include "../vmpa.h" + + + +#define G_TYPE_UNDEF_INSTRUCTION g_undef_instruction_get_type() +#define G_UNDEF_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstruction)) +#define G_IS_UNDEF_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_UNDEF_INSTRUCTION)) +#define G_UNDEF_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass)) +#define G_IS_UNDEF_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_UNDEF_INSTRUCTION)) +#define G_UNDEF_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass)) + + +/* Définition générique d'une instruction au comportement non défini (instance) */ +typedef struct _GUndefInstruction GUndefInstruction; + +/* Définition générique d'une instruction au comportement non défini (classe) */ +typedef struct _GUndefInstructionClass GUndefInstructionClass; + + +/* Etat précis de l'instruction */ +typedef enum _InstrExpectedBehavior +{ + IEB_NOP, + IEB_UNDEFINED, + IEB_UNPREDICTABLE, + +} InstrExpectedBehavior; + + +/* Indique le type défini pour une instruction au comportement non défini. */ +GType g_undef_instruction_get_type(void); + +/* Crée une instruction au comportement nominalement indéfini. */ +GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior); + +/* Indique le type de conséquences réél de l'instruction. */ +InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *); + + + +#endif /* _ARCH_INSTRUCTIONS_UNDEFINED_H */ diff --git a/src/arch/undefined-int.h b/src/arch/undefined-int.h deleted file mode 100644 index 0bd3e0c..0000000 --- a/src/arch/undefined-int.h +++ /dev/null @@ -1,51 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * undefined-int.h - prototypes pour la définition générique interne des instructions au comportement non défini - * - * Copyright (C) 2019 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 _ARCH_UNDEFINED_INT_H -#define _ARCH_UNDEFINED_INT_H - - -#include "undefined.h" -#include "instruction-int.h" - - - -/* Définition générique d'une instruction au comportement non défini (instance) */ -struct _GUndefInstruction -{ - GArchInstruction parent; /* A laisser en premier */ - - InstrBehaviorStatus status; /* Conséquences réelles */ - -}; - -/* Définition générique d'une instruction au comportement non défini (classe) */ -struct _GUndefInstructionClass -{ - GArchInstructionClass parent; /* A laisser en premier */ - -}; - - - -#endif /* _ARCH_UNDEFINED_INT_H */ diff --git a/src/arch/undefined.c b/src/arch/undefined.c deleted file mode 100644 index e64bffd..0000000 --- a/src/arch/undefined.c +++ /dev/null @@ -1,395 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * undefined.c - instructions au comportement non défini - * - * Copyright (C) 2016-2019 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 "undefined.h" - - -#include - - -#include - - -#include "undefined-int.h" - - - -/* Initialise la classe des instructions non définies. */ -static void g_undef_instruction_class_init(GUndefInstructionClass *); - -/* Initialise une instance d'instruction non définie. */ -static void g_undef_instruction_init(GUndefInstruction *); - -/* Supprime toutes les références externes. */ -static void g_undef_instruction_dispose(GUndefInstruction *); - -/* Procède à la libération totale de la mémoire. */ -static void g_undef_instruction_finalize(GUndefInstruction *); - -/* Indique l'encodage d'une instruction de façon détaillée. */ -static const char *g_undef_instruction_get_encoding(const GUndefInstruction *); - -/* Fournit le nom humain de l'instruction manipulée. */ -static const char *g_undef_instruction_get_keyword(const GUndefInstruction *); - - - -/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ - - -/* Charge une instruction depuis une mémoire tampon. */ -static bool g_undef_instruction_unserialize(GUndefInstruction *, GAsmStorage *, GBinFormat *, packed_buffer *); - -/* Sauvegarde une instruction dans une mémoire tampon. */ -static bool g_undef_instruction_serialize(GUndefInstruction *, GAsmStorage *, packed_buffer *); - - - -/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ - - -/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t, size_t, const GBinContent *); - - - -/* ---------------------------------------------------------------------------------- */ -/* INSTRUCTION INCONNUE / DONNEES */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour une instruction au comportement non défini. */ -G_DEFINE_TYPE(GUndefInstruction, g_undef_instruction, G_TYPE_ARCH_INSTRUCTION); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des instructions non définies. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_undef_instruction_class_init(GUndefInstructionClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GArchInstructionClass *instr; /* Encore une autre vision... */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_undef_instruction_dispose; - object->finalize = (GObjectFinalizeFunc)g_undef_instruction_finalize; - - instr = G_ARCH_INSTRUCTION_CLASS(klass); - - instr->get_encoding = (get_instruction_encoding_fc)g_undef_instruction_get_encoding; - instr->get_keyword = (get_instruction_keyword_fc)g_undef_instruction_get_keyword; - - instr->unserialize = (unserialize_instruction_fc)g_undef_instruction_unserialize; - instr->serialize = (serialize_instruction_fc)g_undef_instruction_serialize; - - instr->print = (print_instruction_fc)g_undef_instruction_print; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance à initialiser. * -* * -* Description : Initialise une instance d'instruction non définie. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_undef_instruction_init(GUndefInstruction *instr) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_undef_instruction_dispose(GUndefInstruction *instr) -{ - G_OBJECT_CLASS(g_undef_instruction_parent_class)->dispose(G_OBJECT(instr)); - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_undef_instruction_finalize(GUndefInstruction *instr) -{ - G_OBJECT_CLASS(g_undef_instruction_parent_class)->finalize(G_OBJECT(instr)); - -} - - -/****************************************************************************** -* * -* Paramètres : status = état réel du CPU après le passage de l'instruction. * -* * -* Description : Crée une instruction au comportement nominalement indéfini. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_undef_instruction_new(InstrBehaviorStatus status) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL); - - G_UNDEF_INSTRUCTION(result)->status = status; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction quelconque à consulter. * -* * -* Description : Indique l'encodage d'une instruction de façon détaillée. * -* * -* Retour : Description humaine de l'encodage utilisé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *g_undef_instruction_get_encoding(const GUndefInstruction *instr) -{ - const char *result; /* Description à retourner */ - - result = _("Undefined"); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à consulter. * -* * -* Description : Fournit le nom humain de l'instruction manipulée. * -* * -* Retour : Mot clef de bas niveau. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr) -{ - const char *result; /* Désignation à retourner */ - - switch (instr->status) - { - case IBS_NOP: - result = "nop"; - break; - - case IBS_UNDEFINED: - result = "undefined"; - break; - - case IBS_UNPREDICTABLE: - result = "unpredictable"; - break; - - default: - assert(false); - result = NULL; - break; - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge une instruction depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchInstructionClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); - - result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf); - - if (result) - result = extract_packed_buffer(pbuf, &instr->status, sizeof(InstrBehaviorStatus), true); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Sauvegarde une instruction dans une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage *storage, packed_buffer *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchInstructionClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class); - - result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf); - - if (result) - result = extend_packed_buffer(pbuf, &instr->status, sizeof(InstrBehaviorStatus), true); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* OFFRE DE CAPACITES DE GENERATION */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à représenter. * -* line = ligne de rendu à compléter. * -* index = indice de cette même ligne dans le tampon global. * -* repeat = indice d'utilisations successives du générateur. * -* content = éventuel contenu binaire brut à imprimer. * -* * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content) -{ - GArchInstruction *base; /* Version de base */ - const char *key; /* Mot clef principal */ - size_t klen; /* Taille de ce mot clef */ - - base = G_ARCH_INSTRUCTION(instr); - - g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); - - g_buffer_line_fill_content(line, content, &base->range, VMPA_NO_PHYSICAL); - - /* Instruction proprement dite */ - - key = g_arch_instruction_get_keyword(base); - klen = strlen(key); - - g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à consulter. * -* * -* Description : Indique le type de conséquences réél de l'instruction. * -* * -* Retour : Etat réel du CPU après l'exécution de l'instruction. * -* * -* Remarques : - * -* * -******************************************************************************/ - -InstrBehaviorStatus g_undef_instruction_get_status(const GUndefInstruction *instr) -{ - return instr->status; - -} diff --git a/src/arch/undefined.h b/src/arch/undefined.h deleted file mode 100644 index 1b32fb9..0000000 --- a/src/arch/undefined.h +++ /dev/null @@ -1,72 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * undefined.h - prototypes pour les instructions au comportement non défini - * - * Copyright (C) 2016-2019 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 _ARCH_UNDEFINED_H -#define _ARCH_UNDEFINED_H - - -#include - - -#include "instruction.h" -#include "vmpa.h" - - - -#define G_TYPE_UNDEF_INSTRUCTION g_undef_instruction_get_type() -#define G_UNDEF_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstruction)) -#define G_IS_UNDEF_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_UNDEF_INSTRUCTION)) -#define G_UNDEF_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass)) -#define G_IS_UNDEF_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_UNDEF_INSTRUCTION)) -#define G_UNDEF_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass)) - - -/* Définition générique d'une instruction au comportement non défini (instance) */ -typedef struct _GUndefInstruction GUndefInstruction; - -/* Définition générique d'une instruction au comportement non défini (classe) */ -typedef struct _GUndefInstructionClass GUndefInstructionClass; - - -/* Etat précis de l'instruction */ -typedef enum _InstrBehaviorStatus -{ - IBS_NOP, - IBS_UNDEFINED, - IBS_UNPREDICTABLE, - -} InstrBehaviorStatus; - - -/* Indique le type défini pour une instruction au comportement non défini. */ -GType g_undef_instruction_get_type(void); - -/* Crée une instruction au comportement nominalement indéfini. */ -GArchInstruction *g_undef_instruction_new(InstrBehaviorStatus); - -/* Indique le type de conséquences réél de l'instruction. */ -InstrBehaviorStatus g_undef_instruction_get_status(const GUndefInstruction *); - - - -#endif /* _ARCH_UNDEFINED_H */ diff --git a/src/core/processors.c b/src/core/processors.c index c6f3f8a..c03b98f 100644 --- a/src/core/processors.c +++ b/src/core/processors.c @@ -31,7 +31,7 @@ #include "../arch/raw.h" #include "../arch/target.h" -#include "../arch/undefined.h" +#include "../arch/instructions/undefined.h" #include "../arch/operands/immediate.h" #include "../arch/operands/register.h" -- cgit v0.11.2-87-g4458