summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-09-30 00:00:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-09-30 00:00:43 (GMT)
commit3c6968d4d5a8918c456cdea28a7c6195368d996e (patch)
treee6909254a8033cdabd116f287db2893e938a636d /plugins
parent1beaa1af679d49d99696ec907662b764f7ba1867 (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.c62
-rw-r--r--plugins/stackvars/operand.h5
-rw-r--r--plugins/stackvars/stackvars.c72
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;