diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2015-02-16 07:07:15 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2015-02-16 07:07:15 (GMT) | 
| commit | 635640a32fecbb9b8a5ddf239b819c022c4b9977 (patch) | |
| tree | f8fc69a2c2db411000996146536ca5cc4f54d417 | |
| parent | bf879f2562545ab7de23f9d38364b7bd4b43fb2c (diff) | |
Added a basic support for Mobicore truslets.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@472 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
43 files changed, 2388 insertions, 151 deletions
| @@ -1,3 +1,83 @@ +15-02-16  Cyrille Bagard <nocbos@gmail.com> + +	* configure.ac: +	Add the new Makefile from the 'plugins/mobicore' directory. + +	* plugins/devdbg/speed.c: +	* plugins/devdbg/speed.h: +	Fix included headers. Clean the code. + +	* plugins/Makefile.am: +	Add mobicore to SUBDIRS. + +	* plugins/mobicore/annotations.c: +	* plugins/mobicore/annotations.h: +	* plugins/mobicore/Makefile.am: +	* plugins/mobicore/mclf.c: +	* plugins/mobicore/mclf-def.h: +	* plugins/mobicore/mclf.h: +	* plugins/mobicore/mclf-int.c: +	* plugins/mobicore/mclf-int.h: +	* plugins/mobicore/mobicore.c: +	* plugins/mobicore/mobicore.h: +	* plugins/mobicore/symbols.c: +	* plugins/mobicore/symbols.h: +	New entries: add a basic support for Mobicore truslets. + +	* plugins/pychrysa/plugin.c: +	* plugins/pychrysa/pychrysa.c: +	Update code due to PGA_NONE removing. + +	* src/analysis/binary.c: +	Do not free bin_data anymore, as it not owned by the binary. + +	* src/analysis/disass/area.c: +	Disable some checks ; update code with calls to g_raw_instruction_new_array_old(). + +	* src/arch/arm/v7/processor.c: +	* src/arch/artificial.c: +	* src/arch/dalvik/operand.c: +	Update code with calls to g_raw_instruction_new_array_old(). + +	* src/arch/immediate.c: +	* src/arch/immediate.h: +	Load immediate values using the new GBinContent manager. + +	* src/arch/instruction.h: +	Update included headers. + +	* src/arch/raw.c: +	* src/arch/raw.h: +	Load raw instructions using the new GBinContent manager. + +	* src/arch/x86/operand.c: +	* src/arch/x86/operands/modrm.c: +	* src/arch/x86/operands/moffs.c: +	Update code with calls to g_raw_instruction_new_array_old(). + +	* src/core/formats.c: +	* src/core/processors.c: +	Avoid to crash when a key is set to NULL. + +	* src/format/elf/elf-int.c: +	Typo. + +	* src/format/elf/symbols.c: +	Update code with calls to g_raw_instruction_new_array_old(). + +	* src/format/format.c: +	* src/format/format-int.h: +	Store a GBinContent manager instead of a reference to a loaded binary array. + +	* src/glibext/gbincontent.c: +	* src/glibext/gbincontent.h: +	Read all basic values with respect to endianness. + +	* src/plugins/plugin.c: +	* src/plugins/plugin-def.h: +	* src/plugins/plugin-int.h: +	Define init and exit functions for plugins. +  15-02-11  Cyrille Bagard <nocbos@gmail.com>  	* plugins/pychrysa/format/elf/elf.c: diff --git a/configure.ac b/configure.ac index b8fb1e9..611ca92 100644 --- a/configure.ac +++ b/configure.ac @@ -275,6 +275,7 @@ AC_CONFIG_FILES([Makefile                   plugins/androhelpers/Makefile                   plugins/devdbg/Makefile                   plugins/govm/Makefile +                 plugins/mobicore/Makefile                   plugins/pychrysa/Makefile                   plugins/pychrysa/analysis/Makefile                   plugins/pychrysa/analysis/binaries/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 84336ca..5eadf0c 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = androhelpers devdbg pychrysa python stackvars +SUBDIRS = androhelpers devdbg mobicore pychrysa python stackvars diff --git a/plugins/devdbg/speed.c b/plugins/devdbg/speed.c index 7f9705d..e5042ea 100644 --- a/plugins/devdbg/speed.c +++ b/plugins/devdbg/speed.c @@ -31,7 +31,6 @@  #include <plugins/plugin-def.h> -#include <plugins/plugin-int.h> diff --git a/plugins/devdbg/speed.h b/plugins/devdbg/speed.h index bad7ba5..ba013f7 100644 --- a/plugins/devdbg/speed.h +++ b/plugins/devdbg/speed.h @@ -25,12 +25,8 @@  #define _PLUGINS_DEVDBG_SPEED_H -#include <gmodule.h> - -#include <analysis/binary.h>  #include <plugins/plugin.h> -#include <plugins/plugin-def.h> - +#include <plugins/plugin-int.h> @@ -39,25 +35,4 @@ G_MODULE_EXPORT void process_binary_disassembly(const GPluginModule *, PluginAct - - -#if 0 -#include <glib-object.h> -#include <gmodule.h> -#include <stdbool.h> - - - - -/* Initialise le greffon pour les bornes de routine. */ -G_MODULE_EXPORT bool init_plugin(GObject *); - -/* Fournit une indication sur le type d'opération(s) menée(s). */ -G_MODULE_EXPORT PluginAction get_plugin_action(void); - -/* Exécute une action définie sur un binaire chargé. */ -G_MODULE_EXPORT bool execute_action_on_binary(GLoadedBinary *, PluginAction); -#endif - -  #endif  /* _PLUGINS_DEVDBG_SPEED_H */ diff --git a/plugins/mobicore/Makefile.am b/plugins/mobicore/Makefile.am new file mode 100644 index 0000000..ee5cc66 --- /dev/null +++ b/plugins/mobicore/Makefile.am @@ -0,0 +1,17 @@ + +lib_LTLIBRARIES = libmobicore.la + +libmobicore_la_SOURCES =				\ +	annotations.h annotations.c			\ +	mclf-def.h							\ +	mclf-int.h mclf-int.c				\ +	mclf.h mclf.c						\ +	mobicore.h mobicore.c				\ +	symbols.h symbols.c + +libmobicore_la_CFLAGS = $(AM_CFLAGS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/mobicore/annotations.c b/plugins/mobicore/annotations.c new file mode 100644 index 0000000..94fecaf --- /dev/null +++ b/plugins/mobicore/annotations.c @@ -0,0 +1,470 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * annotations.c - enregistrement des annotations liées au format MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "annotations.h" + + +#include <malloc.h> + + +#include <i18n.h> +#include <arch/raw.h> +#include <common/extstr.h> + + +#include "mclf-int.h" + + + +/* Place des annotations sur un descripteur de segment MCLF. */ +static bool annotate_mclf_segment_descriptor(GMCLFFormat *, const char *, vmpa2t *); + +/* Place des annotations sur le début commun du binaire MCLF. */ +static bool annotate_mclf_intro(GMCLFFormat *, vmpa2t *pos); + +/* Place des annotations sur l'en-tête v1 du binaire MCLF. */ +static bool annotate_mclf_header_v1(GMCLFFormat *, vmpa2t *pos); + +/* Place des annotations sur l'en-tête du segment de code. */ +static bool annotate_mclf_text_segment_header(GMCLFFormat *format, vmpa2t *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                prefix = désignation du segment dans son ensemble.           * +*                pos    = tête de lecture à initialiser / faire évoluer. [OUT]* +*                                                                             * +*  Description : Place des annotations sur un descripteur de segment MCLF.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_mclf_segment_descriptor(GMCLFFormat *format, const char *prefix, vmpa2t *pos) +{ +    GBinContent *content;                   /* Contenu binaire à lire      */ +    GArchInstruction *instr;                /* Instruction décodée         */ +    char *text;                             /* Texte construit par étapes  */ +    GDbComment *comment;                    /* Définition de commentaire   */ +    GBinSymbol *symbol;                     /* Symbole à intégrer          */ + +    content = G_BIN_FORMAT(format)->conten_; + +    /* start */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    text = strdup(prefix); +    text = stradd(text, _(": start address")); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    free(text); + +    /* len */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    text = strdup(prefix); +    text = stradd(text, _(": length")); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    free(text); + +    return true; + +} + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pos    = tête de lecture à initialiser / faire évoluer. [OUT]* +*                                                                             * +*  Description : Place des annotations sur le début commun du binaire MCLF.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_mclf_intro(GMCLFFormat *format, vmpa2t *pos) +{ +    GBinContent *content;                   /* Contenu binaire à lire      */ +    GArchInstruction *instr;                /* Instruction décodée         */ +    GArchOperand *operand;                  /* Opérande à venir modifier   */ +    GDbComment *comment;                    /* Définition de commentaire   */ +    GBinSymbol *symbol;                     /* Symbole à intégrer          */ + +    content = G_BIN_FORMAT(format)->conten_; + +    init_vmpa(pos, 0, format->header.v1.text.start); + +    /* magic */ + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, pos, format->endian); + +    SET_IMM_DISPLAY(instr, operand, 0, IOD_CHAR); +    SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR); +    SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); +    SET_IMM_DISPLAY(instr, operand, 3, IOD_CHAR); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("MCLF magic number")); + +    /* version */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Version")); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pos    = tête de lecture à faire évoluer. [OUT]              * +*                                                                             * +*  Description : Place des annotations sur l'en-tête v1 du binaire MCLF.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_mclf_header_v1(GMCLFFormat *format, vmpa2t *pos) +{ +    GBinContent *content;                   /* Contenu binaire à lire      */ +    GArchInstruction *instr;                /* Instruction décodée         */ +    GDbComment *comment;                    /* Définition de commentaire   */ +    GBinSymbol *symbol;                     /* Symbole à intégrer          */ +    const char *text;                       /* Commentaire variable        */ + +    content = G_BIN_FORMAT(format)->conten_; + +    /* flags */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Service flags")); + +    /* mem_type */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    switch (format->header.v1.mem_type) +    { +        case MCLF_MEM_TYPE_INTERNAL_PREFERRED: +            text = _("Memory to use: internal if available, otherwise external memory"); +            break; +        case MCLF_MEM_TYPE_INTERNAL: +            text = _("Internal memory must be used for executing the service"); +            break; +        case MCLF_MEM_TYPE_EXTERNAL: +            text = _("External memory must be used for executing the service"); +            break; +        default: +            text = _("Unknown memory usage"); +            break; +    } + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* service_type */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    switch (format->header.v1.service_type) +    { +        case SERVICE_TYPE_ILLEGAL: +            text = _("Service type is invalid"); +            break; + +        case SERVICE_TYPE_DRIVER: +            text = _("Service is a driver"); +            break; + +        case SERVICE_TYPE_SP_TRUSTLET: +            text = _("Service is a Trustlet"); +            break; + +        case SERVICE_TYPE_SYSTEM_TRUSTLET: +            text = _("Service is a system Trustlet"); +            break; +    } + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, text); + +    /* num_instances */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Number of instances which can be run simultaneously")); + +    /* uuid */ + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 16, pos, format->endian); + +    g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Loadable service unique identifier (UUID)")); + +    /* driver_id */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    if (format->header.v1.service_type == SERVICE_TYPE_DRIVER) +        text = _("Driver ID"); +    else +        text = _("Unused Driver ID"); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Number of threads")); + +    /* num_threads */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Number of threads")); + +    /* text.start */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual text segment: start address")); + +    /* text.len */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual text segment: length")); + +    /* data.start */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual data segment: start address")); + +    /* data.len */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual data segment: length")); + +    /* bss_len */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Length of the BSS segment in bytes")); + +    /* entry */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Virtual start address of service code")); + + + + + +    /* service_version */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Version of the interface the driver exports")); + + + + +    /* sip_id */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Silicon Provider ID")); + +    /* sip_data */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 3, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Platform specific device identifier")); + +    /* permitted_hw_cfg */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Configuration which is allowed to execute binary")); + + +    return true; + +} + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pos    = tête de lecture à initialiser / faire évoluer. [OUT]* +*                                                                             * +*  Description : Place des annotations sur l'en-tête du segment de code.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool annotate_mclf_text_segment_header(GMCLFFormat *format, vmpa2t *pos) +{ +    GBinContent *content;                   /* Contenu binaire à lire      */ +    vmpa2t old;                             /* Position précédente         */ +    phys_t diff;                            /* Décallage entre positions   */ +    GArchInstruction *instr;                /* Instruction décodée         */ +    GDbComment *comment;                    /* Définition de commentaire   */ +    GBinSymbol *symbol;                     /* Symbole à intégrer          */ + +    content = G_BIN_FORMAT(format)->conten_; + +    copy_vmpa(&old, pos); +    init_vmpa(pos, 0x80, format->header.v1.text.start + 0x80); + +    diff = compute_vmpa_diff(&old, pos); + +    printf("DIFF : %u\n", (unsigned int)diff); + +    instr = g_raw_instruction_new_array(content, MDS_8_BITS, diff, &old, format->endian); + +    g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); + +    ADD_RAW_AS_SYM(format, symbol, &old, instr, comment, _("Padding")); + +    /* version */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Version of the TextHeader structure")); + +    /* text_header_len */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Size of this structure")); + +    /* required_feat */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Features that Mobicore must understand when loading")); + +    /* mc_lib_entry */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Address for McLib entry")); + +    /* mc_lib_data */ + +    if (!annotate_mclf_segment_descriptor(format, _("Segment for McLib data"), pos)) +        return false; + +    //Segment for McLib data + +    /* mc_lib_base */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("McLib base address")); + +    /* tl_api_vers */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("TlApi version used when building trustlet")); + +    /* dr_api_vers */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("DrApi version used when building trustlet")); + +    /* ta_properties */ + +    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, format->endian); + +    ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Address of _TA_Properties in the TA")); + +    return true; + +} + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Place des annotations sur le binaire MCLF.                   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool annotate_mclf_binary(GMCLFFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ +    vmpa2t pos;                             /* Localisation des symboles   */ + + +    result = annotate_mclf_intro(format, &pos); + +    result &= annotate_mclf_header_v1(format, &pos); + +    result &= annotate_mclf_text_segment_header(format, &pos); + +    return result; + +} diff --git a/plugins/mobicore/annotations.h b/plugins/mobicore/annotations.h new file mode 100644 index 0000000..2e06915 --- /dev/null +++ b/plugins/mobicore/annotations.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * annotations.h - prototypes pour l'enregistrement des annotations liées au format MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_MOBICORE_ANNOTATIONS_H +#define _PLUGINS_MOBICORE_ANNOTATIONS_H + + +#include <stdbool.h> + + +#include "mclf.h" + + + +/*Place des annotations sur le binaire MCLF. */ +bool annotate_mclf_binary(GMCLFFormat *); + + + +#endif  /* _PLUGINS_MOBICORE_ANNOTATIONS_H */ diff --git a/plugins/mobicore/mclf-def.h b/plugins/mobicore/mclf-def.h new file mode 100644 index 0000000..c02d6c2 --- /dev/null +++ b/plugins/mobicore/mclf-def.h @@ -0,0 +1,222 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mclf-def.h - liste des structures et constantes utilisées par le format MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_MOBICORE_MCLF_DEF_H +#define _PLUGINS_MOBICORE_MCLF_DEF_H + + +#include <stdint.h> + + + +/* ------------------------------ DECLARATIONS DE BASE ------------------------------ */ + + +#define MC_SERVICE_HEADER_MAGIC_STR "MCLF" + + +/* En-tête de base */ +typedef struct _mclf_intro_t +{ +    uint32_t magic;                         /* Valeur magique "MCLF"       */ +    uint32_t version;                       /* Version de l'en-tête        */ + +} mclf_intro_t; + + + +/** Get major version number from complete version. */ +#define MC_GET_MAJOR_VERSION(version) ((version) >> 16) + +/** Get minor version number from complete version. */ +#define MC_GET_MINOR_VERSION(version) ((version) & 0xffff) + + + +/** + * Drapeaux MCLF + */ + +/* Le service ne peut pas être déchargé depuis MobiCore */ +#define MC_SERVICE_HEADER_FLAGS_PERMANENT (1u << 0) + +/* Le service n'a pas d'interface de contrôle WSM */ +#define MC_SERVICE_HEADER_FLAGS_NO_CONTROL_INTERFACE (1u << 1) + + +/* Adresse, physique ou virtuelle */ +typedef uint32_t mclf_addr_t; + +/* Types de service définissant l'exécutable */ +typedef enum service_type_t +{ +    SERVICE_TYPE_ILLEGAL = 0,               /* Type invalide               */ +    SERVICE_TYPE_DRIVER = 1,                /* Le service est un pilote    */ +    SERVICE_TYPE_SP_TRUSTLET = 2,           /* Le service est un Trustlet  */ +    SERVICE_TYPE_SYSTEM_TRUSTLET = 3        /* Idem, mais Trustlet système */ + +} service_type_t; + +/* Types de mémoire */ +typedef enum _mem_type_t +{ +    MCLF_MEM_TYPE_INTERNAL_PREFERRED = 0,   /* Mémoire interne si possible */ +    MCLF_MEM_TYPE_INTERNAL = 1,             /* Mémoire d'exécution interne */ +    MCLF_MEM_TYPE_EXTERNAL = 2              /* Mémoire d'exécution externe */ + +} mem_type_t; + +/* Description d'un segment mémoire */ +typedef struct segment_descriptor_t +{ +    mclf_addr_t start;                      /* Adresse virtuelle de départ */ +    uint32_t len;                           /* Taille du segment           */ + +} segment_descriptor_t; + + + +/* ------------------------------ IDENTIFIANTS UNIQUES ------------------------------ */ + + +/* Identifiant sur 16 octets */ +typedef struct _mc_uuid_t +{ +    uint8_t value[16];                      /* Valeur de l'UUID            */ + +} mc_uuid_t; + + + + + +typedef enum { + +    TODO_ + +} mc_driver_id_t; + + + +/* ----------------------------- DEFINITION VERSION N°1 ----------------------------- */ + + +/* En-tête associée */ +typedef struct _mclf_header_v1_t +{ +    mclf_intro_t intro;                     /* Introduction obligatoire    */ +    uint32_t flags;                         /* Indicateurs de service      */ +    mem_type_t mem_type;                    /* Type de mémoire d'exécution */ +    service_type_t service_type;            /* Type de service             */ + +    uint32_t num_instances;                 /* Nbre d'instances simultanées*/ +    mc_uuid_t uuid;                         /* Identifiant unique (UUID)   */ +    mc_driver_id_t driver_id;               /* Identifiant éventuel        */ +    uint32_t num_threads;                   /* Nbre de threads du service  */ + +    segment_descriptor_t text;              /* Segment virtuel de code     */ +    segment_descriptor_t data;              /* Segment virtuel de données  */ + +    uint32_t bss_len;                       /* Taille du segment BSS       */ +    mclf_addr_t entry;                      /* Point d'entrée du service   */ + +} mclf_header_v1_t; + + + +/* ----------------------------- DEFINITION VERSION N°2 ----------------------------- */ + + +/* En-tête associée */ +typedef struct _mclf_header_v2_t +{ +    mclf_intro_t intro;                     /* Introduction obligatoire    */ +    uint32_t flags;                         /* Indicateurs de service      */ +    mem_type_t mem_type;                    /* Type de mémoire d'exécution */ +    service_type_t service_type;            /* Type de service             */ + +    uint32_t num_instances;                 /* Nbre d'instances simultanées*/ +    mc_uuid_t uuid;                         /* Identifiant unique (UUID)   */ +    mc_driver_id_t driver_id;               /* Identifiant éventuel        */ +    uint32_t num_threads;                   /* Nbre de threads du service  */ + +    segment_descriptor_t text;              /* Segment virtuel de code     */ +    segment_descriptor_t data;              /* Segment virtuel de données  */ + +    uint32_t bss_len;                       /* Taille du segment BSS       */ +    mclf_addr_t entry;                      /* Point d'entrée du service   */ +    uint32_t service_version;               /* Version de l'interface      */ + +} mclf_header_v2_t; + + + + + +/* ------------------------------- DEFINITION GLOBALE ------------------------------- */ +/* ------------------------------- DEFINITION GLOBALE ------------------------------- */ + + + + +/** + * Version 2 MCLF text segment header. + * Required to be present in MobiCore 1.2 components at address (0x1080). + * This extension is initialized already at trustlet compile time, + * but may be modified later by configuration tools and by MobiCore at load time. + */ +typedef struct _mclf_text_header_t +{ +    uint32_t version;                       /* Version de la structure     */ +    uint32_t text_header_len;               /* Taille de la structure      */ +    uint32_t required_feat;                 /* Fonctionnalités requises    */ + +    uint32_t mc_lib_entry;                  /* Adresse d'entrée McLib      */ +    segment_descriptor_t mc_lib_data;       /* Segment pour McLib          */ +    uint32_t mc_lib_base;                   /* Adresse de base pour McLib  */ + +    uint32_t tl_api_vers;                   /* Version TlApi utilisée      */ +    uint32_t dr_api_vers;                   /* Version DrApi utilisée      */ +    uint32_t ta_properties;                 /* Position de _TA_Properties  */ + +} mclf_text_header_t; + + + + + +/* ------------------------------- DEFINITION GLOBALE ------------------------------- */ + + +/* En-tête générique */ +typedef union _mclf_header_t +{ +    mclf_intro_t intro;                     /* Base pour identification    */ +    mclf_header_v1_t v1;                    /* En-tête version 1           */ +    mclf_header_v2_t v2;                    /* En-tête version 2           */ + +} mclf_header_t; + + + +#endif  /* _PLUGINS_MOBICORE_MCLF_DEF_H */ diff --git a/plugins/mobicore/mclf-int.c b/plugins/mobicore/mclf-int.c new file mode 100644 index 0000000..2f2300d --- /dev/null +++ b/plugins/mobicore/mclf-int.c @@ -0,0 +1,122 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mclf-int.c - structures internes du format MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "mclf-int.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                header = en-tête à déterminer. [OUT]                         * +*                endian = boutisme reconnu dans le format. [OUT]              * +*                                                                             * +*  Description : Procède à la lecture de l'en-tête d'un contenu binaire MCLF. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_mclf_header(GMCLFFormat *format, mclf_header_t *header, SourceEndian endian) +{ +    bool result;                            /* Bilan à retourner           */ +    GBinContent *content;                   /* Contenu binaire à lire      */ +    vmpa2t pos;                             /* Position de lecture         */ + +    content = G_BIN_FORMAT(format)->conten_; + +    init_vmpa(&pos, 0, VMPA_NO_VIRTUAL); + +    result = g_binary_content_read_u32(content, &pos, endian, &header->intro.magic); +    result &= g_binary_content_read_u32(content, &pos, endian, &header->intro.version); + +    printf("Version :: %u (%x)\n", header->intro.version, header->intro.version); + + +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.flags); +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.mem_type); +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.service_type); + +    printf("Mem type : 0x%08x\n", header->v1.mem_type); + +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.num_instances); +    result &= g_binary_content_get_raw(content, &pos, 16, (bin_t *)&header->v1.uuid); +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.driver_id); +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.num_threads); + +    printf("Num threads : 0x%08x\n", header->v1.num_threads); + +    result &= read_mclf_segment_desc(format, &header->v1.text, &pos, endian); + +    printf("TEXT :: 0x%08x + %u\n", header->v1.text.start, header->v1.text.len); + +    result &= read_mclf_segment_desc(format, &header->v1.data, &pos, endian); + +    printf("DATA :: 0x%08x + %u\n", header->v1.data.start, header->v1.data.len); + + +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.bss_len); +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v1.entry); + +    printf("ENTRY :: 0x%08x\n", header->v1.entry); + + + +    result &= g_binary_content_read_u32(content, &pos, endian, &header->v2.service_version); + + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = informations chargées à consulter.                 * +*                segment = descripteur à déterminer. [OUT]                    * +*                pos     = position de début de lecture. [OUT]                * +*                endian  = boutisme reconnu dans le format. [OUT]             * +*                                                                             * +*  Description : Procède à la lecture d'un descripteur de segment MCLF.       * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool read_mclf_segment_desc(GMCLFFormat *format, segment_descriptor_t *segment, vmpa2t *pos, SourceEndian endian) +{ +    bool result;                            /* Bilan à retourner           */ +    GBinContent *content;                   /* Contenu binaire à lire      */ + +    content = G_BIN_FORMAT(format)->conten_; + +    result = g_binary_content_read_u32(content, pos, endian, &segment->start); +    result &= g_binary_content_read_u32(content, pos, endian, &segment->len); + +    return result; + +} diff --git a/plugins/mobicore/mclf-int.h b/plugins/mobicore/mclf-int.h new file mode 100644 index 0000000..e34419b --- /dev/null +++ b/plugins/mobicore/mclf-int.h @@ -0,0 +1,64 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mclf-int.h - prototypes pour les structures internes du format MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_MOBICORE_MCLF_INT_H +#define _PLUGINS_MOBICORE_MCLF_INT_H + + +#include <common/endianness.h> +#include <format/executable-int.h> + + +#include "mclf.h" +#include "mclf-def.h" + + + +/* Format d'exécutable MCLF (instance) */ +struct _GMCLFFormat +{ +    GExeFormat parent;                      /* A laisser en premier        */ + +    mclf_header_t header;                   /* En-tête du format           */ +    SourceEndian endian;                    /* Boutisme du format          */ + +}; + +/* Format d'exécutable MCLF (classe) */ +struct _GMCLFFormatClass +{ +    GExeFormatClass parent;                 /* A laisser en premier        */ + +}; + + + +/* Procède à la lecture de l'en-tête d'un contenu binaire MCLF. */ +bool read_mclf_header(GMCLFFormat *, mclf_header_t *, SourceEndian); + +/* Procède à la lecture d'un descripteur de segment MCLF. */ +bool read_mclf_segment_desc(GMCLFFormat *, segment_descriptor_t *, vmpa2t *, SourceEndian); + + + +#endif  /* _PLUGINS_MOBICORE_MCLF_INT_H */ diff --git a/plugins/mobicore/mclf.c b/plugins/mobicore/mclf.c new file mode 100644 index 0000000..3fc9e21 --- /dev/null +++ b/plugins/mobicore/mclf.c @@ -0,0 +1,258 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mclf.c - prise en compte du format binaire 'MCLF' + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "mclf.h" + + +#include <i18n.h> + + +#include "annotations.h" +#include "mclf-int.h" + + + +/* Taille maximale d'une description */ +#define MAX_PORTION_DESC 256 + + + +/* Initialise la classe des formats d'exécutables MCLF. */ +static void g_mclf_format_class_init(GMCLFFormatClass *); + +/* Initialise une instance de format d'exécutable MCLF. */ +static void g_mclf_format_init(GMCLFFormat *); + +/* Indique le type d'architecture visée par le format. */ +static const char *g_mclf_format_get_target_machine(const GMCLFFormat *); + +/* Etend la définition des portions au sein d'un binaire. */ +static void g_mclf_format_refine_portions(const GMCLFFormat *, GBinPortion *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                                                                             * +*  Description : Indique si le format peut être pris en charge ici.           * +*                                                                             * +*  Retour      : true si la réponse est positive, false sinon.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool mclf_is_matching(GBinContent *content) +{ +    bool result;                            /* Bilan à faire connaître     */ +    vmpa2t addr;                            /* Tête de lecture initiale    */ +    char magic[4];                          /* Idenfiant standard          */ + +    init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + +    result = g_binary_content_get_raw(content, &addr, 4, (bin_t *)magic); + +    result &= (memcmp(magic, MC_SERVICE_HEADER_MAGIC_STR, 4) == 0); + +    return result; + +} + + +/* Indique le type défini pour un format d'exécutable MCLF. */ +G_DEFINE_TYPE(GMCLFFormat, g_mclf_format, G_TYPE_EXE_FORMAT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des formats d'exécutables MCLF.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_mclf_format_class_init(GMCLFFormatClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de format d'exécutable MCLF.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_mclf_format_init(GMCLFFormat *format) +{ +    GExeFormat *exe_format;                 /* Format parent à constituer  */ + +    exe_format = G_EXE_FORMAT(format); + +    exe_format->get_machine = (get_target_machine_fc)g_mclf_format_get_target_machine; +    exe_format->refine_portions = (refine_portions_fc)g_mclf_format_refine_portions; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                                                                             * +*  Description : Prend en charge un nouveau format MCLF.                      * +*                                                                             * +*  Retour      : Adresse de la structure mise en place ou NULL en cas d'échec.* +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinFormat *g_mclf_format_new(GBinContent *content) +{ +    GMCLFFormat *result;                    /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_MCLF_FORMAT, NULL); + +    g_binary_format_set_content(G_BIN_FORMAT(result), content); + + + +    if (!read_mclf_header(result, &result->header, result->endian)) +    { +        /* TODO */ +        return NULL; +    } + + + +    if (!load_mclf_symbols(result)) +    { +        /* TODO */ +        return NULL; +    } + + +    if (!annotate_mclf_binary(result)) +        printf("ERRR\n"); + +    return G_BIN_FORMAT(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Indique le type d'architecture visée par le format.          * +*                                                                             * +*  Retour      : Identifiant de l'architecture ciblée par le format.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static const char *g_mclf_format_get_target_machine(const GMCLFFormat *format) +{ +    const char *result;                     /* Identifiant à retourner     */ + +    result = "armv7"; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                raw    = portion de binaire brut à raffiner.                 * +*                                                                             * +*  Description : Etend la définition des portions au sein d'un binaire.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_mclf_format_refine_portions(const GMCLFFormat *format, GBinPortion *raw) +{ +    GBinPortion *new;                       /* Nouvelle portion définie    */ +    char desc[MAX_PORTION_DESC];            /* Description d'une portion   */ +    vmpa2t addr;                            /* Emplacement dans le binaire */ +  +    /* Segment de code */ + +    new = g_binary_portion_new(BPC_CODE); + +    sprintf(desc, "%s \"%s\"", _("Segment"), "text"); +    g_binary_portion_set_desc(new, desc); + +    init_vmpa(&addr, 0, format->header.v1.text.start); +    g_binary_portion_set_values(new, &addr, format->header.v1.text.len); + +    g_binary_portion_set_rights(new, PAC_WRITE | PAC_EXEC); + +    g_binary_portion_include(raw, new); + +    /* Segment de données */ + +    new = g_binary_portion_new(BPC_DATA); + +    sprintf(desc, "%s \"%s\"", _("Segment"), "data"); +    g_binary_portion_set_desc(new, desc); + +    init_vmpa(&addr, format->header.v1.text.len, format->header.v1.data.start); +    g_binary_portion_set_values(new, &addr, format->header.v1.data.len); + +    g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE); + +    g_binary_portion_include(raw, new); + +    /* Signature finale */ + +    new = g_binary_portion_new(BPC_DATA); + +    sprintf(desc, "%s \"%s\"", _("Segment"), "sig"); +    g_binary_portion_set_desc(new, desc); + +    init_vmpa(&addr, G_BIN_FORMAT(format)->length - 521, VMPA_NO_VIRTUAL);  /* FIXME */ +    g_binary_portion_set_values(new, &addr, 521); + +    g_binary_portion_set_rights(new, PAC_READ | PAC_WRITE); + +    g_binary_portion_include(raw, new); + +} diff --git a/plugins/mobicore/mclf.h b/plugins/mobicore/mclf.h new file mode 100644 index 0000000..c2752b8 --- /dev/null +++ b/plugins/mobicore/mclf.h @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mclf.h - prototypes pour la prise en compte du format binaire 'MCLF' + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_MOBICORE_MCLF_H +#define _PLUGINS_MOBICORE_MCLF_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <sys/types.h> + + +#include <format/format.h> + + + +#define G_TYPE_MCLF_FORMAT                (g_mclf_format_get_type()) +#define G_MCLF_FORMAT(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_MCLF_FORMAT, GMCLFFormat)) +#define G_IS_MCLF_FORMAT(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_MCLF_FORMAT)) +#define G_MCLF_FORMAT_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_MCLF_FORMAT, GMCLFFormatClass)) +#define G_IS_MCLF_FORMAT_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_MCLF_FORMAT)) +#define G_MCLF_FORMAT_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_MCLF_FORMAT, GMCLFFormatClass)) + + +/* Format d'exécutable MCLF (instance) */ +typedef struct _GMCLFFormat GMCLFFormat; + +/* Format d'exécutable MCLF (classe) */ +typedef struct _GMCLFFormatClass GMCLFFormatClass; + + +/* Indique si le format peut être pris en charge ici. */ +bool mclf_is_matching(GBinContent *); + +/* Indique le type défini pour un format d'exécutable MCLF. */ +GType g_mclf_format_get_type(void); + +/* Prend en charge un nouveau format MCLF. */ +GBinFormat *g_mclf_format_new(GBinContent *); + + + +#endif  /* _PLUGINS_MOBICORE_MCLF_H */ diff --git a/plugins/mobicore/mobicore.c b/plugins/mobicore/mobicore.c new file mode 100644 index 0000000..9f7b8a4 --- /dev/null +++ b/plugins/mobicore/mobicore.c @@ -0,0 +1,83 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mobicore.c - support du format de chargement MobiCore + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "mobicore.h" + + +#include <core/formats.h> +#include <plugins/plugin-def.h> + + +#include "mclf.h" + + + +DEFINE_CHRYSALIDE_ACTIVE_PLUGIN("Mobicore", "Support MobiCore file format for Trusted Applications", "0.1.0", +                                PGA_PLUGIN_INIT, PGA_PLUGIN_EXIT); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à manipuler.                                * +*                                                                             * +*  Description : Prend acte du chargement du greffon.                         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) +{ +    bool result;                            /* Bilan à retourner           */ + +    printf("Loaded !\n"); + +    result = register_format_type("mclf", "MobiCore Load Format", mclf_is_matching, g_mclf_format_new); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : plugin = greffon à manipuler.                                * +*                                                                             * +*  Description : Prend acte du déchargement du greffon.                       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin) +{ + +    printf("Unloaded !\n"); + + +} diff --git a/plugins/mobicore/mobicore.h b/plugins/mobicore/mobicore.h new file mode 100644 index 0000000..d8687a1 --- /dev/null +++ b/plugins/mobicore/mobicore.h @@ -0,0 +1,41 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * mobicore.h - prototypes pour le support du format de chargement MobiCore + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_MOBICORE_MOBICORE_H +#define _PLUGINS_MOBICORE_MOBICORE_H + + +#include <plugins/plugin.h> +#include <plugins/plugin-int.h> + + + +/* Prend acte du chargement du greffon. */ +G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *); + +/* Prend acte du déchargement du greffon. */ +G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *); + + + +#endif  /* _PLUGINS_MOBICORE_MOBICORE_H */ diff --git a/plugins/mobicore/symbols.c b/plugins/mobicore/symbols.c new file mode 100644 index 0000000..c718cfa --- /dev/null +++ b/plugins/mobicore/symbols.c @@ -0,0 +1,145 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.c - gestion des symboles d'un MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "symbols.h" + + +#include <malloc.h> + + +#include <format/mangling/demangler.h> + + +#include "mclf-int.h" + + + +/* Enregistre un point d'entrée au sein d'un binaire MCLF. */ +static void register_mclf_entry_point(GMCLFFormat *, virt_t, phys_t, GBinRoutine *); + +/* Enumère les points d'entrée principaux d'un binaire MCLF. */ +static bool load_all_mclf_basic_entry_points(GMCLFFormat *format); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format  = description de l'exécutable à compléter.           * +*                vaddr   = adresse virtuelle du symbole à insérer.            * +*                len     = taille de la routine à ajouter.                    * +*                routine = représentation de la fonction repérée.             * +*                                                                             * +*  Description : Enregistre un point d'entrée au sein d'un binaire MCLF.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void register_mclf_entry_point(GMCLFFormat *format, virt_t vaddr, phys_t len, GBinRoutine *routine) +{ +    GBinFormat *base;                   /* Version basique de l'instance   */ +    vmpa2t addr;                        /* Localisation d'une routine  */ +    mrange_t range;                     /* Couverture mémoire associée */ +    GBinSymbol *symbol;                 /* Nouveau symbole construit   */ + +    base = G_BIN_FORMAT(format); + +    /* Comptabilisation pour le désassemblage brut */ + +    base->entry_points = (virt_t *)realloc(base->entry_points, ++base->ep_count * sizeof(virt_t)); + +    base->entry_points[base->ep_count - 1] = vaddr; + +    /* Comptabilisation en tant que symbole */ + +    vaddr &= ~0x1; + +	init_vmpa(&addr, vaddr - format->header.v1.text.start, vaddr); +	init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr); + +	init_mrange(&range, &addr, len); + +	g_binary_routine_set_range(routine, &range); + +	symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0); +	g_binary_symbol_attach_routine(symbol, routine); +	g_binary_format_add_symbol(base, symbol); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à consulter.            * +*                                                                             * +*  Description : Enumère les points d'entrée principaux d'un binaire MCLF.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool load_all_mclf_basic_entry_points(GMCLFFormat *format) +{ +    virt_t ep;                              /* Point d'entrée détecté      */ +    GBinRoutine *routine;                   /* Routine à associer à un pt. */ + +    /* Point d'entrée principal éventuel */ + +    ep = format->header.v1.entry; + +    if (ep != 0x0) +    { +        routine = try_to_demangle_routine("entry_point"); +        register_mclf_entry_point(format, ep, 0, routine); +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                                                                             * +*  Description : Charge en mémoire la liste humaine des symboles.             * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_mclf_symbols(GMCLFFormat *format) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = load_all_mclf_basic_entry_points(format); + +    return result; + +} diff --git a/plugins/mobicore/symbols.h b/plugins/mobicore/symbols.h new file mode 100644 index 0000000..c528994 --- /dev/null +++ b/plugins/mobicore/symbols.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.h - prototypes pour la gestion des symboles d'un MCLF + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_MOBICORE_SYMBOLS_H +#define _PLUGINS_MOBICORE_SYMBOLS_H + + +#include <stdbool.h> + + +#include "mclf.h" + + + +/* Charge en mémoire la liste humaine des symboles. */ +bool load_mclf_symbols(GMCLFFormat *); + + + +#endif  /* _PLUGINS_MOBICORE_SYMBOLS_H */ diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c index 0a27fa1..e1db3de 100644 --- a/plugins/pychrysa/plugin.c +++ b/plugins/pychrysa/plugin.c @@ -331,7 +331,7 @@ static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin)          Py_DECREF(value);      }      else -        result = PGA_NONE; +        result = 0;//PGA_NONE;      return result; @@ -581,8 +581,8 @@ static bool pychrysa_plugin_define_constants(PyObject *dict)  {      int ret;                                /* Bilan d'un ajout            */ -    ret = PyDict_SetItemString(dict, "PGA_NONE", PyInt_FromLong(PGA_NONE)); -    if (ret == -1) return false; +    //ret = PyDict_SetItemString(dict, "PGA_NONE", PyInt_FromLong(PGA_NONE)); +    //if (ret == -1) return false;      ret = PyDict_SetItemString(dict, "PGA_FORMAT_MATCHER", PyInt_FromLong(PGA_FORMAT_MATCHER));      if (ret == -1) return false; @@ -669,7 +669,7 @@ static PyObject *pychrysa_plugin_init(PyObject *self, PyObject *args)  static PyObject *pychrysa_plugin_get_action(PyObject *self, PyObject *args)  { -    return PyInt_FromLong(PGA_NONE); +    return PyInt_FromLong(0/*PGA_NONE*/);  } diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index 2b8202e..00856f3 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -229,7 +229,7 @@ PluginAction get_plugin_action(const GPluginModule *plugin)  {      PluginAction result;                    /* Combinaison à retourner     */ -    result = PGA_NONE; +    //result = PGA_NONE;      return result; diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 96e774c..d27e761 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -210,9 +210,6 @@ static void g_loaded_binary_finalize(GLoadedBinary *binary)  {      free(binary->username); -    if (binary->bin_data != NULL) -        free(binary->bin_data); -      /* TODO... */      G_OBJECT_CLASS(g_loaded_binary_parent_class)->finalize(G_OBJECT(binary)); diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index a6e58cd..974a223 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -359,13 +359,13 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph          index = i / (sizeof(unsigned long) * 8);          remaining = i % (sizeof(unsigned long) * 8); -        assert((area->processed[index] & (1ul << remaining)) == 0); +        //assert((area->processed[index] & (1ul << remaining)) == 0);          area->processed[index] |= (1ul << remaining);      } -    assert(area->instructions[start] == NULL); +    //assert(area->instructions[start] == NULL);      area->instructions[start] = instr; @@ -666,7 +666,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count              init_mrange(&range, &pos, 4);              if (is_range_blank_in_mem_areas(list, count, &range)) -                instr = g_raw_instruction_new_array(bin_data, MDS_32_BITS, 1, &pos, bin_length, endianness); +                instr = g_raw_instruction_new_array_old(bin_data, MDS_32_BITS, 1, &pos, bin_length, endianness);          }          */ @@ -676,7 +676,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count              init_mrange(&range, &pos, 2);              if (is_range_blank_in_mem_areas(list, count, &range)) -                instr = g_raw_instruction_new_array(bin_data, MDS_16_BITS, 1, &pos, bin_length, endianness); +                instr = g_raw_instruction_new_array_old(bin_data, MDS_16_BITS, 1, &pos, bin_length, endianness);          } @@ -686,7 +686,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count              init_mrange(&range, &pos, 1);              if (is_range_blank_in_mem_areas(list, count, &range)) -                instr = g_raw_instruction_new_array(bin_data, MDS_8_BITS, 1, &pos, bin_length, endianness); +                instr = g_raw_instruction_new_array_old(bin_data, MDS_8_BITS, 1, &pos, bin_length, endianness);              else              {                  /** diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c index 3464214..9117861 100644 --- a/src/arch/arm/v7/processor.c +++ b/src/arch/arm/v7/processor.c @@ -298,7 +298,7 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr          advance_vmpa(pos, diff);      /*      else -        result = g_raw_instruction_new_array(data, MDS_32_BITS, 1, pos, end, +        result = g_raw_instruction_new_array_old(data, MDS_32_BITS, 1, pos, end,                                               G_ARCH_PROCESSOR(proc)->endianness);      */      return result; diff --git a/src/arch/artificial.c b/src/arch/artificial.c index d2b2117..a6fea56 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -201,7 +201,7 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, vmpa2t *addr      pos = get_phy_addr(address);      old = pos; -    operand = g_imm_operand_new_from_data(g_arch_processor_get_instruction_size(proc), +    operand = g_imm_operand_new_from_data_old(g_arch_processor_get_instruction_size(proc),                                            data, &pos, end,                                            g_arch_processor_get_endianness(proc)); diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index a63369c..fca7956 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -300,27 +300,27 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const GDexFormat              case DOI_IMMEDIATE_4:                  assert(0); -                //op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, end, low, endian); +                //op = _g_imm_operand_new_from_data_old(MDS_4_BITS, data, pos, end, low, endian);                  break;              case DOI_IMMEDIATE_8:                  assert(0); -                //op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, end, endian); +                //op = g_imm_operand_new_from_data_old(MDS_8_BITS, data, pos, end, endian);                  break;              case DOI_IMMEDIATE_16:                  assert(0); -                //op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, end, endian); +                //op = g_imm_operand_new_from_data_old(MDS_16_BITS, data, pos, end, endian);                  break;              case DOI_IMMEDIATE_32:                  assert(0); -                //op = g_imm_operand_new_from_data(MDS_32_BITS, data, pos, end, endian); +                //op = g_imm_operand_new_from_data_old(MDS_32_BITS, data, pos, end, endian);                  break;              case DOI_IMMEDIATE_64:                  assert(0); -                //op = g_imm_operand_new_from_data(MDS_64_BITS, data, pos, end, endian); +                //op = g_imm_operand_new_from_data_old(MDS_64_BITS, data, pos, end, endian);                  break;              case DOI_IMMEDIATE_H16: diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 4d0c0b8..3a3e64c 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -211,7 +211,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian) +GArchOperand *_g_imm_operand_new_from_data_old(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)  {      GImmOperand *result;                    /* Opérande à retourner        */      off_t old;                              /* Ancienne tête de lecture    */ @@ -315,6 +315,117 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat  /******************************************************************************  *                                                                             * +*  Paramètres  : size    = taille de l'opérande souhaitée.                    * +*                content = flux de données à analyser.                        * +*                addr    = position courante dans ce flux. [OUT]              * +*                low     = position éventuelle des 4 bits visés. [OUT]        * +*                endian  = ordre des bits dans la source.                     * +*                                                                             * +*  Description : Crée un opérande réprésentant une valeur numérique.          * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) +{ +    GImmOperand *result;                    /* Opérande à retourner        */ +    uint8_t uval8;                          /* Valeur sur 8 bits           */ +    uint16_t uval16;                        /* Valeur sur 16 bits          */ +    uint32_t uval32;                        /* Valeur sur 32 bits          */ +    uint64_t uval64;                        /* Valeur sur 64 bits          */ +    int8_t sval8;                           /* Valeur sur 8 bits           */ +    int16_t sval16;                         /* Valeur sur 16 bits          */ +    int32_t sval32;                         /* Valeur sur 32 bits          */ +    int64_t sval64;                         /* Valeur sur 64 bits          */ + +    result = g_object_new(G_TYPE_IMM_OPERAND, NULL); + +    result->size = size; + +    switch (size) +    { +        case MDS_4_BITS_UNSIGNED: +            if (!g_binary_content_read_u4(content, addr, low, endian, &uval8)) +                goto gionfd_error; +            result->raw = uval8; +            break; + +        case MDS_8_BITS_UNSIGNED: +            if (!g_binary_content_read_u8(content, addr, endian, &uval8)) +                goto gionfd_error; +            result->raw = uval8; +            break; + +        case MDS_16_BITS_UNSIGNED: +            if (!g_binary_content_read_u16(content, addr, endian, &uval16)) +                goto gionfd_error; +            result->raw = uval16; +            break; + +        case MDS_32_BITS_UNSIGNED: +            if (!g_binary_content_read_u32(content, addr, endian, &uval32)) +                goto gionfd_error; +            result->raw = uval32; +            break; + +        case MDS_64_BITS_UNSIGNED: +            if (!g_binary_content_read_u64(content, addr, endian, &uval64)) +                goto gionfd_error; +            result->raw = uval64; +            break; + +        case MDS_4_BITS_SIGNED: +            if (!g_binary_content_read_s4(content, addr, low, endian, &sval8)) +                goto gionfd_error; +            result->raw = sval8; +            break; + +        case MDS_8_BITS_SIGNED: +            if (!g_binary_content_read_s8(content, addr, endian, &sval8)) +                goto gionfd_error; +            result->raw = sval8; +            break; + +        case MDS_16_BITS_SIGNED: +            if (!g_binary_content_read_s16(content, addr, endian, &sval16)) +                goto gionfd_error; +            result->raw = sval16; +            break; + +        case MDS_32_BITS_SIGNED: +            if (!g_binary_content_read_s32(content, addr, endian, &sval32)) +                goto gionfd_error; +            result->raw = sval32; +            break; + +        case MDS_64_BITS_SIGNED: +            if (!g_binary_content_read_s64(content, addr, endian, &sval64)) +                goto gionfd_error; +            result->raw = sval64; +            break; + +        case MDS_UNDEFINED: +            goto gionfd_error; +            break; + +    } + +    return G_ARCH_OPERAND(result); + + gionfd_error: + +    g_object_unref(G_OBJECT(result)); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : size  = taille de l'opérande souhaitée.                      *  *                value = valeur sur x bits à venir récupérer.                 *  *                                                                             * diff --git a/src/arch/immediate.h b/src/arch/immediate.h index a218c16..a0721b2 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -33,6 +33,7 @@  #include "archbase.h"  #include "operand.h"  #include "../common/endianness.h" +#include "../glibext/gbincontent.h" @@ -66,10 +67,16 @@ typedef struct _GImmOperandClass GImmOperandClass;  GType g_imm_operand_get_type(void);  /* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian); +GArchOperand *_g_imm_operand_new_from_data_old(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian)  __attribute__ ((deprecated)); -#define g_imm_operand_new_from_data(size, data, pos, len, endian) \ -    _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian) +#define g_imm_operand_new_from_data_old(size, data, pos, len, endian) \ +    _g_imm_operand_new_from_data_old(size, data, pos, len, NULL, endian) + +/* Crée un opérande réprésentant une valeur numérique. */ +GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const GBinContent *, vmpa2t *, bool *, SourceEndian); + +#define g_imm_operand_new_from_data(size, content, addr, endian) \ +    _g_imm_operand_new_from_data(size, content, addr, NULL, endian)  /* Crée un opérande réprésentant une valeur numérique. */  GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, uint64_t); diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 02bb9b7..f1ce67f 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -35,6 +35,7 @@  #include "../analysis/type.h"  #include "../decomp/context.h"  #include "../decomp/instruction.h" +#include "../glibext/gbincontent.h"  //#include "../format/executable.h"  //#include "../format/format.h" diff --git a/src/arch/raw.c b/src/arch/raw.c index 62c88c1..808d973 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -254,7 +254,7 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize size, size_t count, vmpa2t *addr, off_t end, SourceEndian endian) +GArchInstruction *g_raw_instruction_new_array_old(const bin_t *data, MemoryDataSize size, size_t count, vmpa2t *addr, off_t end, SourceEndian endian)  {      GArchInstruction *result;               /* Instruction à retourner     */      vmpa2t old;                             /* Sauvegarde de la position   */ @@ -271,7 +271,63 @@ GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize      for (i = 0; i < count; i++)      { -        operand = g_imm_operand_new_from_data(size, data, addr, end, endian); +        operand = g_imm_operand_new_from_data_old(size, data, addr, end, endian); +        if (operand == NULL) goto grina_error; + +        g_imm_operand_pad(G_IMM_OPERAND(operand), true); + +        g_arch_instruction_attach_extra_operand(result, operand); +    } + +    init_mrange(&range, &old, compute_vmpa_diff(addr, &old)); + +    g_arch_instruction_set_range(result, &range); + +    return result; + + grina_error: + +    g_object_unref(G_OBJECT(result)); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = flux de données à analyser.                        * +*                size    = taille de chacun des éléments à représenter.       * +*                count   = nombre de ces éléments.                            * +*                addr    = position courante dans ce flux. [OUT]              * +*                endian  = ordre des bits dans la source.                     * +*                                                                             * +*  Description : Crée une instruction de type 'db/dw/etc' étendue.            * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, MemoryDataSize size, size_t count, vmpa2t *addr, SourceEndian endian) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    vmpa2t old;                             /* Sauvegarde de la position   */ +    size_t i;                               /* Boucle de parcours          */ +    GArchOperand *operand;                  /* Octet non décodé à afficher */ +    mrange_t range;                         /* Couverture de l'instruction */ + +    /* Par soucis de cohérence */ +    if (count == 0) return NULL; + +    result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); + +    copy_vmpa(&old, addr); + +    for (i = 0; i < count; i++) +    { +        operand = g_imm_operand_new_from_data(size, content, addr, endian);          if (operand == NULL) goto grina_error;          g_imm_operand_pad(G_IMM_OPERAND(operand), true); diff --git a/src/arch/raw.h b/src/arch/raw.h index 8ae9a74..f7e1715 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -56,7 +56,10 @@ GType g_raw_instruction_get_type(void);  GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *, MemoryDataSize, uint64_t);  /* Crée une instruction de type 'db/dw/etc' étendue. */ -GArchInstruction *g_raw_instruction_new_array(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); +GArchInstruction *g_raw_instruction_new_array_old(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); + +/* Crée une instruction de type 'db/dw/etc' étendue. */ +GArchInstruction *g_raw_instruction_new_array(const GBinContent *, MemoryDataSize, size_t, vmpa2t *, SourceEndian);  /* Marque l'instruction comme ne contenant que du bourrage. */  void g_raw_instruction_mark_as_padding(GRawInstruction *, bool); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 8eb79dc..cab2570 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -118,18 +118,18 @@ bool _x86_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos,          {              case X86_OTP_IMM8:                  assert(0); -                //op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); +                //op = g_imm_operand_new_from_data_old(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);                  break;              case X86_OTP_IMM16:                  assert(0); -                //op = g_imm_operand_new_from_data(MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); +                //op = g_imm_operand_new_from_data_old(MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);                  break;              case X86_OTP_IMM1632:                  if (oprsize == MDS_UNDEFINED) oprsize = va_arg(ap, MemoryDataSize);                  assert(0); -                //op = g_imm_operand_new_from_data(oprsize == MDS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); +                //op = g_imm_operand_new_from_data_old(oprsize == MDS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);                  break;              case X86_OTP_MOFFS8: diff --git a/src/arch/x86/operands/modrm.c b/src/arch/x86/operands/modrm.c index 1da734f..030b401 100644 --- a/src/arch/x86/operands/modrm.c +++ b/src/arch/x86/operands/modrm.c @@ -138,7 +138,7 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,          /* FIXME *///free_x86_register(reg);          assert(0);          return NULL; -        //return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/); +        //return g_imm_operand_new_from_data_old(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);      }      result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL); @@ -179,7 +179,7 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,                  result->base = NULL;                  assert(0); -                //result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */); +                //result->displacement = g_imm_operand_new_from_data_old(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);                  if (result->displacement == NULL) goto gxmron_error;              } @@ -187,13 +187,13 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,          case 0x40:              assert(0); -            //result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */); +            //result->displacement = g_imm_operand_new_from_data_old(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);              if (result->displacement == NULL) goto gxmron_error;              break;          case 0x80:              assert(0); -            //result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */); +            //result->displacement = g_imm_operand_new_from_data_old(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);              if (result->displacement == NULL) goto gxmron_error;              break; diff --git a/src/arch/x86/operands/moffs.c b/src/arch/x86/operands/moffs.c index 689a400..1bdc1f8 100644 --- a/src/arch/x86/operands/moffs.c +++ b/src/arch/x86/operands/moffs.c @@ -117,7 +117,7 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,      result = NULL;      assert(0); -    //offset = g_imm_operand_new_from_data(size, data, pos, len, SRE_LITTLE /* FIXME */); +    //offset = g_imm_operand_new_from_data_old(size, data, pos, len, SRE_LITTLE /* FIXME */);      if (offset != NULL)      { diff --git a/src/core/formats.c b/src/core/formats.c index b528e62..9ff31b2 100644 --- a/src/core/formats.c +++ b/src/core/formats.c @@ -178,9 +178,10 @@ static format_t *find_format_by_key(const char *key)      result = NULL; -    for (i = 0; i < _formats_definitions_count; i++) -        if (strcmp(_formats_definitions[i].key, key) == 0) -            result = &_formats_definitions[i]; +    if (key != NULL) +        for (i = 0; i < _formats_definitions_count; i++) +            if (strcmp(_formats_definitions[i].key, key) == 0) +                result = &_formats_definitions[i];      return result; diff --git a/src/core/processors.c b/src/core/processors.c index 7489614..715cd88 100644 --- a/src/core/processors.c +++ b/src/core/processors.c @@ -179,9 +179,10 @@ static proc_t *find_processor_by_key(const char *key)      result = NULL; -    for (i = 0; i < _processors_definitions_count; i++) -        if (strcmp(_processors_definitions[i].key, key) == 0) -            result = &_processors_definitions[i]; +    if (key != NULL) +        for (i = 0; i < _processors_definitions_count; i++) +            if (strcmp(_processors_definitions[i].key, key) == 0) +                result = &_processors_definitions[i];      return result; diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c index a2ef9b2..4fd65df 100644 --- a/src/format/elf/elf-int.c +++ b/src/format/elf/elf-int.c @@ -31,9 +31,9 @@  /******************************************************************************  *                                                                             *  *  Paramètres  : format = informations chargées à consulter.                  * -*                header  = en-tête à déterminer. [OUT]                        * -*                is_32b  = indique si le format est en 32 ou 64 bits. [OUT]   * -*                endian  = boutisme reconnu dans le format. [OUT]             * +*                header = en-tête à déterminer. [OUT]                         * +*                is_32b = indique si le format est en 32 ou 64 bits. [OUT]    * +*                endian = boutisme reconnu dans le format. [OUT]              *  *                                                                             *  *  Description : Procède à la lecture de l'en-tête d'un contenu binaire ELF.  *  *                                                                             * diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index c09c429..1c3da14 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -544,7 +544,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* ELFMAG (0) */ -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 4, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 4, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR);      SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR); @@ -570,7 +570,7 @@ static bool annotate_elf_header(GElfFormat *format)              break;      } -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -594,7 +594,7 @@ static bool annotate_elf_header(GElfFormat *format)              break;      } -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -615,7 +615,7 @@ static bool annotate_elf_header(GElfFormat *format)              break;      } -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -672,7 +672,7 @@ static bool annotate_elf_header(GElfFormat *format)              break;      } -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -680,7 +680,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* EI_ABIVERSION (8) */ -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -688,7 +688,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Padding */ -    instr = g_raw_instruction_new_array(content, MDS_8_BITS, 7, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_8_BITS, 7, pos, length, format->endian);      g_raw_instruction_mark_as_padding(G_RAW_INSTRUCTION(instr), true); @@ -724,7 +724,7 @@ static bool annotate_elf_header(GElfFormat *format)              break;      } -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -815,7 +815,7 @@ static bool annotate_elf_header(GElfFormat *format)          default:		    text = _("Architecture: unknown"); break;      } -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -823,7 +823,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_version" */ -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -833,19 +833,19 @@ static bool annotate_elf_header(GElfFormat *format)      {          /* Champ "e_entry" */ -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Entry point virtual address"));          /* Champ "e_phoff" */ -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Program header table file offset"));          /* Champ "e_shoff" */ -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header table file offset")); @@ -855,19 +855,19 @@ static bool annotate_elf_header(GElfFormat *format)      {          /* Champ "e_entry" */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Entry point virtual address"));          /* Champ "e_phoff" */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Program header table file offset"));          /* Champ "e_shoff" */ -        instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section header table file offset")); @@ -877,7 +877,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_flags" */ -    instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);      //SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -885,7 +885,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_ehsize" */ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -893,7 +893,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_phentsize" */ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -901,7 +901,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_phnum" */ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -909,7 +909,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_shentsize" */ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -917,7 +917,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_shnum" */ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -925,7 +925,7 @@ static bool annotate_elf_header(GElfFormat *format)      /* Champ "e_shstrndx" */ -    instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, length, format->endian); +    instr = g_raw_instruction_new_array_old(content, MDS_16_BITS, 1, pos, length, format->endian);      SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -1049,7 +1049,7 @@ static bool annotate_elf_program_header_table(GElfFormat *format)                  break;          } -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          SET_IMM_DISPLAY(instr, operand, 0, disp); @@ -1059,31 +1059,31 @@ static bool annotate_elf_program_header_table(GElfFormat *format)          {              /* Champ "p_offset" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment file offset"));              /* Champ "p_vaddr" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment virtual address"));              /* Champ "p_paddr" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment physical address"));              /* Champ "p_filesz" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in file"));              /* Champ "p_memsz" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in memory")); @@ -1119,7 +1119,7 @@ static bool annotate_elf_program_header_table(GElfFormat *format)              if (!filled)                  dtext = stradd(dtext, _("none")); -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, dtext); @@ -1127,7 +1127,7 @@ static bool annotate_elf_program_header_table(GElfFormat *format)              /* Champ "p_align" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment alignment")); @@ -1166,7 +1166,7 @@ static bool annotate_elf_program_header_table(GElfFormat *format)              if (!filled)                  dtext = stradd(dtext, _("none")); -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, dtext); @@ -1174,37 +1174,37 @@ static bool annotate_elf_program_header_table(GElfFormat *format)              /* Champ "p_offset" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment file offset"));              /* Champ "p_vaddr" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment virtual address"));              /* Champ "p_paddr" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment physical address"));              /* Champ "p_filesz" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in file"));              /* Champ "p_memsz" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment size in memory"));              /* Champ "p_align" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Segment alignment")); @@ -1280,7 +1280,7 @@ static bool annotate_elf_section_header_table(GElfFormat *format)              dtext = stradd(dtext, "'");          } -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -1406,7 +1406,7 @@ static bool annotate_elf_section_header_table(GElfFormat *format)                  break;          } -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          SET_IMM_DISPLAY(instr, operand, 0, disp); @@ -1460,7 +1460,7 @@ static bool annotate_elf_section_header_table(GElfFormat *format)          {              /* Champ "sh_flags" (suite) */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, dtext); @@ -1468,19 +1468,19 @@ static bool annotate_elf_section_header_table(GElfFormat *format)              /* Champ "sh_addr" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section virtual addr at execution"));              /* Champ "sh_offset" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section file offset"));              /* Champ "sh_size" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -1491,7 +1491,7 @@ static bool annotate_elf_section_header_table(GElfFormat *format)          {              /* Champ "sh_flags" (suite) */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, dtext); @@ -1499,19 +1499,19 @@ static bool annotate_elf_section_header_table(GElfFormat *format)              /* Champ "sh_addr" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section virtual addr at execution"));              /* Champ "sh_offset" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section file offset"));              /* Champ "sh_size" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -1521,13 +1521,13 @@ static bool annotate_elf_section_header_table(GElfFormat *format)          /* Champ "sh_link" */ -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Link to another section"));          /* Champ "sh_info" */ -        instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +        instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);          ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Additional section information")); @@ -1535,13 +1535,13 @@ static bool annotate_elf_section_header_table(GElfFormat *format)          {              /* Champ "sh_addralign" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section alignment"));              /* Champ "sh_entsize" */ -            instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_32_BITS, 1, pos, length, format->endian);              SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); @@ -1552,13 +1552,13 @@ static bool annotate_elf_section_header_table(GElfFormat *format)          {              /* Champ "sh_addralign" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              ADD_RAW_AS_SYM(format, symbol, pos, instr, comment, _("Section alignment"));              /* Champ "sh_entsize" */ -            instr = g_raw_instruction_new_array(content, MDS_64_BITS, 1, pos, length, format->endian); +            instr = g_raw_instruction_new_array_old(content, MDS_64_BITS, 1, pos, length, format->endian);              SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); diff --git a/src/format/format-int.h b/src/format/format-int.h index 22b0c0f..96ff081 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -41,6 +41,7 @@ struct _GBinFormat  {      GObject parent;                         /* A laisser en premier        */ +    GBinContent *conten_;                   /* Contenu binaire à étudier   */      const bin_t *content;                   /* Contenu binaire à étudier   */      off_t length;                           /* Taille de ce contenu        */ diff --git a/src/format/format.c b/src/format/format.c index c779947..fa00856 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -105,6 +105,7 @@ static void g_binary_format_init(GBinFormat *format)  void g_binary_format_set_content(GBinFormat *format, GBinContent *content)  { +    format->conten_ = content;      format->content = g_binary_content_get(content, &format->length); diff --git a/src/glibext/gbincontent.c b/src/glibext/gbincontent.c index c72ac15..e0c64d4 100644 --- a/src/glibext/gbincontent.c +++ b/src/glibext/gbincontent.c @@ -24,6 +24,7 @@  #include "gbincontent.h" +#include <assert.h>  #include <fcntl.h>  #include <malloc.h>  #include <stdio.h> @@ -33,6 +34,9 @@  #include <sys/stat.h> +#include "../common/endianness.h" + +  /* Aire de contenu binaire */  typedef struct _binary_part @@ -73,6 +77,9 @@ static void g_binary_content_dispose(GBinContent *);  /* Procède à la libération totale de la mémoire. */  static void g_binary_content_finalize(GBinContent *); +/* Retrouve la zone adaptée pour une localisation de données. */ +static const binary_part *g_binary_content_find_part(const GBinContent *, const vmpa2t *, phys_t *); +  /* Indique le type défini par la GLib pour les contenus de données. */ @@ -239,10 +246,43 @@ GBinContent *g_binary_content_new_from_file(const char *filename)  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à venir lire.                      * +*                addr    = position de la tête de lecture globale demandée.   * +*                start   = position de la tête de lecture dans la zone. [OUT] * +*                                                                             * +*  Description : Retrouve la zone adaptée pour une localisation de données.   * +*                                                                             * +*  Retour      : Partie trouvée ou NULL en cas d'échec.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +static const binary_part *g_binary_content_find_part(const GBinContent *content, const vmpa2t *addr, phys_t *start) +{ +    const binary_part *result;              /* Trouvaille à retourner      */ +    size_t i;                               /* Boucle de parcours          */ +    binary_part *part;                      /* Zone mémoire manipulée      */ +    result = NULL; +    for (i = 0; i < content->count && result == NULL; i++) +    { +        part = &content->parts[i]; + +        if (mrange_contains_addr(&part->range, addr)) +            result = part; + +    } +    if (result != NULL) +        *start = compute_vmpa_diff(get_mrange_addr(&result->range), addr); + +    return result; + +}  /****************************************************************************** @@ -260,19 +300,367 @@ GBinContent *g_binary_content_new_from_file(const char *filename)  *                                                                             *  ******************************************************************************/ -bool g_binary_content_get_raw(const GBinContent *content, const vmpa2t *addr, phys_t length, bin_t *out) +bool g_binary_content_get_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out)  { +    bool result; +    phys_t offset; +      /* FIXME */ -    memcpy(out, &content->parts[0].data[get_phy_addr(addr)], length); +    offset = get_phy_addr(addr); + +    memcpy(out, &content->parts[0].data[offset], length); + +    advance_vmpa(addr, length); + +    return true; + +} + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à venir lire.                      * +*                addr    = position de la tête de lecture.                    * +*                low     = position éventuelle des 4 bits visés. [OUT]        * +*                endian  = ordre des bits dans la source.                     * +*                val     = lieu d'enregistrement de la lecture. [OUT]         * +*                                                                             * +*  Description : Lit un nombre non signé sur quatre bits.                     * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian, uint8_t *val) +{ +    phys_t start;                           /* Tête de lecture relative    */ +    const binary_part *part;                /* Zone de mémoire effective   */ +    bin_t *data;                            /* Contenu binaire représenté  */ + +    part = g_binary_content_find_part(content, addr, &start); +    if (part == NULL) return false; + +    if ((get_mrange_length(&part->range) - start) < 1) return false; + +    data = part->data; + +    if (*low) +    { +        *val = data[start] & 0x0f; +        *low = false; +    } +    else +    { +        *val = (data[start] & 0xf0) >> 4; +        *low = true; +        advance_vmpa(addr, 4); +    } + +    return true; + +} + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à venir lire.                      * +*                addr    = position de la tête de lecture.                    * +*                endian  = ordre des bits dans la source.                     * +*                val     = lieu d'enregistrement de la lecture. [OUT]         * +*                                                                             * +*  Description : Lit un nombre non signé sur un octet.                        * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint8_t *val) +{ +    phys_t start;                           /* Tête de lecture relative    */ +    const binary_part *part;                /* Zone de mémoire effective   */ +    bin_t *data;                            /* Contenu binaire représenté  */ + +    part = g_binary_content_find_part(content, addr, &start); +    if (part == NULL) return false; + +    if ((get_mrange_length(&part->range) - start) < 1) return false; + +    data = part->data; + +    *val = data[start]; + +    advance_vmpa(addr, 1); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à venir lire.                      * +*                addr    = position de la tête de lecture.                    * +*                endian  = ordre des bits dans la source.                     * +*                val     = lieu d'enregistrement de la lecture. [OUT]         * +*                                                                             * +*  Description : Lit un nombre non signé sur deux octets.                     * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) +{ +    phys_t start;                           /* Tête de lecture relative    */ +    const binary_part *part;                /* Zone de mémoire effective   */ +    bin_t *data;                            /* Contenu binaire représenté  */ + +    part = g_binary_content_find_part(content, addr, &start); +    if (part == NULL) return false; + +    if ((get_mrange_length(&part->range) - start) < 2) return false; + +    data = part->data; + +    switch (endian) +    { +        case SRE_LITTLE: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *val = data[start] | (uint16_t)data[start + 1] << 8; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *val = data[start + 1] | (uint16_t)data[start] << 8; + +#else + +#   error "TODO : extra byte order !" + +#endif + +            break; + +        case SRE_MIDDLE: +            assert(false);   /* TODO */ +            break; + +        case SRE_BIG: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *val = data[start + 1] | (uint16_t)data[start] << 8; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *val = data[start] | (uint16_t)data[start + 1] << 8; + +#else + +#   error "TODO : extra byte order !" + +#endif + +            break; + + +    } + +    advance_vmpa(addr, 2); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à venir lire.                      * +*                addr    = position de la tête de lecture.                    * +*                endian  = ordre des bits dans la source.                     * +*                val     = lieu d'enregistrement de la lecture. [OUT]         * +*                                                                             * +*  Description : Lit un nombre non signé sur quatre octets.                   * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) +{ +    phys_t start;                           /* Tête de lecture relative    */ +    const binary_part *part;                /* Zone de mémoire effective   */ +    bin_t *data;                            /* Contenu binaire représenté  */ + +    part = g_binary_content_find_part(content, addr, &start); +    if (part == NULL) return false; + +    if ((get_mrange_length(&part->range) - start) < 4) return false; + +    data = part->data; + +    switch (endian) +    { +        case SRE_LITTLE: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *val = data[start] | (uint32_t)data[start + 1] << 8; +            *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *val = data[start + 3] | (uint32_t)data[start + 2] << 8; +            *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24; + +#else + +#   error "TODO : extra byte order !" + +#endif + +            break; + +        case SRE_MIDDLE: +            assert(false);  /* TODO */ +            break; + +        case SRE_BIG: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *val = data[start + 3] | (uint32_t)data[start + 2] << 8; +            *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *val = data[start] | (uint32_t)data[start + 1] << 8; +            *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24; + +#else + +#   error "TODO : extra byte order !" + +#endif + +            break; + + +    } + +    advance_vmpa(addr, 4);      return true;  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à venir lire.                      * +*                addr    = position de la tête de lecture.                    * +*                endian  = ordre des bits dans la source.                     * +*                val     = lieu d'enregistrement de la lecture. [OUT]         * +*                                                                             * +*  Description : Lit un nombre non signé sur huit octets.                     * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) +{ +    phys_t start;                           /* Tête de lecture relative    */ +    const binary_part *part;                /* Zone de mémoire effective   */ +    bin_t *data;                            /* Contenu binaire représenté  */ + +    part = g_binary_content_find_part(content, addr, &start); +    if (part == NULL) return false; + +    if ((get_mrange_length(&part->range) - start) < 8) return false; +    data = part->data; +    switch (endian) +    { +        case SRE_LITTLE: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8; +            *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24; +            *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40; +            *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8; +            *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24; +            *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40; +            *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56; + +#else + +#   error "TODO : extra byte order !" + +#endif + +            break; + +        case SRE_MIDDLE: +            assert(false);  /* TODO */ +            break; + +        case SRE_BIG: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8; +            *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24; +            *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40; +            *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8; +            *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24; +            *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40; +            *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56; + +#else + +#   error "TODO : extra byte order !" + +#endif + +            break; + + +    } + +    advance_vmpa(addr, 8); + +    return true; + +} diff --git a/src/glibext/gbincontent.h b/src/glibext/gbincontent.h index 1bfcfa5..e2f5933 100644 --- a/src/glibext/gbincontent.h +++ b/src/glibext/gbincontent.h @@ -59,10 +59,33 @@ GBinContent *g_binary_content_new_from_file(const char *);  /* Fournit une portion des données représentées. */ -bool g_binary_content_get_raw(const GBinContent *, const vmpa2t *, phys_t, bin_t *); +bool g_binary_content_get_raw(const GBinContent *, vmpa2t *, phys_t, bin_t *); +/* Lit un nombre non signé sur quatre bits. */ +bool g_binary_content_read_u4(const GBinContent *, vmpa2t *, bool *, SourceEndian, uint8_t *); + +/* Lit un nombre non signé sur un octet. */ +bool g_binary_content_read_u8(const GBinContent *, vmpa2t *, SourceEndian, uint8_t *); + +/* Lit un nombre non signé sur deux octets. */ +bool g_binary_content_read_u16(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *); + +/* Lit un nombre non signé sur quatre octets. */ +bool g_binary_content_read_u32(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *); + +/* Lit un nombre non signé sur huit octets. */ +bool g_binary_content_read_u64(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *); + + +#define g_binary_content_read_s4(c, a, l, e, v) g_binary_content_read_u4(c, a, l, e, (uint8_t *)v) +#define g_binary_content_read_s8(c, a, e, v) g_binary_content_read_u8(c, a, e, (uint8_t *)v) +#define g_binary_content_read_s16(c, a, e, v) g_binary_content_read_u16(c, a, e, (uint16_t *)v) +#define g_binary_content_read_s32(c, a, e, v) g_binary_content_read_u32(c, a, e, (uint32_t *)v) +#define g_binary_content_read_s64(c, a, e, v) g_binary_content_read_u64(c, a, e, (uint64_t *)v) + +  const bin_t *g_binary_content_get(GBinContent *content, off_t *length); diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h index d1a13b7..edab3a5 100644 --- a/src/plugins/plugin-def.h +++ b/src/plugins/plugin-def.h @@ -69,14 +69,15 @@ typedef uint32_t plugin_action_t;  #define MASK_PLUGIN_SUB_CATEGORY(val) (val & (0xff << 16)) -#define DPC_NONE                DEFINE_PLUGIN_CATEGORY(0) +#define DPC_BASIC               DEFINE_PLUGIN_CATEGORY(0)  #define DPC_BINARY_PROCESSING   DEFINE_PLUGIN_CATEGORY(1)  // GUI -/* DPC_NONE */ +/* DPC_BASIC */  #define DPS_NONE                DEFINE_PLUGIN_SUB_CATEGORY(0) +#define DPS_PG_MANAGEMENT       DEFINE_PLUGIN_SUB_CATEGORY(1)  /* DPC_BINARY_PROCESSING */ @@ -94,8 +95,22 @@ typedef uint32_t plugin_action_t;  /* Action(s) menée(s) par un greffon */  typedef enum _PluginAction  { +    /** +     * DPC_BASIC | DPS_NONE +     */ +      /* Aucun intérêt */ -    PGA_NONE = DPC_NONE | DPS_NONE | DEFINE_PLUGIN_ACTION(0), +    PGA_BASIC_NONE = DPC_BASIC | DPS_NONE | DEFINE_PLUGIN_ACTION(0), + +    /** +     * DPC_BASIC | DPS_NONE +     */ + +    /* Chargement */ +    PGA_PLUGIN_INIT = DPC_BASIC | DPS_PG_MANAGEMENT | DEFINE_PLUGIN_ACTION(0), + +    /* Déchargement */ +    PGA_PLUGIN_EXIT = DPC_BASIC | DPS_PG_MANAGEMENT | DEFINE_PLUGIN_ACTION(1),      /**       * DPC_BINARY_PROCESSING | DPS_FORMAT diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h index 7a3fb3e..1bf459c 100644 --- a/src/plugins/plugin-int.h +++ b/src/plugins/plugin-int.h @@ -26,14 +26,18 @@  #include <glib-object.h> +#include <stdbool.h>  #include "plugin.h"  #include "plugin-def.h" +#include "../glibext/gbincontent.h"  #include "../gui/panels/log.h" +/* Prend acte du [dé]chargement du greffon. */ +typedef bool (* pg_management_fc) (GPluginModule *);  /* Indique si le format peut être pris en charge ici. */  typedef bool (* pg_format_is_matching) (const GPluginModule *, GBinContent **); @@ -78,14 +82,16 @@ struct _GPluginModule      const plugin_interface *interface;      /* Déclaration d'interfaçage   */ +    pg_management_fc init;                  /* Procédure d'initialisation  */ +    pg_management_fc exit;                  /* Procédure d'extinction      */      //char *name;                             /* Nom associé au greffon      */      //PluginType type;                        /* Type(s) du greffon          */ -    init_plugin_fc init;                    /* Procédure d'initialisation  */ -    exit_plugin_fc exit;                    /* Procédure d'extinction      */ +    //init_plugin_fc init;                    /* Procédure d'initialisation  */ +    //exit_plugin_fc exit;                    /* Procédure d'extinction      */      get_plugin_action_fc get_action;        /* Opération(s) menée(s)       */      //is_matching_fc is_matching;             /* Recherche de correspondance */ diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index fd55f8c..0ca19e4 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -222,13 +222,25 @@ GPluginModule *g_plugin_module_new(const gchar *filename)          switch (category)          { -            case DPC_NONE: +            case DPC_BASIC:                  switch (sub)                  {                      case DPS_NONE:                          break; +                    case PGA_PLUGIN_INIT: +                        if (!load_plugin_symbol(result->module, +                                                "chrysalide_plugin_init", &result->init)) +                            goto bad_plugin; +                        break; + +                    case PGA_PLUGIN_EXIT: +                        if (!load_plugin_symbol(result->module, +                                                "chrysalide_plugin_exit", &result->exit)) +                            goto bad_plugin; +                        break; +                      default:                          log_variadic_message(LMT_WARNING,                                               _("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename); @@ -269,27 +281,21 @@ GPluginModule *g_plugin_module_new(const gchar *filename)      } - - - - -    /* -    if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init)) -        result->init = NULL; - -    if (!g_module_symbol(result->module, "exit_plugin", (gpointer *)&result->exit)) -        result->exit = NULL; -    */ - - - - -      /* Conclusion */      dir = strdup(filename);      dir = dirname(dir); +    if (result->init != NULL) +    { +        if (!result->init(result)) +        { +            log_variadic_message(LMT_ERROR, +                                 _("Plugin '%s' failed to load itself..."), filename); +            goto bad_plugin; +        } +    } +      log_variadic_message(LMT_PROCESS, _("Loaded the '<b>%s</b>' from the '<b>%s</b>' directory"),                           strrchr(filename, G_DIR_SEPARATOR) + 1, dir); | 
