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; |