diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/analysis/decomp/Makefile.am | 1 | ||||
| -rw-r--r-- | src/analysis/decomp/cmerge.c | 135 | ||||
| -rw-r--r-- | src/analysis/decomp/cmerge.h | 37 | ||||
| -rw-r--r-- | src/analysis/decomp/decompiler.c | 7 | ||||
| -rw-r--r-- | src/arch/dalvik/decomp/if.c | 29 | ||||
| -rw-r--r-- | src/decomp/expr/Makefile.am | 1 | ||||
| -rw-r--r-- | src/decomp/expr/block.c | 27 | ||||
| -rw-r--r-- | src/decomp/expr/block.h | 3 | ||||
| -rw-r--r-- | src/decomp/expr/comp.c | 311 | ||||
| -rw-r--r-- | src/decomp/expr/comp.h | 60 | ||||
| -rw-r--r-- | src/decomp/expr/cond.c | 287 | ||||
| -rw-r--r-- | src/decomp/expr/cond.h | 18 | ||||
| -rw-r--r-- | src/decomp/expression-int.h | 7 | ||||
| -rw-r--r-- | src/decomp/expression.c | 63 | ||||
| -rw-r--r-- | src/decomp/expression.h | 5 | ||||
| -rw-r--r-- | src/decomp/instr/ite.c | 57 | ||||
| -rw-r--r-- | src/decomp/instr/ite.h | 9 | ||||
| -rw-r--r-- | src/decomp/lang/java.c | 77 | ||||
| -rw-r--r-- | src/decomp/output-int.h | 13 | ||||
| -rw-r--r-- | src/decomp/output.c | 53 | ||||
| -rw-r--r-- | src/decomp/output.h | 30 | 
21 files changed, 1154 insertions, 76 deletions
| diff --git a/src/analysis/decomp/Makefile.am b/src/analysis/decomp/Makefile.am index 27388d6..0e3ffb4 100755 --- a/src/analysis/decomp/Makefile.am +++ b/src/analysis/decomp/Makefile.am @@ -2,6 +2,7 @@  noinst_LTLIBRARIES = libanalysisdecomp.la  libanalysisdecomp_la_SOURCES =			\ +	cmerge.h cmerge.c					\  	decompiler.h decompiler.c			\  	il.h il.c							\  	reduce.h reduce.c diff --git a/src/analysis/decomp/cmerge.c b/src/analysis/decomp/cmerge.c new file mode 100644 index 0000000..9838531 --- /dev/null +++ b/src/analysis/decomp/cmerge.c @@ -0,0 +1,135 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * cmerge.c - fusion des conditions successives + * + * Copyright (C) 2013 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "cmerge.h" + + +#include "../../decomp/expr/block.h" +#include "../../decomp/expr/comp.h" +#include "../../decomp/expr/cond.h" +#include "../../decomp/instr/ite.h" + + + +/* Recherche des conditions successives pouvant être fusionnées. */ +static bool track_branch_conditions(GDecInstruction *, GDecInstruction *, DecInstrVisitFlags, void *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr  = instruction visitée.                                * +*                parent = instruction parente.                                * +*                flags  = moments des appels réalisés en retour.              * +*                data   = adresse non utilisée ici.                           * +*                                                                             * +*  Description : Recherche des conditions successives pouvant être fusionnées.* +*                                                                             * +*  Retour      : true afin d'aller jusqu'au terme du parcours.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool track_branch_conditions(GDecInstruction *instr, GDecInstruction *parent, DecInstrVisitFlags flags, void *data) +{ +    GDecInstruction *true_branch;           /* Branche 'vrai'              */ +    GDecInstruction *false_branch;          /* Branche 'faux'              */ +    GDecInstruction *first;                 /* Première sous-instruction   */ +    GCondExpression *sub_cond;              /* Expression conditionnelle   */ +    GCondExpression *top_cond;              /* Expression conditionnelle   */ + +    if (!G_IS_ITE_INSTRUCTION(instr)) +        goto tbc_done; + +    g_ite_instruction_get_branches(G_ITE_INSTRUCTION(instr), &true_branch, &false_branch); +    if (false_branch != NULL) goto tbc_done; + +    /* count(block) == 1 */ + +    first = g_expr_block_get_item(G_EXPR_BLOCK(true_branch), 0); +    if (!G_IS_ITE_INSTRUCTION(first)) goto tbc_done; + +    printf("got one!\n"); + +    /* Récupération des informations inférieures */ + +    sub_cond = g_ite_instruction_get_condition(G_ITE_INSTRUCTION(first)); +    g_object_ref(G_OBJECT(sub_cond)); + +    g_ite_instruction_get_branches(G_ITE_INSTRUCTION(first), &true_branch, &false_branch); +    if (true_branch != NULL) g_object_ref(G_OBJECT(true_branch)); +    if (false_branch != NULL) g_object_ref(G_OBJECT(false_branch)); + +    /* Reconstitution d'une nouvelle instruction */ + +    top_cond = g_ite_instruction_get_condition(G_ITE_INSTRUCTION(instr)); + +    //g_cond_expression_add_condition(top_cond, sub_cond, COT_AND); + +    //g_ite_instruction_set_branches(G_ITE_INSTRUCTION(instr), true_branch, false_branch); + + + + +    printf("got one!\n"); + +    /* +GDecExpression *g_ite_instruction_get_condition(const GITEInstruction *instr) + + + +GDecExpression *g_cond_expression_get_expression(const GCondExpression *cond) + + +void g_cond_expression_set_expression(GCondExpression *cond, GDecExpression *exp) +    */ + + + tbc_done: + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instructions à traiter.                              * +*                                                                             * +*  Description : Fusionne les conditions qui s'enchaînent.                    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void merge_lonely_conditions(GDecInstruction *instr) +{ +    return; + +    g_dec_instruction_visit(instr, (dec_instr_visitor_cb)track_branch_conditions, +                            DVF_EXIT, NULL); + +} diff --git a/src/analysis/decomp/cmerge.h b/src/analysis/decomp/cmerge.h new file mode 100644 index 0000000..0b556c6 --- /dev/null +++ b/src/analysis/decomp/cmerge.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * cmerge.h - prototypes pour la fusion des conditions successives + * + * Copyright (C) 2013 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 _ANALYSIS_DECOMP_CMERGE_H +#define _ANALYSIS_DECOMP_CMERGE_H + + +#include "../../decomp/instruction.h" + + + +/* Fusionne les conditions qui s'enchaînent. */ +void merge_lonely_conditions(GDecInstruction *); + + + +#endif  /* _ANALYSIS_DECOMP_CMERGE_H */ diff --git a/src/analysis/decomp/decompiler.c b/src/analysis/decomp/decompiler.c index c36811d..89f9d49 100644 --- a/src/analysis/decomp/decompiler.c +++ b/src/analysis/decomp/decompiler.c @@ -32,6 +32,7 @@  #include <i18n.h> +#include "cmerge.h"  #include "il.h"  #include "reduce.h"  #include "../../decomp/output.h" @@ -184,7 +185,9 @@ static void prepare_all_routines_for_decomp(const GLoadedBinary *binary, const c          //instr = g_binary_format_decompile_routine(G_BIN_FORMAT(format), routines[i], context); -        reduce_used_variables(dinstrs); +        //merge_lonely_conditions(dinstrs); + +        /////reduce_used_variables(dinstrs);          g_expr_block_set_border_behavior(G_EXPR_BLOCK(dinstrs), BBB_FORCE_ON); @@ -228,7 +231,7 @@ GCodeBuffer *decompile_all_from_file(const GLoadedBinary *binary, const char *fi      build_decomp_prologue(result, filename); -    prepare_all_routines_for_decomp(binary, filename); +    //prepare_all_routines_for_decomp(binary, filename); diff --git a/src/arch/dalvik/decomp/if.c b/src/arch/dalvik/decomp/if.c index f7591b9..c82413d 100644 --- a/src/arch/dalvik/decomp/if.c +++ b/src/arch/dalvik/decomp/if.c @@ -25,6 +25,7 @@  #include "../instruction.h" +#include "../../../decomp/expr/comp.h"  #include "../../../decomp/expr/cond.h"  #include "../../../decomp/expr/immediate.h"  #include "../../../decomp/instr/ite.h" @@ -53,7 +54,8 @@ GDecInstruction *dalvik_decomp_instr_if(const GArchInstruction *instr, GDecConte      GDecInstruction *op1;                   /* Premier opérande utilisé    */      GDecInstruction *op2;                   /* Second opérande utilisé     */      vmpa_t jmp;                             /* Adresse de saut             */ -    GDecInstruction *cond;                  /* Comparaison à restituer     */ +    GDecInstruction *comp;                  /* Comparaison à restituer     */ +    GDecInstruction *cond;                  /* Transformation en condition */      switch (g_dalvik_instruction_get_opcode(G_DALVIK_INSTRUCTION(instr)))      { @@ -91,8 +93,9 @@ GDecInstruction *dalvik_decomp_instr_if(const GArchInstruction *instr, GDecConte      operand = g_arch_instruction_get_operand(instr, 2);      jmp = 0x1234ull;/*g_dec_context_convert_register(ctx, operand, addr);*/ -    cond = g_cond_expression_new(G_DEC_EXPRESSION(op1), sign, G_DEC_EXPRESSION(op2)); -    result = g_ite_instruction_new(G_DEC_EXPRESSION(cond), jmp, jmp); +    comp = g_comp_expression_new(G_DEC_EXPRESSION(op1), sign, G_DEC_EXPRESSION(op2)); +    cond = g_cond_expression_new(comp); +    result = g_ite_instruction_new(cond, jmp, jmp);      return result; @@ -122,26 +125,27 @@ GDecInstruction *dalvik_decomp_instr_if_zero(const GArchInstruction *instr, GDec      GDecInstruction *op1;                   /* Premier opérande utilisé    */      GDecInstruction *op2;                   /* Second opérande utilisé     */      vmpa_t jmp;                             /* Adresse de saut             */ -    GDecInstruction *cond;                  /* Comparaison à restituer     */ +    GDecInstruction *comp;                  /* Comparaison à restituer     */ +    GDecInstruction *cond;                  /* Transformation en condition */      switch (g_dalvik_instruction_get_opcode(G_DALVIK_INSTRUCTION(instr)))      { -        case DOP_IF_EQ: +        case DOP_IF_EQZ:              sign = CST_EQ;              break; -        case DOP_IF_NE: +        case DOP_IF_NEZ:              sign = CST_NE;              break; -        case DOP_IF_LT: +        case DOP_IF_LTZ:              sign = CST_LT;              break; -        case DOP_IF_GE: +        case DOP_IF_GEZ:              sign = CST_GE;              break; -        case DOP_IF_GT: +        case DOP_IF_GTZ:              sign = CST_GT;              break; -        case DOP_IF_LE: +        case DOP_IF_LEZ:              sign = CST_LE;              break;          default: @@ -160,8 +164,9 @@ GDecInstruction *dalvik_decomp_instr_if_zero(const GArchInstruction *instr, GDec      operand = g_arch_instruction_get_operand(instr, 2);      jmp = 0x1234ull;/*g_dec_context_convert_register(ctx, operand, addr);*/ -    cond = g_cond_expression_new(G_DEC_EXPRESSION(op1), sign, G_DEC_EXPRESSION(op2)); -    result = g_ite_instruction_new(G_DEC_EXPRESSION(cond), jmp, jmp); +    comp = g_comp_expression_new(G_DEC_EXPRESSION(op1), sign, G_DEC_EXPRESSION(op2)); +    cond = g_cond_expression_new(comp); +    result = g_ite_instruction_new(cond, jmp, jmp);      return result; diff --git a/src/decomp/expr/Makefile.am b/src/decomp/expr/Makefile.am index 483a1f3..3ff6cb5 100644 --- a/src/decomp/expr/Makefile.am +++ b/src/decomp/expr/Makefile.am @@ -8,6 +8,7 @@ libdecompexpr_la_SOURCES =				\  	assign.h assign.c					\  	block.h block.c						\  	call.h call.c						\ +	comp.h comp.c						\  	cond.h cond.c						\  	immediate.h immediate.c				\  	pseudo.h pseudo.c					\ diff --git a/src/decomp/expr/block.c b/src/decomp/expr/block.c index 7c2387a..6b811f6 100644 --- a/src/decomp/expr/block.c +++ b/src/decomp/expr/block.c @@ -333,6 +333,33 @@ void g_expr_block_add_item(GExprBlock *block, GDecInstruction *item)  /******************************************************************************  *                                                                             * +*  Paramètres  : block = ensemble à consulter.                                * +*                index = indice de l'instruction décompilée recherchée.       * +*                                                                             * +*  Description : Fournit une instruction décompilée donnée du conteneur.      * +*                                                                             * +*  Retour      : Instruction décompilée, ou NULL si l'indice n'est pas valide.* +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDecInstruction *g_expr_block_get_item(const GExprBlock *block, size_t index) +{ +    GDecInstruction *result;                /* Elément à retourner         */ + +    result = NULL; + +    if (index < block->count) +        result = block->list[index]; + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : block = ensemble à faire évoluer.                            *  *                item  = nouvel élément à retirer de l'ensemble.              *  *                                                                             * diff --git a/src/decomp/expr/block.h b/src/decomp/expr/block.h index b0788dd..92ac9f9 100644 --- a/src/decomp/expr/block.h +++ b/src/decomp/expr/block.h @@ -73,6 +73,9 @@ void g_expr_block_set_border_behavior(GExprBlock *, BlockBordeBehavior);  /* Ajoute une instruction décompilée au conteneur existant. */  void g_expr_block_add_item(GExprBlock *, GDecInstruction *); +/* Fournit une instruction décompilée donnée du conteneur. */ +GDecInstruction *g_expr_block_get_item(const GExprBlock *, size_t); +  /* Supprime une instruction décompilée du conteneur existant. */  void g_expr_block_delete_item(GExprBlock *, GDecInstruction *); diff --git a/src/decomp/expr/comp.c b/src/decomp/expr/comp.c new file mode 100644 index 0000000..3852aa8 --- /dev/null +++ b/src/decomp/expr/comp.c @@ -0,0 +1,311 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * comp.c - représentation des comparaisons + * + * Copyright (C) 2013 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 "comp.h" + + +#include "../expression-int.h" + + + +/* Définition d'une comparaison binaire quelconque (instance) */ +struct _GCompExpression +{ +    GDecExpression parent;                  /* A laisser en premier        */ + +    GDecExpression *a;                      /* Premier élément à comparer  */ +    CompSignType sign;                      /* Méthode de comparaison      */ +    GDecExpression *b;                      /* Second élément à comparer   */ + +}; + + +/* Définition d'une comparaison binaire quelconque (classe) */ +struct _GCompExpressionClass +{ +    GDecExpressionClass parent;             /* A laisser en premier        */ + +}; + + + +/* Initialise la classe des comparaisons binaires quelconques. */ +static void g_comp_expression_class_init(GCompExpressionClass *); + +/* Initialise une instance de comparaison binaire quelconque. */ +static void g_comp_expression_init(GCompExpression *); + +/* Visite un ensemble hiérarchique d'instructions décompilées. */ +static bool g_comp_expression_visit(GCompExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *); + +/* Remplace une instruction décompilée par une autre. */ +static bool g_comp_expression_replace(GCompExpression *, GDecInstruction *, GDecInstruction *); + +/* Imprime pour l'écran un version humaine d'une expression. */ +static GBufferLine *g_comp_expression_print(const GCompExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *); + +/* Réalise une négation sur une expression décompilée. */ +static bool g_comp_expression_negate(GCompExpression *); + + + +/* Indique le type défini pour une comparaison binaire quelconque. */ +G_DEFINE_TYPE(GCompExpression, g_comp_expression, G_TYPE_DEC_EXPRESSION); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des comparaisons binaires quelconques.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_comp_expression_class_init(GCompExpressionClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise une instance de comparaison binaire quelconque.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_comp_expression_init(GCompExpression *expr) +{ +    GDecInstruction *instr;                 /* Autre version de l'objet    */ +    GDecExpression *base;                   /* Autre version de l'objet    */ + +    instr = G_DEC_INSTRUCTION(expr); + +    instr->visit = (dec_instr_visit_fc)g_comp_expression_visit; +    instr->replace = (dec_instr_replace_fc)g_comp_expression_replace; +    instr->print = (dec_instr_print_fc)g_comp_expression_print; + +    base = G_DEC_EXPRESSION(expr); + +    base->negate = (dec_expr_negate_fc)g_comp_expression_negate; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a    = second élément à comparer.                            * +*                sign = choix de la méthode de comparaison.                   * +*                b    = second élément à comparer.                            * +*                                                                             * +*  Description : Exprime une comparaison binaire quelconque.                  * +*                                                                             * +*  Retour      : Expression mise en place.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDecExpression *g_comp_expression_new(GDecExpression *a, CompSignType sign, GDecExpression *b) +{ +    GCompExpression *result;              /* Expression à retourner      */ + +    result = g_object_new(G_TYPE_COMP_EXPRESSION, NULL); + +    result->a = a; +    result->sign = sign; +    result->b = b; + +    return G_DEC_EXPRESSION(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr     = première instruction à venir visiter.             * +*                callback = procédure à appeler à chaque instruction visitée. * +*                flags    = moments des appels à réaliser en retour.          * +*                data     = données quelconques associées au visiteur.        * +*                                                                             * +*  Description : Visite un ensemble hiérarchique d'instructions décompilées.  * +*                                                                             * +*  Retour      : true si le parcours a été jusqu'à son terme, false sinon.    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_comp_expression_visit(GCompExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->a), G_DEC_INSTRUCTION(expr), +                                      callback, flags, data); + +    if (result) +        result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->b), G_DEC_INSTRUCTION(expr), +                                          callback, flags, data); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr = première instruction à venir ausculter.               * +*                old  = instruction décompilée à venir remplacer.             * +*                new  = instruction décompilée à utiliser dorénavant.         * +*                                                                             * +*  Description : Remplace une instruction décompilée par une autre.           * +*                                                                             * +*  Retour      : true si un remplacement a été effectué, false sinon.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_comp_expression_replace(GCompExpression *expr, GDecInstruction *old, GDecInstruction *new) +{ +    bool result;                            /* Bilan à retourner           */ + +    if (expr->a == G_DEC_EXPRESSION(old)) +    { +        g_object_unref(G_OBJECT(expr->a)); +        g_object_ref(G_OBJECT(new)); +        expr->a = G_DEC_EXPRESSION(new); + +        result = true; + +    } +    else +        result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->a), old, new); + +    if (expr->b == G_DEC_EXPRESSION(old)) +    { +        g_object_unref(G_OBJECT(expr->b)); +        g_object_ref(G_OBJECT(new)); +        expr->b = G_DEC_EXPRESSION(new); + +        result = true; + +    } +    else +        result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->b), old, new); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr   = expression à transcrire en version humaine.         * +*                buffer = tampon où doit se réaliser l'insertion.             * +*                line   = ligne d'impression prête à emploi ou NULL.          * +*                output = langage de programmation de sortie.                 * +*                                                                             * +*  Description : Imprime pour l'écran un version humaine d'une expression.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBufferLine *g_comp_expression_print(const GCompExpression *expr, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output) +{ +    GBufferLine *result;                    /* Ligne à retourner           */ + +    result = line; + +    result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->a), +                                     buffer, result, output); + +    g_lang_output_write_comp_sign(output, result, expr->sign); + +    result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->b), +                                     buffer, result, output); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr = instance à traiter.                                   * +*                                                                             * +*  Description : Réalise une négation sur une expression décompilée.          * +*                                                                             * +*  Retour      : true si la négation a été gérée, false sinon.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_comp_expression_negate(GCompExpression *expr) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    switch (expr->sign) +    { +        case CST_EQ: +            expr->sign = CST_NE; +            break; +        case CST_NE: +            expr->sign = CST_EQ; +            break; +        case CST_LT: +            expr->sign = CST_GE; +            break; +        case CST_GE: +            expr->sign = CST_LT; +            break; +        case CST_GT: +            expr->sign = CST_LE; +            break; +        case CST_LE: +            expr->sign = CST_GT; +            break; +        default: +            result = false; +            break; + +    } + +    return result; + +} diff --git a/src/decomp/expr/comp.h b/src/decomp/expr/comp.h new file mode 100644 index 0000000..8599aa0 --- /dev/null +++ b/src/decomp/expr/comp.h @@ -0,0 +1,60 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * comp.h - prototypes pour la représentation des comparaisons + * + * Copyright (C) 2013 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  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 _DECOMP_EXPR_COMP_H +#define _DECOMP_EXPR_COMP_H + + +#include <glib-object.h> + + +#include "../expression.h" +#include "../output.h" + + + +#define G_TYPE_COMP_EXPRESSION               g_comp_expression_get_type() +#define G_COMP_EXPRESSION(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_comp_expression_get_type(), GCompExpression)) +#define G_IS_COMP_EXPRESSION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_comp_expression_get_type())) +#define G_COMP_EXPRESSION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMP_EXPRESSION, GCompExpressionClass)) +#define G_IS_COMP_EXPRESSION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMP_EXPRESSION)) +#define G_COMP_EXPRESSION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMP_EXPRESSION, GCompExpressionClass)) + + + +/* Définition d'une comparaison binaire quelconque (instance) */ +typedef struct _GCompExpression GCompExpression; + +/* Définition d'une comparaison binaire quelconque (classe) */ +typedef struct _GCompExpressionClass GCompExpressionClass; + + +/* Indique le type défini pour une comparaison binaire quelconque. */ +GType g_comp_expression_get_type(void); + +/* Exprime une comparaison binaire quelconque. */ +GDecExpression *g_comp_expression_new(GDecExpression *, CompSignType, GDecExpression *); + + + +#endif  /* _DECOMP_EXPR_COMP_H */ diff --git a/src/decomp/expr/cond.c b/src/decomp/expr/cond.c index fab2c17..c776059 100644 --- a/src/decomp/expr/cond.c +++ b/src/decomp/expr/cond.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * cond.c - représentation des conditions   * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -24,6 +24,9 @@  #include "cond.h" +#include <malloc.h> + +  #include "../expression-int.h" @@ -33,9 +36,17 @@ struct _GCondExpression  {      GDecExpression parent;                  /* A laisser en premier        */ -    GDecExpression *a;                      /* Premier élément à comparer  */ -    CompSignType sign;                      /* Méthode de comparaison      */ -    GDecExpression *b;                      /* Second élément à comparer   */ +    CondOperatorType operator;              /* Opérateur de la liste       */ + +    union +    { +        GDecExpression *exp;                /* Expression analysée de base */ +        struct +        { +            GCondExpression **conds;        /* Liste d'expressions         */ +            size_t count;                   /* Taille de cette liste       */ +        }; +    };  }; @@ -64,6 +75,9 @@ static bool g_cond_expression_replace(GCondExpression *, GDecInstruction *, GDec  /* Imprime pour l'écran un version humaine d'une expression. */  static GBufferLine *g_cond_expression_print(const GCondExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *); +/* Réalise une négation sur une expression décompilée. */ +static bool g_cond_expression_negate(GCondExpression *); +  /* Indique le type défini pour une condition binaire quelconque. */ @@ -90,7 +104,7 @@ static void g_cond_expression_class_init(GCondExpressionClass *klass)  /******************************************************************************  *                                                                             * -*  Paramètres  : expr = instance à initialiser.                               * +*  Paramètres  : cond = instance à initialiser.                               *  *                                                                             *  *  Description : Initialise une instance de condition binaire quelconque.     *  *                                                                             * @@ -100,24 +114,29 @@ static void g_cond_expression_class_init(GCondExpressionClass *klass)  *                                                                             *  ******************************************************************************/ -static void g_cond_expression_init(GCondExpression *expr) +static void g_cond_expression_init(GCondExpression *cond)  {      GDecInstruction *instr;                 /* Autre version de l'objet    */ +    GDecExpression *expr;                   /* Autre version de l'objet    */ -    instr = G_DEC_INSTRUCTION(expr); +    instr = G_DEC_INSTRUCTION(cond);      instr->visit = (dec_instr_visit_fc)g_cond_expression_visit;      instr->replace = (dec_instr_replace_fc)g_cond_expression_replace;      instr->print = (dec_instr_print_fc)g_cond_expression_print; +    expr = G_DEC_EXPRESSION(cond); + +    expr->negate = (dec_expr_negate_fc)g_cond_expression_negate; + +    cond->operator = COT_NONE; +  }  /******************************************************************************  *                                                                             * -*  Paramètres  : a    = second élément à comparer.                            * -*                sign = choix de la méthode de comparaison.                   * -*                b    = second élément à comparer.                            * +*  Paramètres  : exp = expression sur laquelle repose la condition.           *  *                                                                             *  *  Description : Exprime une condition binaire quelconque.                    *  *                                                                             * @@ -127,17 +146,15 @@ static void g_cond_expression_init(GCondExpression *expr)  *                                                                             *  ******************************************************************************/ -GDecInstruction *g_cond_expression_new(GDecExpression *a, CompSignType sign, GDecExpression *b) +GDecExpression *g_cond_expression_new(GDecExpression *exp)  {      GCondExpression *result;              /* Expression à retourner      */      result = g_object_new(G_TYPE_COND_EXPRESSION, NULL); -    result->a = a; -    result->sign = sign; -    result->b = b; +    result->exp = exp; -    return G_DEC_INSTRUCTION(result); +    return G_DEC_EXPRESSION(result);  } @@ -160,14 +177,23 @@ GDecInstruction *g_cond_expression_new(GDecExpression *a, CompSignType sign, GDe  static bool g_cond_expression_visit(GCondExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)  {      bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ -    result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->a), G_DEC_INSTRUCTION(expr), -                                      callback, flags, data); - -    if (result) -        result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->b), G_DEC_INSTRUCTION(expr), +    if (expr->operator == COT_NONE) +        result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->exp), G_DEC_INSTRUCTION(expr),                                            callback, flags, data); +    else +    { +        result = true; + +        for (i = 0; i < expr->count && result; i++) +            result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->conds[i]), +                                              G_DEC_INSTRUCTION(expr), +                                              callback, flags, data); + +    } +      return result;  } @@ -190,30 +216,44 @@ static bool g_cond_expression_visit(GCondExpression *expr, dec_instr_visitor_cb  static bool g_cond_expression_replace(GCondExpression *expr, GDecInstruction *old, GDecInstruction *new)  {      bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ -    if (expr->a == G_DEC_EXPRESSION(old)) +    if (expr->operator == COT_NONE)      { -        g_object_unref(G_OBJECT(expr->a)); -        g_object_ref(G_OBJECT(new)); -        expr->a = G_DEC_EXPRESSION(new); +        if (expr->exp == G_DEC_EXPRESSION(old)) +        { +            g_object_unref(G_OBJECT(expr->exp)); +            g_object_ref(G_OBJECT(new)); +            expr->exp = G_DEC_EXPRESSION(new); -        result = true; +            result = true; + +        } +        else +            result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->exp), old, new);      }      else -        result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->a), old, new); - -    if (expr->b == G_DEC_EXPRESSION(old))      { -        g_object_unref(G_OBJECT(expr->b)); -        g_object_ref(G_OBJECT(new)); -        expr->b = G_DEC_EXPRESSION(new); +        result = false; -        result = true; +        for (i = 0; i < expr->count; i++) +        { +            if (expr->conds[i] == G_COND_EXPRESSION(old)) +            { +                g_object_unref(G_OBJECT(expr->conds[i])); +                g_object_ref(G_OBJECT(new)); +                expr->conds[i] = G_COND_EXPRESSION(new); + +                result = true; + +            } +            else +                result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->conds[i]), old, new); + +        }      } -    else -        result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->b), old, new);      return result; @@ -238,15 +278,184 @@ static bool g_cond_expression_replace(GCondExpression *expr, GDecInstruction *ol  static GBufferLine *g_cond_expression_print(const GCondExpression *expr, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output)  {      GBufferLine *result;                    /* Ligne à retourner           */ +    size_t i;                               /* Boucle de parcours          */ -    result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->a), -                                     buffer, line, output); +    result = g_lang_output_encapsulate_condition(output, buffer, line, true); -    g_lang_output_write_comp_sign(output, result, expr->sign); +    if (expr->operator == COT_NONE) +        result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->exp), +                                         buffer, result, output); -    result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->b), -                                     buffer, result, output); +    else +        for (i = 0; i < expr->count; i++) +        { +            if (i > 0) +                g_lang_output_write_cond_operator(output, result, expr->operator); + +            result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->conds[i]), +                                             buffer, result, output); + +        } + +    result = g_lang_output_encapsulate_condition(output, buffer, result, false);      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cond = instance à traiter.                                   * +*                                                                             * +*  Description : Réalise une négation sur une expression décompilée.          * +*                                                                             * +*  Retour      : true si la négation a été gérée, false sinon.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_cond_expression_negate(GCondExpression *cond) +{ +    size_t i;                               /* Boucle de parcours          */ + +    if (cond->operator == COT_NONE) +        g_dec_expression_negate(cond->exp); + +    else +    { +        cond->operator = (cond->operator == COT_AND ? COT_OR : COT_AND); + +        for (i = 0; i < cond->count; i++) +            g_dec_expression_negate(G_DEC_EXPRESSION(cond->conds[i])); + +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cond = instance à consulter.                                 * +*                                                                             * +*  Description : Fournit l'opération logique entre les comparaisons.          * +*                                                                             * +*  Retour      : Opération liant les différentes parties, ou COT_NONE.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +CondOperatorType g_cond_expression_get_operator(const GCondExpression *cond) +{ +    return cond->operator; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cond = instance à consulter.                                 * +*                                                                             * +*  Description : Fournit l'expression d'une condition.                        * +*                                                                             * +*  Retour      : Expression sur laquelle repose la condition.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDecExpression *g_cond_expression_get_expression(const GCondExpression *cond) +{ +    return cond->exp; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cond = instance à modifier.                                  * +*                exp  = expression sur laquelle repose la condition.          * +*                                                                             * +*  Description : Définit l'expression d'une condition.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_cond_expression_set_expression(GCondExpression *cond, GDecExpression *exp) +{ +    if (cond->exp != NULL) +        g_object_unref(G_OBJECT(cond->exp)); + +    cond->exp = exp; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : cond  = instance à compléter.                                * +*                extra = condition à rajouter.                                * +*                op    = lien avec le reste de la condition.                  * +*                                                                             * +*  Description : Etend l'expression d'une condition.                          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_cond_expression_add_condition(GCondExpression *cond, GCondExpression *extra, CondOperatorType op) +{ +    GCondExpression *existing;              /* Expr. première revalorisée  */ + +    if (cond->operator == COT_NONE) +    { +        existing = G_COND_EXPRESSION(g_cond_expression_new(cond->exp)); +        goto gceac_replace_existing; +    } +    else +    { +        if (cond->operator == op) +        { +            cond->conds = (GCondExpression **)calloc(++cond->count, sizeof(GCondExpression)); +            cond->conds[cond->count - 1] = extra; +        } +        else +        { +            existing = G_COND_EXPRESSION(g_cond_expression_new(NULL)); + +            existing->operator = cond->operator; +            existing->conds = cond->conds; +            existing->count = cond->count; + +            goto gceac_replace_existing; + +        } + +    } + + gceac_done: + +    return; + + gceac_replace_existing: + +    cond->operator = op; + +    cond->conds = (GCondExpression **)calloc(2, sizeof(GCondExpression)); +    cond->conds[0] = existing; +    cond->conds[1] = extra; + +    cond->count = 2; + +    goto gceac_done; + +} diff --git a/src/decomp/expr/cond.h b/src/decomp/expr/cond.h index b6fd073..a4d1ee7 100644 --- a/src/decomp/expr/cond.h +++ b/src/decomp/expr/cond.h @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * cond.h - prototypes pour la représentation des conditions   * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -29,7 +29,7 @@  #include "../expression.h" -#include "../instruction.h" +#include "../output.h" @@ -53,7 +53,19 @@ typedef struct _GCondExpressionClass GCondExpressionClass;  GType g_cond_expression_get_type(void);  /* Exprime une condition binaire quelconque. */ -GDecInstruction *g_cond_expression_new(GDecExpression *, CompSignType, GDecExpression *); +GDecExpression *g_cond_expression_new(GDecExpression *); + +/* Fournit l'opération logique entre les comparaisons. */ +CondOperatorType g_cond_expression_get_operator(const GCondExpression *); + +/* Fournit l'expression d'une condition. */ +GDecExpression *g_cond_expression_get_expression(const GCondExpression *); + +/* Définit l'expression d'une condition. */ +void g_cond_expression_set_expression(GCondExpression *, GDecExpression *); + +/* Etend l'expression d'une condition. */ +void g_cond_expression_add_condition(GCondExpression *, GCondExpression *, CondOperatorType); diff --git a/src/decomp/expression-int.h b/src/decomp/expression-int.h index dacd9b8..ba15ce3 100644 --- a/src/decomp/expression-int.h +++ b/src/decomp/expression-int.h @@ -30,11 +30,18 @@ +/* Réalise une négation sur une expression décompilée. */ +typedef bool (* dec_expr_negate_fc) (GDecExpression *); + +  /* Définition d'une expression décompilée (instance) */  struct _GDecExpression  {      GDecInstruction parent;                 /* A laisser en premier        */ +    dec_expr_negate_fc negate;              /* Négation de l'expression    */ +    dec_instr_print_fc original_print;      /* Eventuelle version négative */ +  }; diff --git a/src/decomp/expression.c b/src/decomp/expression.c index 82a2b4a..783f78f 100644 --- a/src/decomp/expression.c +++ b/src/decomp/expression.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * expression.c - gestion des expressions décompilées   * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -34,6 +34,9 @@ static void g_dec_expression_class_init(GDecExpressionClass *);  /* Initialise une instance d'expression décompilée. */  static void g_dec_expression_init(GDecExpression *); +/* Imprime pour l'écran la négation d'une expression décompilée. */ +static GBufferLine *g_dec_expression_neg_print(const GDecExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *); +  /* Indique le type défini pour une expression décompilée. */ @@ -74,3 +77,61 @@ static void g_dec_expression_init(GDecExpression *expr)  {  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr   = expression à transcrire en version humaine.         * +*                buffer = tampon où doit se réaliser l'insertion.             * +*                line   = ligne d'impression prête à emploi ou NULL.          * +*                output = langage de programmation de sortie.                 * +*                                                                             * +*  Description : Imprime pour l'écran la négation d'une expression décompilée.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBufferLine *g_dec_expression_neg_print(const GDecExpression *expr, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output) +{ +    GBufferLine *result;                    /* Ligne à retourner           */ + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "!", 1, RTT_KEY_WORD); + +    result = expr->original_print(G_DEC_INSTRUCTION(expr), buffer, line, output); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : expr = instance à traiter.                                   * +*                                                                             * +*  Description : Réalise une négation sur une expression décompilée.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_dec_expression_negate(GDecExpression *expr) +{ +    bool status;                            /* Réussite de l'opération ?   */ + +    if (expr->negate != NULL) +        status = expr->negate(expr); +    else +        status = false; + +    if (!status) +    { +        expr->original_print = G_DEC_INSTRUCTION(expr)->print; +        G_DEC_INSTRUCTION(expr)->print = (dec_instr_print_fc)g_dec_expression_neg_print; +    } + +} diff --git a/src/decomp/expression.h b/src/decomp/expression.h index 4a56c24..01eaa66 100644 --- a/src/decomp/expression.h +++ b/src/decomp/expression.h @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * expression.h - prototypes pour la gestion des expressions décompilées   * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -48,6 +48,9 @@ typedef struct _GDecExpressionClass GDecExpressionClass;  /* Indique le type défini pour une expression décompilée. */  GType g_dec_expression_get_type(void); +/* Réalise une négation sur une expression décompilée. */ +void g_dec_expression_negate(GDecExpression *); +  #endif  /* _DECOMP_EXPRESSION_H */ diff --git a/src/decomp/instr/ite.c b/src/decomp/instr/ite.c index 60627a6..5cdeb87 100644 --- a/src/decomp/instr/ite.c +++ b/src/decomp/instr/ite.c @@ -33,9 +33,7 @@ struct _GITEInstruction  {      GDecInstruction parent;                 /* A laisser en premier        */ -    bool inverse;                           /* Condition inversée          */ - -    GDecExpression *cond;                   /* Condition prise en compte   */ +    GCondExpression *cond;                  /* Condition prise en compte   */      GDecInstruction *true_branch;           /* Condition vérifiée          */      GDecInstruction *false_branch;          /* Condition non vérifiée      */ @@ -144,7 +142,7 @@ static void g_ite_instruction_init(GITEInstruction *instr)  *                                                                             *  ******************************************************************************/ -GDecInstruction *g_ite_instruction_new(GDecExpression *cond, vmpa_t if_true, vmpa_t if_false) +GDecInstruction *g_ite_instruction_new(GCondExpression *cond, vmpa_t if_true, vmpa_t if_false)  {      GITEInstruction *result;              /* Expression à retourner      */ @@ -245,9 +243,6 @@ static GBufferLine *g_ite_instruction_print(const GITEInstruction *instr, GCodeB      g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "if ", 3, RTT_KEY_WORD); -    if (instr->inverse) -        g_buffer_line_insert_text(line /* FIXME */, BLC_ASSEMBLY_HEAD, "!", 1, RTT_KEY_WORD); -      result = g_dec_instruction_print(G_DEC_INSTRUCTION(instr->cond),                                       buffer, line, output); @@ -266,6 +261,25 @@ static GBufferLine *g_ite_instruction_print(const GITEInstruction *instr, GCodeB  /******************************************************************************  *                                                                             * +*  Paramètres  : instr = instruction fixant le choix de l'aiguillage.         * +*                                                                             * +*  Description : Fournit la condition régissant la suite de l'exécution.      * +*                                                                             * +*  Retour      : Condition mise en place.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GCondExpression *g_ite_instruction_get_condition(const GITEInstruction *instr) +{ +    return instr->cond; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : instr        = expression fixant le choix de l'aiguillage.   *  *                true_branch  = instructions si la condition est vérifiée.    *  *                false_branch = instructions si la cond. n'est pas vérifiée.  * @@ -280,10 +294,12 @@ static GBufferLine *g_ite_instruction_print(const GITEInstruction *instr, GCodeB  void g_ite_instruction_set_branches(GITEInstruction *instr, GDecInstruction *true_branch, GDecInstruction *false_branch)  { +    if (instr->true_branch != NULL) g_object_unref(G_OBJECT(instr->true_branch)); +    if (instr->false_branch != NULL) g_object_unref(G_OBJECT(instr->false_branch));      if (true_branch == NULL)      { -        instr->inverse = true; +        g_dec_expression_negate(G_DEC_EXPRESSION(instr->cond));          instr->true_branch = false_branch;          instr->false_branch = true_branch; @@ -296,3 +312,28 @@ void g_ite_instruction_set_branches(GITEInstruction *instr, GDecInstruction *tru      }  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr        = instruction fixant le choix de l'aiguillage.  * +*                true_branch  = instrs. si la condition est vérifiée. [OUT]   * +*                false_branch = instrs. si la cond. n'est pas vérifiée. [OUT] * +*                                                                             * +*  Description : Fournit le corps des différentes branches possibles.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_ite_instruction_get_branches(const GITEInstruction *instr, GDecInstruction **true_branch, GDecInstruction **false_branch) +{ +    if (true_branch != NULL) +        *true_branch = instr->true_branch; + +    if (false_branch != NULL) +        *false_branch = instr->false_branch; + +} diff --git a/src/decomp/instr/ite.h b/src/decomp/instr/ite.h index 7137452..91c18ae 100644 --- a/src/decomp/instr/ite.h +++ b/src/decomp/instr/ite.h @@ -30,6 +30,7 @@  #include "../expression.h"  #include "../instruction.h" +#include "../expr/cond.h" @@ -53,11 +54,17 @@ typedef struct _GITEInstructionClass GITEInstructionClass;  GType g_ite_instruction_get_type(void);  /* Exprime un aiguillage du flux en fonction d'une condition. */ -GDecInstruction *g_ite_instruction_new(GDecExpression *, vmpa_t, vmpa_t); +GDecInstruction *g_ite_instruction_new(GCondExpression *, vmpa_t, vmpa_t); + +/* Fournit la condition régissant la suite de l'exécution. */ +GCondExpression *g_ite_instruction_get_condition(const GITEInstruction *);  /* Détermine le corps des différentes branches possibles. */  void g_ite_instruction_set_branches(GITEInstruction *, GDecInstruction *, GDecInstruction *); +/* Fournit le corps des différentes branches possibles. */ +void g_ite_instruction_get_branches(const GITEInstruction *, GDecInstruction **, GDecInstruction **); +  #endif  /* _DECOMP_INSTR_ITE_H */ diff --git a/src/decomp/lang/java.c b/src/decomp/lang/java.c index f4466a5..65383b0 100644 --- a/src/decomp/lang/java.c +++ b/src/decomp/lang/java.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * java.c - sorties en langage Java   * - * Copyright (C) 2010-2012 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -66,6 +66,9 @@ static GBufferLine *g_java_output_write_comments(GJavaOutput *, GCodeBuffer *, c  /* Imprime dans un tampon donné une méthode de comparaison. */  static void g_java_output_write_comp_sign(GJavaOutput *, GBufferLine *, CompSignType); +/* Imprime dans un tampon donné un opérateur logique. */ +static void g_java_output_write_cond_operator(GLangOutput *, GBufferLine *, CondOperatorType); +  /* Débute la définition d'une classe. */  static GBufferLine *g_java_output_start_class(GJavaOutput *, GCodeBuffer *, const GDataType *); @@ -90,6 +93,9 @@ static GBufferLine *g_java_output_start_code_block(GJavaOutput *, GCodeBuffer *,  /* Termine la définition d'un bloc de code. */  static GBufferLine *g_java_output_end_code_block(GJavaOutput *, GCodeBuffer *, GBufferLine *, size_t); +/* Emballe une expression conditionelle. */ +static GBufferLine *g_java_output_encapsulate_condition(GLangOutput *, GCodeBuffer *, GBufferLine *, bool); +  /* Indique le type défini pour une sortie en langage Java. */ @@ -139,6 +145,7 @@ static void g_java_output_init(GJavaOutput *output)      lang->write_comments = (write_comments_fc)g_java_output_write_comments;      lang->comp_sign = (write_comp_sign_fc)g_java_output_write_comp_sign; +    lang->cond_op = (write_cond_op_fc)g_java_output_write_cond_operator;      lang->start_class = (rlgbuftp_fc)g_java_output_start_class;      lang->end_class = (lgbuf_fc)g_java_output_end_class; @@ -150,6 +157,7 @@ static void g_java_output_init(GJavaOutput *output)      lang->start_code_block = (rlgbuflnsz_fc)g_java_output_start_code_block;      lang->end_code_block = (rlgbuflnsz_fc)g_java_output_end_code_block; +    lang->encaps_cond = (lo_buf_ln_bool_fc)g_java_output_encapsulate_condition;  } @@ -342,6 +350,42 @@ static void g_java_output_write_comp_sign(GJavaOutput *output, GBufferLine *line  /******************************************************************************  *                                                                             *  *  Paramètres  : output = encadrant de l'impression en langage de prog.       * +*                line   = tampon de sortie à disposition.                     * +*                op     = opérateur logique à imprimer.                       * +*                                                                             * +*  Description : Imprime dans un tampon donné un opérateur logique.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_java_output_write_cond_operator(GLangOutput *output, GBufferLine *line, CondOperatorType op) +{ +    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + +    switch (op) +    { +        case COT_AND: +            g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "&&", 2, RTT_SIGNS); +            break; +        case COT_OR: +            g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "||", 2, RTT_SIGNS); +            break; +        default: +            g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "??", 2, RTT_SIGNS); +            break; +    } + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, " ", 1, RTT_RAW); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : output = encadrant de l'impression en langage de prog.       *  *                buffer = tampon de sortie à disposition.                     *  *                type   = désignation de la classe à définir.                 *  *                                                                             * @@ -575,3 +619,34 @@ static GBufferLine *g_java_output_end_code_block(GJavaOutput *output, GCodeBuffe      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : output  = encadrant de l'impression en langage de prog.      * +*                buffer  = tampon de sortie à disposition.                    * +*                line    = ligne contenant le prototype de la routine traitée.* +*                opening = précise si la condition débute ou se termine.      * +*                                                                             * +*  Description : Emballe une expression conditionelle.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBufferLine *g_java_output_encapsulate_condition(GLangOutput *output, GCodeBuffer *buffer, GBufferLine *line, bool opening) +{ +    GBufferLine *result;                    /* Nouvelle ligne à utiliser   */ + +    result = line; + +    if (opening) +        g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, "(", 1, RTT_HOOK); +    else +        g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, ")", 1, RTT_HOOK); + +    return result; + +} diff --git a/src/decomp/output-int.h b/src/decomp/output-int.h index 8ee7dd4..95b891b 100644 --- a/src/decomp/output-int.h +++ b/src/decomp/output-int.h @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * output-int.h - définitions internes pour les sorties en langage de programmation   * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -38,6 +38,9 @@ typedef GBufferLine * (* write_comments_fc) (GLangOutput *, GCodeBuffer *, const  /* Imprime dans un tampon donné une méthode de comparaison. */  typedef void (* write_comp_sign_fc) (GLangOutput *, GBufferLine *, CompSignType); +/* Imprime dans un tampon donné un opérateur logique. */ +typedef void (* write_cond_op_fc) (GLangOutput *, GBufferLine *, CondOperatorType); +  /* Débute la documentation d'une routine. */  typedef GBufferLine * (* start_rtn_info_fc) (const GLangOutput *, GCodeBuffer *); @@ -57,6 +60,11 @@ typedef GBufferLine * (* rlgbufln_fc) (GLangOutput *, GCodeBuffer *, GBufferLine  typedef GBufferLine * (* rlgbuflnsz_fc) (GLangOutput *, GCodeBuffer *, GBufferLine *, size_t); +/* Xxx. */ +typedef GBufferLine * (* lo_buf_ln_bool_fc) (GLangOutput *, GCodeBuffer *, GBufferLine *, bool); + + +  /* Sortie selon un langage de programmation (instance) */  struct _GLangOutput  { @@ -68,6 +76,7 @@ struct _GLangOutput      write_comments_fc write_comments;       /* Commentaires sur une ligne  */      write_comp_sign_fc comp_sign;           /* Méthde de comparaison       */ +    write_cond_op_fc cond_op;               /* Opérateur logique           */      rlgbuftp_fc start_class;                /* Début de définition         */      lgbuf_fc end_class;                     /* Fin de définition de classe */ @@ -80,6 +89,8 @@ struct _GLangOutput      lgbuf_fc end_routine_body;              /* Fin de définition de corps  */      rlgbuflnsz_fc start_code_block;         /* Début de définition         */      rlgbuflnsz_fc end_code_block;           /* Fin de définition de corps  */ +    lo_buf_ln_bool_fc encaps_cond;          /* Emballe une condition       */ +  }; diff --git a/src/decomp/output.c b/src/decomp/output.c index 5689319..c358653 100644 --- a/src/decomp/output.c +++ b/src/decomp/output.c @@ -2,7 +2,7 @@  /* OpenIDA - Outil d'analyse de fichiers binaires   * output.c - sorties en langage de programmation   * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard   *   *  This file is part of OpenIDA.   * @@ -206,6 +206,28 @@ void g_lang_output_write_comp_sign(GLangOutput *output, GBufferLine *line, CompS  /******************************************************************************  *                                                                             *  *  Paramètres  : output = encadrant de l'impression en langage de prog.       * +*                line   = tampon de sortie à disposition.                     * +*                op     = opérateur logique à imprimer.                       * +*                                                                             * +*  Description : Imprime dans un tampon donné un opérateur logique.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_lang_output_write_cond_operator(GLangOutput *output, GBufferLine *line, CondOperatorType op) +{ +    if (output->cond_op != NULL) +        output->cond_op(output, line, op); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : output = encadrant de l'impression en langage de prog.       *  *                buffer = tampon de sortie à disposition.                     *  *                type   = désignation de la classe à définir.                 *  *                                                                             * @@ -430,3 +452,32 @@ GBufferLine *g_lang_output_end_code_block(GLangOutput *output, GCodeBuffer *buff      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : output  = encadrant de l'impression en langage de prog.      * +*                buffer  = tampon de sortie à disposition.                    * +*                line    = ligne contenant le prototype de la routine traitée.* +*                opening = précise si la condition débute ou se termine.      * +*                                                                             * +*  Description : Emballe une expression conditionelle.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBufferLine *g_lang_output_encapsulate_condition(GLangOutput *output, GCodeBuffer *buffer, GBufferLine *line, bool opening) +{ +    GBufferLine *result;                    /* Nouvelle ligne à utiliser   */ + +    if (output->encaps_cond != NULL) +        result = output->encaps_cond(output, buffer, line, opening); +    else +        result = NULL; + +    return result; + +} diff --git a/src/decomp/output.h b/src/decomp/output.h index dc81a98..63f586a 100644 --- a/src/decomp/output.h +++ b/src/decomp/output.h @@ -63,20 +63,35 @@ GBufferLine *g_lang_output_write_comments(GLangOutput *, GCodeBuffer *, const ch  /* Liste des signes binaires de comparaison */  typedef enum _CompSignType  { -    CST_EQ,                                 /* == */ -    CST_NE,                                 /* != */ -    CST_LT,                                 /* < */ -    CST_GE,                                 /* >= */ -    CST_GT,                                 /* > */ -    CST_LE,                                 /* <= */ +    CST_EQ,                                 /* ==                          */ +    CST_NE,                                 /* !=                          */ +    CST_LT,                                 /* <                           */ +    CST_GE,                                 /* >=                          */ +    CST_GT,                                 /* >                           */ +    CST_LE,                                 /* <=                          */      CST_COUNT  } CompSignType; +/* Liste des signes binaires de comparaison */ +typedef enum _CondOperatorType +{ +    COT_NONE,                               /* pas de condition            */ +    COT_AND,                                /* &&                          */ +    COT_OR,                                 /* ||                          */ + +    COT_COUNT + +} CondOperatorType; + +  /* Imprime dans un tampon donné une méthode de comparaison. */  void g_lang_output_write_comp_sign(GLangOutput *, GBufferLine *, CompSignType); +/* Imprime dans un tampon donné un opérateur logique. */ +void g_lang_output_write_cond_operator(GLangOutput *, GBufferLine *, CondOperatorType); +  /* Débute la définition d'une classe. */  GBufferLine *g_lang_output_start_class(GLangOutput *, GCodeBuffer *, const void *); @@ -105,6 +120,9 @@ GBufferLine *g_lang_output_start_code_block(GLangOutput *, GCodeBuffer *, GBuffe  /* Termine la définition d'un bloc de code. */  GBufferLine *g_lang_output_end_code_block(GLangOutput *, GCodeBuffer *, GBufferLine *, size_t); +/* Emballe une expression conditionelle. */ +GBufferLine *g_lang_output_encapsulate_condition(GLangOutput *, GCodeBuffer *, GBufferLine *, bool); +  typedef unsigned int lang_t; | 
