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 /plugins | |
| parent | 1beaa1af679d49d99696ec907662b764f7ba1867 (diff) | |
Parsed and replaced ModRM operands.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@121 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/stackvars/operand.c | 62 | ||||
| -rw-r--r-- | plugins/stackvars/operand.h | 5 | ||||
| -rw-r--r-- | plugins/stackvars/stackvars.c | 72 | 
3 files changed, 88 insertions, 51 deletions
| 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; | 
