diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2009-09-30 00:00:43 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2009-09-30 00:00:43 (GMT) | 
| commit | 3c6968d4d5a8918c456cdea28a7c6195368d996e (patch) | |
| tree | e6909254a8033cdabd116f287db2893e938a636d | |
| parent | 1beaa1af679d49d99696ec907662b764f7ba1867 (diff) | |
Parsed and replaced ModRM operands.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@121 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
| -rw-r--r-- | ChangeLog | 47 | ||||
| -rw-r--r-- | plugins/stackvars/operand.c | 62 | ||||
| -rw-r--r-- | plugins/stackvars/operand.h | 5 | ||||
| -rw-r--r-- | plugins/stackvars/stackvars.c | 72 | ||||
| -rwxr-xr-x | src/analysis/Makefile.am | 2 | ||||
| -rw-r--r-- | src/analysis/binary.c | 2 | ||||
| -rw-r--r-- | src/analysis/exporter.c | 7 | ||||
| -rw-r--r-- | src/analysis/exporter.h | 2 | ||||
| -rw-r--r-- | src/analysis/routine.c (renamed from src/analysis/prototype.c) | 123 | ||||
| -rw-r--r-- | src/analysis/routine.h (renamed from src/analysis/prototype.h) | 14 | ||||
| -rw-r--r-- | src/analysis/variable.c | 201 | ||||
| -rw-r--r-- | src/analysis/variable.h | 44 | ||||
| -rw-r--r-- | src/arch/immediate.c | 68 | ||||
| -rw-r--r-- | src/arch/immediate.h | 3 | ||||
| -rw-r--r-- | src/format/exe_format.h | 2 | ||||
| -rw-r--r-- | src/format/format.h | 1 | ||||
| -rw-r--r-- | src/format/mangling/demangler-int.h | 1 | ||||
| -rw-r--r-- | src/format/mangling/demangler.h | 2 | ||||
| -rw-r--r-- | src/format/symbol.c | 3 | ||||
| -rw-r--r-- | src/format/symbol.h | 1 | ||||
| -rw-r--r-- | src/plugins/pglist.c | 2 | ||||
| -rw-r--r-- | src/plugins/plugin.c | 2 | 
22 files changed, 592 insertions, 74 deletions
| @@ -1,3 +1,50 @@ +09-09-30  Cyrille Bagard <nocbos@gmail.com> + +	* plugins/stackvars/operand.c: +	* plugins/stackvars/operand.h: +	Display default name of variables. + +	* plugins/stackvars/stackvars.c: +	Parse and replace matching operands. + +	* src/analysis/binary.c: +	Update included headers (prototype -> routine). + +	* src/analysis/exporter.c: +	* src/analysis/exporter.h: +	Add a rendering type for variable names. + +	* src/analysis/Makefile.am: +	Remove prototype.[ch] and add routine.[ch] to libanalysis_la_SOURCES. + +	* src/analysis/prototype.c: +	* src/analysis/prototype.h: +	Renamed entries: see routine.[ch]. + +	* src/analysis/routine.c: +	* src/analysis/routine.h: +	New entries: insert variables from the stack. + +	* src/analysis/variable.c: +	* src/analysis/variable.h: +	Create a new GLib oriented basic variable. + +	* src/arch/immediate.c: +	* src/arch/immediate.h: +	Export values to size_t. + +	* src/format/exe_format.h: +	* src/format/format.h: +	* src/format/mangling/demangler.h: +	* src/format/mangling/demangler-int.h: +	* src/format/symbol.c: +	* src/format/symbol.h: +	Update included headers (prototype -> routine). + +	* src/plugins/pglist.c: +	* src/plugins/plugin.c: +	Enable plugins again. +  09-09-27  Cyrille Bagard <nocbos@gmail.com>  	* src/arch/x86/operand.c: diff --git a/plugins/stackvars/operand.c b/plugins/stackvars/operand.c index 6eff546..387f766 100644 --- a/plugins/stackvars/operand.c +++ b/plugins/stackvars/operand.c @@ -24,8 +24,8 @@  #include "operand.h" -#include <malloc.h>  #include <stdio.h> +#include <string.h>  #include <arch/operand-int.h> @@ -37,7 +37,8 @@ struct _GStackVarOperand  {      GArchOperand parent;                    /* Instance parente            */ -    const GArchOperand *child;              /* Opérand d'origine substitué */ +    const GBinRoutine *routine;             /* Routine d'appartenance      */ +    const GX86ModRMOperand *child;          /* Opérand d'origine substitué */  }; @@ -56,15 +57,15 @@ static void g_stack_var_operand_class_init(GStackVarOperandClass *);  /* Initialise l'instande d'un opérandes de substitution. */  static void g_stack_var_operand_init(GStackVarOperand *); -/* Traduit un opérande en version humainement lisible. */ -static char *g_stack_var_operand_get_text(const GStackVarOperand *, const GExeFormat *, AsmSyntax); +/* Ajoute à un texte GTK le contenu d'un opérande. */ +static void g_stack_var_operand_add_to_gtk_buffer(const GStackVarOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); +  /* Indique le type défini pour un opérande de substitution pour variable de pile. */  G_DEFINE_TYPE(GStackVarOperand, g_stack_var_operand, G_TYPE_ARCH_OPERAND); -  /******************************************************************************  *                                                                             *  *  Paramètres  : klass = classe à initialiser.                                * @@ -97,18 +98,19 @@ static void g_stack_var_operand_class_init(GStackVarOperandClass *klass)  static void g_stack_var_operand_init(GStackVarOperand *operand)  { -    GArchOperand *parent;                   /* Instance parente            */ +    GContentExporter *parent;               /* Instance parente            */ -    parent = G_ARCH_OPERAND(operand); +    parent = G_CONTENT_EXPORTER(operand); -    parent->get_text = (get_operand_text_fc)g_stack_var_operand_get_text; +    parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_stack_var_operand_add_to_gtk_buffer;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : child = opérande d'origine à substituer.                     * +*  Paramètres  : routine = routine d'appatenance de l'opérande.               * +*                child   = opérande d'origine à substituer.                   *  *                                                                             *  *  Description : Crée un opérande de substitution pour variable de pile.      *  *                                                                             * @@ -118,41 +120,57 @@ static void g_stack_var_operand_init(GStackVarOperand *operand)  *                                                                             *  ******************************************************************************/ -GArchOperand *g_stack_var_operand_new(const GArchOperand *child) +GArchOperand *g_stack_var_operand_new(const GBinRoutine *routine, const GX86ModRMOperand *child)  { -    GStackVarOperand *result;                    /* Opérande à retourner        */ +    GStackVarOperand *result;               /* Opérande à retourner        */      result = g_object_new(G_TYPE_STACK_VAR_OPERAND, NULL); +    result->routine = routine;      result->child = child; -    return result; +    return G_ARCH_OPERAND(result);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                format  = format du binaire manipulé.                        * -*                syntax  = type de représentation demandée.                   * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static char *g_stack_var_operand_get_text(const GStackVarOperand *operand, const GExeFormat *format, AsmSyntax syntax) +static void g_stack_var_operand_add_to_gtk_buffer(const GStackVarOperand *operand, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter)  { -    char *result;                           /* Chaîne à retourner          */ +    const GImmOperand *displacement;        /* Décallage supplémentaire    */ +    size_t value;                           /* Position dans la pile       */ +    bool negative;                          /* Direction dans la pile      */ +    size_t index;                           /* Indice de la variable       */ +    char name[32];                          /* Nom de la variable          */ + +    displacement = g_x86_mod_rm_operand_get_displacement(operand->child); +    g_imm_operand_to_size_t(displacement, &value, &negative); + +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                           "[", 1, RTT_HOOK); -    result = (char *)calloc(19, sizeof(char)); +    index = g_binary_routine_get_var_index_from_offset(operand->routine, value, negative); +    snprintf(name, 32, "%s%u", negative ? "local" : "arg", index); -    snprintf(result, 19, "[<b>varX</b>]"); +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                           name, strlen(name), RTT_VAR_NAME); -    return result; +    g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(operand), buffer, iter, +                                           "]", 1, RTT_HOOK);  } diff --git a/plugins/stackvars/operand.h b/plugins/stackvars/operand.h index d0f8120..1b58395 100644 --- a/plugins/stackvars/operand.h +++ b/plugins/stackvars/operand.h @@ -29,7 +29,8 @@  #include <stdbool.h> -#include <arch/operand.h> +#include <analysis/routine.h> +#include <arch/x86/operand.h> @@ -50,7 +51,7 @@ typedef struct _GStackVarOperandClass GStackVarOperandClass;  GType g_stack_var_operand_get_type(void);  /* Crée un opérande de substitution pour variable de pile. */ -GArchOperand *g_stack_var_operand_new(const GArchOperand *); +GArchOperand *g_stack_var_operand_new(const GBinRoutine *, const GX86ModRMOperand *); diff --git a/plugins/stackvars/stackvars.c b/plugins/stackvars/stackvars.c index 32535e9..35f8016 100644 --- a/plugins/stackvars/stackvars.c +++ b/plugins/stackvars/stackvars.c @@ -25,7 +25,7 @@  #include <analysis/line_code.h> -#include <analysis/prototype.h> +#include <analysis/routine.h>  #include <arch/x86/operand.h>  #include <format/executable.h>  #include <format/format.h> @@ -39,10 +39,10 @@  static bool replace_stack_vars_in_routine(GBinRoutine *, GRenderingLine *);  /* Effectue d'éventuels remplacements dans une instruction. */ -static bool replace_stack_vars_in_instruction(GArchInstruction *); +static bool replace_stack_vars_in_instruction(GArchInstruction *, GBinRoutine *, bool);  /* Effectue d'éventuels remplacements dans un opérande. */ -static GArchOperand *replace_stack_vars_in_operand(const GArchOperand *); +static bool replace_stack_var_in_operand(const GArchOperand *, GBinRoutine *, bool, GArchOperand **); @@ -108,8 +108,6 @@ G_MODULE_EXPORT bool execute_action_on_binary(GOpenidaBinary *binary, PluginActi      result = false; -    printf(" ------------- exec stackvars !!!\n"); -      lines = g_openida_binary_get_lines(binary);      format = g_openida_binary_get_format(binary); @@ -149,11 +147,20 @@ static bool replace_stack_vars_in_routine(GBinRoutine *routine, GRenderingLine *      start = g_binary_routine_get_address(routine);      end = start + g_binary_routine_get_size(routine); -     +    for (iter = g_rendering_line_find_by_address(lines, NULL, start); +         iter != NULL && get_rendering_line_address(iter) < end; +         iter = g_rendering_line_get_next_iter(lines, iter, NULL)) +    { +        if (!G_IS_CODE_LINE(iter)) continue; + +        instr = g_code_line_get_instruction(G_CODE_LINE(iter)); -    printf(" +++ processing '%s'\n", g_binary_routine_get_name(routine)); +        result |= replace_stack_vars_in_instruction(instr, routine, true); +    } +    if (!result) return false; +    else result = false;      for (iter = g_rendering_line_find_by_address(lines, NULL, start);           iter != NULL && get_rendering_line_address(iter) < end; @@ -163,7 +170,7 @@ static bool replace_stack_vars_in_routine(GBinRoutine *routine, GRenderingLine *          instr = g_code_line_get_instruction(G_CODE_LINE(iter)); -        result |= replace_stack_vars_in_instruction(instr); +        result |= replace_stack_vars_in_instruction(instr, routine, false);      } @@ -174,7 +181,9 @@ static bool replace_stack_vars_in_routine(GBinRoutine *routine, GRenderingLine *  /******************************************************************************  *                                                                             * -*  Paramètres  : instr = instruction dont le contenu peut être modifié.       * +*  Paramètres  : instr   = instruction dont le contenu peut être modifié.     * +*                routine = routine contenant l'instruction analysée.          * +*                dryrun  = mode enregistrement ou remplacement ?              *  *                                                                             *  *  Description : Effectue d'éventuels remplacements dans une instruction.     *  *                                                                             * @@ -184,24 +193,25 @@ static bool replace_stack_vars_in_routine(GBinRoutine *routine, GRenderingLine *  *                                                                             *  ******************************************************************************/ -static bool replace_stack_vars_in_instruction(GArchInstruction *instr) +static bool replace_stack_vars_in_instruction(GArchInstruction *instr, GBinRoutine *routine, bool dryrun)  {      bool result;                            /* Bilan à renvoyer            */ +    GArchOperand *new;                      /* Opérande d'encapsulation    */      size_t opcount;                         /* Nombre d'opérandes          */      size_t i;                               /* Boucle de parcours          */      const GArchOperand *operand;            /* Opérande de l'instruction   */ -    GArchOperand *new;                      /* Opérande d'encapsulation    */      result = false; +    new = NULL;     /* Pour GCC */      opcount = g_arch_instruction_count_operands(instr);      for (i = 0; i < opcount; i++)      {          operand = g_arch_instruction_get_operand(instr, i); -        new = replace_stack_vars_in_operand(operand); +        result = replace_stack_var_in_operand(operand, routine, dryrun, &new); -        if (new != NULL) +        if (!dryrun && result)          {              g_arch_instruction_replace_operand(instr, new, operand); @@ -219,6 +229,9 @@ static bool replace_stack_vars_in_instruction(GArchInstruction *instr)  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande dont le contenu est à analyser.           * +*                routine = routine contenant l'opérande analysé.              * +*                dryrun  = mode enregistrement ou remplacement ?              * +*                new     = éventuelle nouvelle encapsulation créée.           *  *                                                                             *  *  Description : Effectue d'éventuels remplacements dans un opérande.         *  *                                                                             * @@ -228,32 +241,37 @@ static bool replace_stack_vars_in_instruction(GArchInstruction *instr)  *                                                                             *  ******************************************************************************/ -static GArchOperand *replace_stack_vars_in_operand(const GArchOperand *operand) +static bool replace_stack_var_in_operand(const GArchOperand *operand, GBinRoutine *routine, bool dryrun, GArchOperand **new)  { -    GArchOperand *result;                   /* Encapsulation à retourner   */ +    bool result;                            /* Bilan à retourner           */ +    GX86ModRMOperand *modrm;                /* Autre version de l'opérande */      uint8_t scale;                          /* Puissance de deux           */ -    GX86Register *index;                    /* Registre servant d'indice   */ -    GX86Register *base;                     /* Registre de base            */ -    GImmOperand *displacement;              /* Décallage supplémentaire    */ +    const GX86Register *index;              /* Registre servant d'indice   */ +    const GX86Register *base;               /* Registre de base            */ +    const GImmOperand *displacement;        /* Décallage supplémentaire    */ +    size_t value;                           /* Position dans la pile       */ +    bool negative;                          /* Direction dans la pile      */ -    result = NULL; +    result = false;      if (G_IS_X86_MOD_RM_OPERAND(operand))      { -        g_x86_mod_rm_operand_get_scale_and_index(G_X86_MOD_RM_OPERAND(operand), &scale, &index); -        base = g_x86_mod_rm_operand_get_base(G_X86_MOD_RM_OPERAND(operand)); -        displacement = g_x86_mod_rm_operand_get_displacement(G_X86_MOD_RM_OPERAND(operand)); +        modrm = G_X86_MOD_RM_OPERAND(operand); -        if (scale == 0 && g_x86_register_is_base_pointer(index) && base == NULL) +        g_x86_mod_rm_operand_get_scale_and_index(modrm, &scale, &index); +        base = g_x86_mod_rm_operand_get_base(modrm); +        displacement = g_x86_mod_rm_operand_get_displacement(modrm); + +        if (scale == 0 && g_x86_register_is_base_pointer(index) && base == NULL +            && g_imm_operand_to_size_t(displacement, &value, &negative))          { +            if (dryrun) g_binary_routine_register_if_needed(routine, value, negative); +            else *new = g_stack_var_operand_new(routine, modrm); -            printf(" [+] found one ebp !!\n"); -            result = g_stack_var_operand_new(operand); +            result = true;          } - -      }      return result; diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 7dca420..d7f0f0e 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -10,8 +10,8 @@ libanalysis_la_SOURCES =				\  	line_code.h line_code.c				\  	line_comment.h line_comment.c		\  	line_prologue.h line_prologue.c		\ -	prototype.h prototype.c				\  	roptions.h roptions.c				\ +	routine.h routine.c					\  	variable.h variable.c  libanalysis_la_LDFLAGS =  diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 4fe8f06..97b916e 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -38,7 +38,7 @@  #include "line_code.h"          /* TODO : supprimer ? */  #include "line_comment.h"       /* TODO : supprimer ? */  #include "line_prologue.h" -#include "prototype.h" +#include "routine.h"  #include "../common/extstr.h"  #include "../glibext/delayed-int.h"  #include "../format/format.h" diff --git a/src/analysis/exporter.c b/src/analysis/exporter.c index 8a41abf..54673d3 100644 --- a/src/analysis/exporter.c +++ b/src/analysis/exporter.c @@ -123,6 +123,13 @@ static void g_content_exporter_class_init(GContentExporterClass *klass)      klass->tags[RTT_STRING] = tag;      gtk_text_tag_table_add(table, tag); +    tag = gtk_text_tag_new(NULL); + +    g_object_set(G_OBJECT(tag), "foreground", "black", NULL); + +    klass->tags[RTT_VAR_NAME] = tag; +    gtk_text_tag_table_add(table, tag); +  } diff --git a/src/analysis/exporter.h b/src/analysis/exporter.h index 9e8d54a..60c37b1 100644 --- a/src/analysis/exporter.h +++ b/src/analysis/exporter.h @@ -51,6 +51,8 @@ typedef enum _RenderingTagType      RTT_SEGMENT,                            /* Indication de segment       */      RTT_STRING,                             /* Chaîne de caractères avec " */ +    RTT_VAR_NAME,                           /* Nom de variable             */ +      RTT_COUNT  } RenderingTagType; diff --git a/src/analysis/prototype.c b/src/analysis/routine.c index 72ee809..4bbd712 100644 --- a/src/analysis/prototype.c +++ b/src/analysis/routine.c @@ -1,6 +1,6 @@  /* OpenIDA - Outil d'analyse de fichiers binaires - * prototype.c - manipulation des prototypes de fonctions et de variables + * routine.c - manipulation des prototypes de fonctions et de variables   *   * Copyright (C) 2008 Cyrille Bagard   * @@ -21,11 +21,12 @@   */ -#include "prototype.h" +#include "routine.h"  #include <malloc.h>  #include <string.h> +#include <stdlib.h>  #include "../common/extstr.h" @@ -47,8 +48,14 @@ struct _GBinRoutine      char *name;                             /* Désignation humaine         */      variable **args_types;                  /* Types d'arguments           */ +    size_t old_args_count;                      /* Nombre d'arguments          */ + +    GUnknownVariable **args;                /* Arguments de la routines    */      size_t args_count;                      /* Nombre d'arguments          */ +    GUnknownVariable **locals;              /* Variables locales du code   */ +    size_t locals_count;                    /* Nombre de variables locales */ +  }; @@ -153,7 +160,7 @@ void g_binary_routine_finalize(GBinRoutine *routine)      if (routine->name != NULL)          free(routine->name); -    for (i = 0; i < routine->args_count; i++) +    for (i = 0; i < routine->old_args_count; i++)          delete_var(routine->args_types[i]);      free(routine); @@ -392,12 +399,114 @@ void g_binary_routine_set_return_type(GBinRoutine *routine, variable *var)  void g_binary_routine_add_arg(GBinRoutine *routine, variable *var)  { -    routine->args_count++; +    routine->old_args_count++;      routine->args_types = (variable **)realloc(routine->args_types, -                                               routine->args_count * sizeof(variable *)); +                                               routine->old_args_count * sizeof(variable *)); + +    routine->args_types[routine->old_args_count - 1] = var; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine à mettre à jour.                           * +*                offset  = position abstraite à retrouver.                    * +*                local   = indique le type de variable à manipuler.           * +*                                                                             * +*  Description : S'assure qu'une variable est bien associée à une routine.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_routine_register_if_needed(GBinRoutine *routine, size_t offset, bool local) +{ +    GUnknownVariable ***list;               /* Liste à manipuler           */ +    size_t *count;                          /* Taille de la liste          */ +    bool found;                             /* Indication de présence      */ +    size_t i;                               /* Boucle de parcours          */     +    GUnknownVariable *new;                  /* Nouvelle variable à intégrer*/ + +    if (local) +    { +        list = &routine->locals; +        count = &routine->locals_count; +    } +    else +    { +        list = &routine->args; +        count = &routine->args_count; +    } + +    found = false; + +    for (i = 0; i < *count && !found; i++) +        found = g_unknown_variable_contains_offset((*list)[i], offset); + +    if (!found) +    { +        /* Construction */ + +        new = g_unknown_variable_new(); + +        g_unknown_variable_set_offset(new, offset); -    routine->args_types[routine->args_count - 1] = var; +        /* Ajout */ + +        (*list)= (variable **)realloc(*list, ++(*count) * sizeof(GUnknownVariable *)); +        (*list)[*count - 1] = new; + +        qsort(*list, *count, sizeof(GUnknownVariable *), g_unknown_variable_compare); + + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine à mettre à jour.                           * +*                offset  = position abstraite à retrouver.                    * +*                local   = indique le type de variable à manipuler.           * +*                                                                             * +*  Description : Donne l'indice d'une variable dans la liste d'une routine.   * +*                                                                             * +*  Retour      : Indice de la variable dans la liste adaptée.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +size_t g_binary_routine_get_var_index_from_offset(const GBinRoutine *routine, size_t offset, bool local) +{ +    size_t result;                          /* Indice à renvoyer           */ +    GUnknownVariable ***list;               /* Liste à manipuler           */ +    size_t *count;                          /* Taille de la liste          */ +    size_t i;                               /* Boucle de parcours          */     + +    result = SIZE_MAX; + +    if (local) +    { +        list = &routine->locals; +        count = &routine->locals_count; +    } +    else +    { +        list = &routine->args; +        count = &routine->args_count; +    } + +    for (i = 0; i < *count && result == SIZE_MAX; i++) +        if (g_unknown_variable_contains_offset((*list)[i], offset)) +            result = i; + +    return result;  } @@ -454,7 +563,7 @@ char *g_binary_routine_to_string(const GBinRoutine *routine)      result = stradd(result, "("); -    for (i = 0; i < routine->args_count; i++) +    for (i = 0; i < routine->old_args_count; i++)      {          if (i > 0) result = stradd(result, ", "); diff --git a/src/analysis/prototype.h b/src/analysis/routine.h index 2a9439e..4e47b5e 100644 --- a/src/analysis/prototype.h +++ b/src/analysis/routine.h @@ -1,6 +1,6 @@  /* OpenIDA - Outil d'analyse de fichiers binaires - * prototype.h - prototypes pour la manipulation des prototypes de fonctions et de variables + * routine.h - prototypes pour la manipulation des prototypes de fonctions et de variables   *   * Copyright (C) 2008 Cyrille Bagard   * @@ -21,8 +21,8 @@   */ -#ifndef _ANALYSIS_PROTOTYPE_H -#define _ANALYSIS_PROTOTYPE_H +#ifndef _ANALYSIS_ROUTINE_H +#define _ANALYSIS_ROUTINE_H  #include <glib-object.h> @@ -97,9 +97,15 @@ void g_binary_routine_set_return_type(GBinRoutine *, variable *);  /* Ajoute un argument à une routine. */  void g_binary_routine_add_arg(GBinRoutine *, variable *); +/* S'assure qu'une variable est bien associée à une routine. */ +void g_binary_routine_register_if_needed(GBinRoutine *, size_t, bool); + +/* Donne l'indice d'une variable dans la liste d'une routine. */ +size_t g_binary_routine_get_var_index_from_offset(const GBinRoutine *, size_t, bool); +  /* Décrit le prototype de la routine sous forme de caractères. */  char *g_binary_routine_to_string(const GBinRoutine *); -#endif  /* _ANALYSIS_PROTOTYPE_H */ +#endif  /* _ANALYSIS_ROUTINE_H */ diff --git a/src/analysis/variable.c b/src/analysis/variable.c index 058c152..01c780e 100644 --- a/src/analysis/variable.c +++ b/src/analysis/variable.c @@ -25,7 +25,7 @@  #include <malloc.h> -#include <stdbool.h> +#include <stdint.h>  #include <string.h> @@ -33,6 +33,205 @@ + +/* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */ + + +/* Base de variable (instance) */ +struct _GUnknownVariable +{ +    GObject parent;                         /* A laisser en premier        */ + +    size_t offset;                          /* Position abstraite associée */ +    size_t size;                            /* Taille en mémoire           */ + +}; + +/* Base de variable (classe) */ +struct _GUnknownVariableClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Initialise la classe des bases de variables. */ +static void g_unknown_variable_class_init(GUnknownVariableClass *); + +/* Initialise l'instande d'une base de variable. */ +static void g_unknown_variable_init(GUnknownVariable *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                      BASE DE VARIABLES OU VARIABLES INCONNUES                      */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une base de variable. */ +G_DEFINE_TYPE(GUnknownVariable, g_unknown_variable, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des bases de variables.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_unknown_variable_class_init(GUnknownVariableClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : var = instance à initialiser.                                * +*                                                                             * +*  Description : Initialise l'instande d'une base de variable.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_unknown_variable_init(GUnknownVariable *var) +{ +    var->offset = SIZE_MAX; +    var->size = SIZE_MAX; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Crée une représentation de variable de type inconnu.         * +*                                                                             * +*  Retour      : Variable mise en place.                                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GUnknownVariable *g_unknown_variable_new(void) +{ +    GUnknownVariable *result;               /* Variable à retourner        */ + +    result = g_object_new(G_TYPE_UNKNOWN_VARIABLE, NULL); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = premières informations à consulter.                      * +*                b = secondes informations à consulter.                       * +*                                                                             * +*  Description : Etablit la comparaison ascendante entre deux variables.      * +*                                                                             * +*  Retour      : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b).                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int g_unknown_variable_compare(const GUnknownVariable **a, const GUnknownVariable **b) +{ +    int result;                             /* Bilan à renvoyer            */ + +    if ((*a)->offset < (*b)->offset) result = -1; +    else if((*a)->offset > (*b)->offset) result = 1; +    else result = 0; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : var    = variable à manipuler.                               * +*                offset = position (abstraite ou non) à enregistrer.          * +*                                                                             * +*  Description : Définit la position associée à une variable.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_unknown_variable_set_offset(GUnknownVariable *var, size_t offset) +{ +    var->offset = offset; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : var = variable à manipuler.                                  * +*                                                                             * +*  Description : Fournit la position associée à une variable.                 * +*                                                                             * +*  Retour      : Position de la variable.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +size_t g_unknown_variable_get_offset(const GUnknownVariable *var) +{ +    return var->offset; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : var    = variable à manipuler.                               * +*                offset = position (abstraite ou non) à traiter.              * +*                                                                             * +*  Description : Indique si une position est contenue dans une variable.      * +*                                                                             * +*  Retour      : Bilan de la consultation.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_unknown_variable_contains_offset(const GUnknownVariable *var, size_t offset) +{ +    bool result;                            /* Bilan à retourner           */ + +    if (var->offset == SIZE_MAX) +        return false; + +    if (var->size == SIZE_MAX) +        result = (var->offset == offset); + +    else result = (var->offset <= offset && offset < (var->offset + var->size)); + +    return result; + +} + + + + + +  /* ---------------------------- TYPES DE DONNEES SIMPLES ---------------------------- */ diff --git a/src/analysis/variable.h b/src/analysis/variable.h index 8b50cf4..f2bbb87 100644 --- a/src/analysis/variable.h +++ b/src/analysis/variable.h @@ -25,6 +25,50 @@  #define _ANALYSIS_VARIABLE_H +#include <stdbool.h> +#include <glib-object.h> + + + +/* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */ + + +#define G_TYPE_UNKNOWN_VARIABLE               g_unknown_variable_get_type() +#define G_UNKNOWN_VARIABLE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_unknown_variable_get_type(), GUnknownVariable)) +#define G_IS_UNKNOWN_VARIABLE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_unknown_variable_get_type())) +#define G_UNKNOWN_VARIABLE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_UNKNOWN_VARIABLE, GUnknownVariableClass)) +#define G_IS_UNKNOWN_VARIABLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_UNKNOWN_VARIABLE)) +#define G_UNKNOWN_VARIABLE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_UNKNOWN_VARIABLE, GUnknownVariableClass)) + + +/* Base de variable (instance) */ +typedef struct _GUnknownVariable GUnknownVariable; + +/* Base de variable (classe) */ +typedef struct _GUnknownVariableClass GUnknownVariableClass; + + +/* Indique le type défini pour une base de variable. */ +GType g_unknown_variable_get_type(void); + +/* Crée une représentation de variable de type inconnu. */ +GUnknownVariable *g_unknown_variable_new(void); + +/* Etablit la comparaison ascendante entre deux variables. */ +int g_unknown_variable_compare(const GUnknownVariable **, const GUnknownVariable **); + +/* Définit la position associée à une variable. */ +void g_unknown_variable_set_offset(GUnknownVariable *, size_t); + +/* Fournit la position associée à une variable. */ +size_t g_unknown_variable_get_offset(const GUnknownVariable *); + +/* Indique si une position est contenue dans une variable. */ +bool g_unknown_variable_contains_offset(const GUnknownVariable *, size_t); + + + +  /* Variable repésentant un argument ou un type de retour */  typedef struct _variable variable; diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 54d8135..73a7648 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -313,8 +313,6 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)  {      bool result;                            /* Bilan à renvoyer            */ -    result = false; -      switch (operand->size)      {          case AOS_8_BITS_SIGNED: @@ -330,7 +328,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)              result = (operand->signed_imm.val64 & 0x8000000000000000ll);              break;          default: -            /* Traitement non nécessaire */ +            result = false;              break;      } @@ -561,3 +559,67 @@ bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr)      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand  = opérande à traiter.                               * +*                value    = valeur résultante. [OUT]                          * +*                negative = indique si la valeur était négative à l'origine.  * +*                                                                             * +*  Description : Convertit une valeur immédiate en valeur de type size_t.     * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_imm_operand_to_size_t(const GImmOperand *operand, size_t *value, bool *negative) +{ +    bool result;                            /* Bilan à renvoyer            */ + +    *negative = g_imm_operand_is_negative(operand); + +    switch (operand->size) +    { +        case AOS_8_BITS_UNSIGNED: +            result = (sizeof(size_t) >= 1); +            if (result) *value = operand->unsigned_imm.val8; +            break; +        case AOS_16_BITS_UNSIGNED: +            result = (sizeof(size_t) >= 2); +            if (result) *value = operand->unsigned_imm.val16; +            break; +        case AOS_32_BITS_UNSIGNED: +            result = (sizeof(size_t) >= 4); +            if (result) *value = operand->unsigned_imm.val32; +            break; +        case AOS_64_BITS_UNSIGNED: +            result = (sizeof(size_t) >= 8); +            if (result) *value = operand->unsigned_imm.val64; +            break; +        case AOS_8_BITS_SIGNED: +            result = (sizeof(size_t) >= 1); +            if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val8; +            break; +        case AOS_16_BITS_SIGNED: +            result = (sizeof(size_t) >= 2); +            if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val16; +            break; +        case AOS_32_BITS_SIGNED: +            result = (sizeof(size_t) >= 4); +            if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val32; +            break; +        case AOS_64_BITS_SIGNED: +            result = (sizeof(size_t) >= 8); +            if (result) *value = (*negative ? -1 : 1 ) * operand->signed_imm.val64; +            break; +        default: +            result = false; +            break; +    } + +    return result; + +} diff --git a/src/arch/immediate.h b/src/arch/immediate.h index 1dcc548..d3e4624 100644 --- a/src/arch/immediate.h +++ b/src/arch/immediate.h @@ -63,6 +63,9 @@ bool g_imm_operand_is_negative(const GImmOperand *);  /* Convertit une valeur immédiate en adresse de type vmpa_t. */  bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *); +/* Convertit une valeur immédiate en valeur de type size_t. */ +bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *); +  #endif  /* _ARCH_IMMEDIATE_H */ diff --git a/src/format/exe_format.h b/src/format/exe_format.h index b1cbb17..d61e51a 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -30,7 +30,7 @@  #include <sys/types.h> -#include "../analysis/prototype.h" +#include "../analysis/routine.h"  #include "symbol.h" diff --git a/src/format/format.h b/src/format/format.h index c485e0b..a4de552 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -31,6 +31,7 @@  #include "symbol.h" +#include "../analysis/routine.h" diff --git a/src/format/mangling/demangler-int.h b/src/format/mangling/demangler-int.h index f137fa0..8b8772c 100644 --- a/src/format/mangling/demangler-int.h +++ b/src/format/mangling/demangler-int.h @@ -26,7 +26,6 @@  #include "demangler.h" -#include "../../analysis/prototype.h" diff --git a/src/format/mangling/demangler.h b/src/format/mangling/demangler.h index 3c9a6c1..fb23f16 100644 --- a/src/format/mangling/demangler.h +++ b/src/format/mangling/demangler.h @@ -28,7 +28,7 @@  #include <stdbool.h> -#include "../../analysis/prototype.h" +#include "../../analysis/routine.h" diff --git a/src/format/symbol.c b/src/format/symbol.c index 40efdd2..b5e329b 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -27,6 +27,9 @@  #include <string.h> +#include "../analysis/routine.h" + +  /* Symbole d'exécutable (instance) */  struct _GBinSymbol diff --git a/src/format/symbol.h b/src/format/symbol.h index f4fe299..17fdbcf 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -28,7 +28,6 @@  #include <glib-object.h> -#include "../analysis/prototype.h"  #include "../arch/archbase.h" diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c index 6725fd8..6d47f57 100644 --- a/src/plugins/pglist.c +++ b/src/plugins/pglist.c @@ -77,7 +77,7 @@ bool init_all_plugins(GObject *ref)  {      _list.ref = ref; -    browse_directory_for_plugins(&_list, PACKAGE_SOURCE_DIR "/plugins.disabled"); +    browse_directory_for_plugins(&_list, PACKAGE_SOURCE_DIR "/plugins");      return true; diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 7c62146..e6e4a1a 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -135,7 +135,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)      result->module = g_module_open(filename, G_MODULE_BIND_LAZY); -#if 0 +#if 1      if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&__get_action))      {          printf("Err plugin get_action sym\n"); | 
