From 3c6968d4d5a8918c456cdea28a7c6195368d996e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 30 Sep 2009 00:00:43 +0000 Subject: Parsed and replaced ModRM operands. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@121 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 47 +++ plugins/stackvars/operand.c | 62 ++-- plugins/stackvars/operand.h | 5 +- plugins/stackvars/stackvars.c | 72 +++-- src/analysis/Makefile.am | 2 +- src/analysis/binary.c | 2 +- src/analysis/exporter.c | 7 + src/analysis/exporter.h | 2 + src/analysis/prototype.c | 471 ----------------------------- src/analysis/prototype.h | 105 ------- src/analysis/routine.c | 580 ++++++++++++++++++++++++++++++++++++ src/analysis/routine.h | 111 +++++++ src/analysis/variable.c | 201 ++++++++++++- src/analysis/variable.h | 44 +++ src/arch/immediate.c | 68 ++++- src/arch/immediate.h | 3 + src/format/exe_format.h | 2 +- src/format/format.h | 1 + src/format/mangling/demangler-int.h | 1 - src/format/mangling/demangler.h | 2 +- src/format/symbol.c | 3 + src/format/symbol.h | 1 - src/plugins/pglist.c | 2 +- src/plugins/plugin.c | 2 +- 24 files changed, 1157 insertions(+), 639 deletions(-) delete mode 100644 src/analysis/prototype.c delete mode 100644 src/analysis/prototype.h create mode 100644 src/analysis/routine.c create mode 100644 src/analysis/routine.h diff --git a/ChangeLog b/ChangeLog index a3dc317..11943d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +09-09-30 Cyrille Bagard + + * 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 * 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 #include +#include #include @@ -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, "[varX]"); + 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 -#include +#include +#include @@ -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 -#include +#include #include #include #include @@ -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/prototype.c deleted file mode 100644 index 72ee809..0000000 --- a/src/analysis/prototype.c +++ /dev/null @@ -1,471 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * prototype.c - manipulation des prototypes de fonctions et de variables - * - * Copyright (C) 2008 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 . - */ - - -#include "prototype.h" - - -#include -#include - - -#include "../common/extstr.h" - - - -/* Représentation générique de routine (instance) */ -struct _GBinRoutine -{ - GObject parent; /* A laisser en premier */ - - vmpa_t addr; /* Position physique/mémoire */ - off_t size; /* Taille du code associé */ - - RoutineType type; /* Type de routine */ - - variable *ret_type; /* Type retourné */ - - char *name; /* Désignation humaine */ - - variable **args_types; /* Types d'arguments */ - size_t args_count; /* Nombre d'arguments */ - -}; - - -/* Représentation générique de routine (classe) */ -struct _GBinRoutineClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des représentation de routine. */ -static void g_bin_routine_class_init(GBinRoutineClass *); - -/* Initialise une instance représentation de routine. */ -static void g_bin_routine_init(GBinRoutine *); - - - -/* Indique le type définit pour une représentation de routine. */ -G_DEFINE_TYPE(GBinRoutine, g_bin_routine, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des représentation de routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_bin_routine_class_init(GBinRoutineClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : line = instance à initialiser. * -* * -* Description : Initialise une instance représentation de routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_bin_routine_init(GBinRoutine *line) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée une représentation de routine. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinRoutine *g_binary_routine_new(void) -{ - GBinRoutine *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_BIN_ROUTINE, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à effacer. * -* * -* Description : Supprime une représentation de routine de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 /* FIXME */ -void g_binary_routine_finalize(GBinRoutine *routine) -{ - size_t i; /* Boucle de parcours */ - - if (routine->ret_type) - delete_var(routine->ret_type); - - if (routine->name != NULL) - free(routine->name); - - for (i = 0; i < routine->args_count; i++) - delete_var(routine->args_types[i]); - - free(routine); - -} -#endif - - -/****************************************************************************** -* * -* Paramètres : a = premières informations à consulter. * -* b = secondes informations à consulter. * -* * -* Description : Etablit la comparaison ascendante entre deux routines. * -* * -* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * -* * -* Remarques : - * -* * -******************************************************************************/ - -int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) -{ - int result; /* Bilan à renvoyer */ - - if ((*a)->addr < (*b)->addr) result = -1; - else if((*a)->addr > (*b)->addr) result = 1; - else result = 0; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : a = premières informations à consulter. * -* b = secondes informations à consulter. * -* * -* Description : Etablit la comparaison descendante entre deux routines. * -* * -* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * -* * -* Remarques : - * -* * -******************************************************************************/ - -int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) -{ - int result; /* Bilan à renvoyer */ - - if ((*a)->addr > (*b)->addr) result = -1; - else if((*a)->addr < (*b)->addr) result = 1; - else result = 0; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* addr = position mémoire ou physique déclarée. * -* * -* Description : Définit la position physique / en mémoire d'une routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr) -{ - routine->addr = addr; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* * -* Description : Fournit la position physique / en mémoire d'une routine. * -* * -* Retour : Position mémoire ou physique déclarée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -vmpa_t g_binary_routine_get_address(const GBinRoutine *routine) -{ - return routine->addr; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* addr = taille du code associé. * -* * -* Description : Définit la taille du code d'une routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_routine_set_size(GBinRoutine *routine, off_t size) -{ - routine->size = size; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* * -* Description : Fournit la taille du code associé à une routine. * -* * -* Retour : Taille du code associée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -off_t g_binary_routine_get_size(const GBinRoutine *routine) -{ - return routine->size; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* type = type de routine spécifié. * -* * -* Description : Définit le type d'une routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) -{ - routine->type = type; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* name = désignation humainement lisible. * -* * -* Description : Définit le nom humain d'une routine. * -* * -* Retour : - * -* * -* Remarques : Le nom ne doit pas ensuite être libéré par l'appelant ! * -* * -******************************************************************************/ - -void g_binary_routine_set_name(GBinRoutine *routine, char *name) -{ - if (routine->name != NULL) - free(routine->name); - - routine->name = name; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* * -* Description : Fournit le nom humain d'une routine. * -* * -* Retour : Désignation humainement lisible ou NULL si non définie. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_binary_routine_get_name(const GBinRoutine *routine) -{ - return routine->name; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* var = variable représentant un type de retour. * -* * -* Description : Définit le type de retour d'une routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_routine_set_return_type(GBinRoutine *routine, variable *var) -{ - if (routine->ret_type != NULL) - delete_var(routine->ret_type); - - routine->ret_type = var; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* var = variable représentant un argument supplémentaire. * -* * -* Description : Ajoute un argument à une routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_routine_add_arg(GBinRoutine *routine, variable *var) -{ - routine->args_count++; - - routine->args_types = (variable **)realloc(routine->args_types, - routine->args_count * sizeof(variable *)); - - routine->args_types[routine->args_count - 1] = var; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à consulter. * -* * -* Description : Décrit le prototype de la routine sous forme de caractères. * -* * -* Retour : Chaîne de caractères à libérer de la mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *g_binary_routine_to_string(const GBinRoutine *routine) -{ - char *result; /* Chaîne à renvoyer */ - size_t i; /* Boucle de parcours */ - char *typestr; /* Stockage de nom temporaire */ - - /* Retour de la fonction */ - - switch (routine->type) - { - case RTT_CONSTRUCTOR: - result = strdup(routine->name); - result = stradd(result, "::"); - break; - - case RTT_DESTRUCTOR: - result = strdup(routine->name); - result = stradd(result, "::~"); - break; - - default: /* Pour gcc */ - case RTT_CLASSIC: - if (routine->ret_type == NULL) result = strdup("??? "); - else - { - result = var_to_string(routine->ret_type); - result = stradd(result, " "); - } - break; - - } - - /* Nom de la routine */ - - result = stradd(result, routine->name); - - /* Liste des arguments */ - - result = stradd(result, "("); - - for (i = 0; i < routine->args_count; i++) - { - if (i > 0) result = stradd(result, ", "); - - typestr = var_to_string(routine->args_types[i]); - result = stradd(result, typestr); - free(typestr); - - } - - result = stradd(result, ")"); - - return result; - -} diff --git a/src/analysis/prototype.h b/src/analysis/prototype.h deleted file mode 100644 index 2a9439e..0000000 --- a/src/analysis/prototype.h +++ /dev/null @@ -1,105 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * prototype.h - prototypes pour la manipulation des prototypes de fonctions et de variables - * - * Copyright (C) 2008 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 . - */ - - -#ifndef _ANALYSIS_PROTOTYPE_H -#define _ANALYSIS_PROTOTYPE_H - - -#include -#include -#include - - -#include "variable.h" -#include "../arch/archbase.h" - - - -/* Type de routine traitée */ -typedef enum _RoutineType -{ - RTT_CLASSIC, /* Fonction ou méthode */ - RTT_CONSTRUCTOR, /* Constructeur */ - RTT_DESTRUCTOR /* Destructeur */ - -} RoutineType; - - -#define G_TYPE_BIN_ROUTINE g_bin_routine_get_type() -#define G_BIN_ROUTINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_bin_routine_get_type(), GBinRoutine)) -#define G_IS_BIN_ROUTINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_bin_routine_get_type())) -#define G_BIN_ROUTINE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_bin_routine_get_type(), GBinRoutineIface)) - - -/* Représentation générique de routine (instance) */ -typedef struct _GBinRoutine GBinRoutine; - -/* Représentation générique de routine (classe) */ -typedef struct _GBinRoutineClass GBinRoutineClass; - - -/* Indique le type définit pour une représentation de routine. */ -GType g_bin_routine_get_type(void); - -/* Crée une représentation de routine. */ -GBinRoutine *g_binary_routine_new(void); - -/* Etablit la comparaison ascendante entre deux routines. */ -int g_binary_routine_compare(const GBinRoutine **, const GBinRoutine **); - -/* Etablit la comparaison descendante entre deux routines. */ -int g_binary_routine_rcompare(const GBinRoutine **, const GBinRoutine **); - -/* Définit la position physique / en mémoire d'une routine. */ -void g_binary_routine_set_address(GBinRoutine *, vmpa_t); - -/* Fournit la position physique / en mémoire d'une routine. */ -vmpa_t g_binary_routine_get_address(const GBinRoutine *); - -/* Définit la taille du code d'une routine. */ -void g_binary_routine_set_size(GBinRoutine *, off_t); - -/* Fournit la taille du code associé à une routine. */ -off_t g_binary_routine_get_size(const GBinRoutine *); - -/* Définit le type d'une routine. */ -void g_binary_routine_set_type(GBinRoutine *, RoutineType); - -/* Définit le nom humain d'une routine. */ -void g_binary_routine_set_name(GBinRoutine *, char *); - -/* Désignation humainement lisible ou NULL si non définie. */ -const char *g_binary_routine_get_name(const GBinRoutine *); - -/* Définit le type de retour d'une routine. */ -void g_binary_routine_set_return_type(GBinRoutine *, variable *); - -/* Ajoute un argument à une routine. */ -void g_binary_routine_add_arg(GBinRoutine *, variable *); - -/* Décrit le prototype de la routine sous forme de caractères. */ -char *g_binary_routine_to_string(const GBinRoutine *); - - - -#endif /* _ANALYSIS_PROTOTYPE_H */ diff --git a/src/analysis/routine.c b/src/analysis/routine.c new file mode 100644 index 0000000..4bbd712 --- /dev/null +++ b/src/analysis/routine.c @@ -0,0 +1,580 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * routine.c - manipulation des prototypes de fonctions et de variables + * + * Copyright (C) 2008 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 . + */ + + +#include "routine.h" + + +#include +#include +#include + + +#include "../common/extstr.h" + + + +/* Représentation générique de routine (instance) */ +struct _GBinRoutine +{ + GObject parent; /* A laisser en premier */ + + vmpa_t addr; /* Position physique/mémoire */ + off_t size; /* Taille du code associé */ + + RoutineType type; /* Type de routine */ + + variable *ret_type; /* Type retourné */ + + 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 */ + +}; + + +/* Représentation générique de routine (classe) */ +struct _GBinRoutineClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des représentation de routine. */ +static void g_bin_routine_class_init(GBinRoutineClass *); + +/* Initialise une instance représentation de routine. */ +static void g_bin_routine_init(GBinRoutine *); + + + +/* Indique le type définit pour une représentation de routine. */ +G_DEFINE_TYPE(GBinRoutine, g_bin_routine, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des représentation de routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bin_routine_class_init(GBinRoutineClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : line = instance à initialiser. * +* * +* Description : Initialise une instance représentation de routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bin_routine_init(GBinRoutine *line) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une représentation de routine. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine *g_binary_routine_new(void) +{ + GBinRoutine *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BIN_ROUTINE, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à effacer. * +* * +* Description : Supprime une représentation de routine de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#if 0 /* FIXME */ +void g_binary_routine_finalize(GBinRoutine *routine) +{ + size_t i; /* Boucle de parcours */ + + if (routine->ret_type) + delete_var(routine->ret_type); + + if (routine->name != NULL) + free(routine->name); + + for (i = 0; i < routine->old_args_count; i++) + delete_var(routine->args_types[i]); + + free(routine); + +} +#endif + + +/****************************************************************************** +* * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * +* * +* Description : Etablit la comparaison ascendante entre deux routines. * +* * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) +{ + int result; /* Bilan à renvoyer */ + + if ((*a)->addr < (*b)->addr) result = -1; + else if((*a)->addr > (*b)->addr) result = 1; + else result = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * +* * +* Description : Etablit la comparaison descendante entre deux routines. * +* * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) +{ + int result; /* Bilan à renvoyer */ + + if ((*a)->addr > (*b)->addr) result = -1; + else if((*a)->addr < (*b)->addr) result = 1; + else result = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* addr = position mémoire ou physique déclarée. * +* * +* Description : Définit la position physique / en mémoire d'une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr) +{ + routine->addr = addr; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* * +* Description : Fournit la position physique / en mémoire d'une routine. * +* * +* Retour : Position mémoire ou physique déclarée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t g_binary_routine_get_address(const GBinRoutine *routine) +{ + return routine->addr; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* addr = taille du code associé. * +* * +* Description : Définit la taille du code d'une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_routine_set_size(GBinRoutine *routine, off_t size) +{ + routine->size = size; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* * +* Description : Fournit la taille du code associé à une routine. * +* * +* Retour : Taille du code associée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +off_t g_binary_routine_get_size(const GBinRoutine *routine) +{ + return routine->size; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* type = type de routine spécifié. * +* * +* Description : Définit le type d'une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) +{ + routine->type = type; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* name = désignation humainement lisible. * +* * +* Description : Définit le nom humain d'une routine. * +* * +* Retour : - * +* * +* Remarques : Le nom ne doit pas ensuite être libéré par l'appelant ! * +* * +******************************************************************************/ + +void g_binary_routine_set_name(GBinRoutine *routine, char *name) +{ + if (routine->name != NULL) + free(routine->name); + + routine->name = name; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* * +* Description : Fournit le nom humain d'une routine. * +* * +* Retour : Désignation humainement lisible ou NULL si non définie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_routine_get_name(const GBinRoutine *routine) +{ + return routine->name; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* var = variable représentant un type de retour. * +* * +* Description : Définit le type de retour d'une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_routine_set_return_type(GBinRoutine *routine, variable *var) +{ + if (routine->ret_type != NULL) + delete_var(routine->ret_type); + + routine->ret_type = var; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* var = variable représentant un argument supplémentaire. * +* * +* Description : Ajoute un argument à une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_routine_add_arg(GBinRoutine *routine, variable *var) +{ + routine->old_args_count++; + + routine->args_types = (variable **)realloc(routine->args_types, + 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); + + /* 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; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à consulter. * +* * +* Description : Décrit le prototype de la routine sous forme de caractères. * +* * +* Retour : Chaîne de caractères à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *g_binary_routine_to_string(const GBinRoutine *routine) +{ + char *result; /* Chaîne à renvoyer */ + size_t i; /* Boucle de parcours */ + char *typestr; /* Stockage de nom temporaire */ + + /* Retour de la fonction */ + + switch (routine->type) + { + case RTT_CONSTRUCTOR: + result = strdup(routine->name); + result = stradd(result, "::"); + break; + + case RTT_DESTRUCTOR: + result = strdup(routine->name); + result = stradd(result, "::~"); + break; + + default: /* Pour gcc */ + case RTT_CLASSIC: + if (routine->ret_type == NULL) result = strdup("??? "); + else + { + result = var_to_string(routine->ret_type); + result = stradd(result, " "); + } + break; + + } + + /* Nom de la routine */ + + result = stradd(result, routine->name); + + /* Liste des arguments */ + + result = stradd(result, "("); + + for (i = 0; i < routine->old_args_count; i++) + { + if (i > 0) result = stradd(result, ", "); + + typestr = var_to_string(routine->args_types[i]); + result = stradd(result, typestr); + free(typestr); + + } + + result = stradd(result, ")"); + + return result; + +} diff --git a/src/analysis/routine.h b/src/analysis/routine.h new file mode 100644 index 0000000..4e47b5e --- /dev/null +++ b/src/analysis/routine.h @@ -0,0 +1,111 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * routine.h - prototypes pour la manipulation des prototypes de fonctions et de variables + * + * Copyright (C) 2008 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 . + */ + + +#ifndef _ANALYSIS_ROUTINE_H +#define _ANALYSIS_ROUTINE_H + + +#include +#include +#include + + +#include "variable.h" +#include "../arch/archbase.h" + + + +/* Type de routine traitée */ +typedef enum _RoutineType +{ + RTT_CLASSIC, /* Fonction ou méthode */ + RTT_CONSTRUCTOR, /* Constructeur */ + RTT_DESTRUCTOR /* Destructeur */ + +} RoutineType; + + +#define G_TYPE_BIN_ROUTINE g_bin_routine_get_type() +#define G_BIN_ROUTINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_bin_routine_get_type(), GBinRoutine)) +#define G_IS_BIN_ROUTINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_bin_routine_get_type())) +#define G_BIN_ROUTINE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_bin_routine_get_type(), GBinRoutineIface)) + + +/* Représentation générique de routine (instance) */ +typedef struct _GBinRoutine GBinRoutine; + +/* Représentation générique de routine (classe) */ +typedef struct _GBinRoutineClass GBinRoutineClass; + + +/* Indique le type définit pour une représentation de routine. */ +GType g_bin_routine_get_type(void); + +/* Crée une représentation de routine. */ +GBinRoutine *g_binary_routine_new(void); + +/* Etablit la comparaison ascendante entre deux routines. */ +int g_binary_routine_compare(const GBinRoutine **, const GBinRoutine **); + +/* Etablit la comparaison descendante entre deux routines. */ +int g_binary_routine_rcompare(const GBinRoutine **, const GBinRoutine **); + +/* Définit la position physique / en mémoire d'une routine. */ +void g_binary_routine_set_address(GBinRoutine *, vmpa_t); + +/* Fournit la position physique / en mémoire d'une routine. */ +vmpa_t g_binary_routine_get_address(const GBinRoutine *); + +/* Définit la taille du code d'une routine. */ +void g_binary_routine_set_size(GBinRoutine *, off_t); + +/* Fournit la taille du code associé à une routine. */ +off_t g_binary_routine_get_size(const GBinRoutine *); + +/* Définit le type d'une routine. */ +void g_binary_routine_set_type(GBinRoutine *, RoutineType); + +/* Définit le nom humain d'une routine. */ +void g_binary_routine_set_name(GBinRoutine *, char *); + +/* Désignation humainement lisible ou NULL si non définie. */ +const char *g_binary_routine_get_name(const GBinRoutine *); + +/* Définit le type de retour d'une routine. */ +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_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 -#include +#include #include @@ -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 +#include + + + +/* -------------------- 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 -#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 -#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 +#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 -#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"); -- cgit v0.11.2-87-g4458