diff options
Diffstat (limited to 'src/analysis')
| -rw-r--r-- | src/analysis/binary.c | 171 | ||||
| -rw-r--r-- | src/analysis/disass/Makefile.am | 1 | ||||
| -rw-r--r-- | src/analysis/disass/disassembler.c | 7 | ||||
| -rw-r--r-- | src/analysis/disass/fetch.c | 4 | ||||
| -rw-r--r-- | src/analysis/disass/limit.c | 156 | ||||
| -rw-r--r-- | src/analysis/disass/limit.h | 38 | ||||
| -rw-r--r-- | src/analysis/disass/output.c | 2 | ||||
| -rw-r--r-- | src/analysis/disass/output.h | 2 | 
8 files changed, 203 insertions, 178 deletions
| diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 45e6d31..2b84b57 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -60,22 +60,6 @@  /* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ -#if 0 - - -/* S'assure que toutes les routines ont une taille définie. */ -static void limit_all_routines(GRenderingLine *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); - -/* Cherche l'adresse de fin d'une routine. */ -static vmpa_t find_best_ending_address_for_routine(GRenderingLine *, size_t, const vmpa_t *, const off_t *, size_t); - - - -#endif - - - -  /* Description de fichier binaire (instance) */  struct _GOpenidaBinary  { @@ -149,161 +133,6 @@ static void g_openida_binary_breakpoint_added(GBreakGroup *, GBreakPoint *, GOpe  static void g_openida_binary_breakpoint_removed(GBreakGroup *, GBreakPoint *, GOpenidaBinary *); -#if 0 - - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : lines     = lignes de rendu à parcourir.                     * -*                routines  = prototypes existants à insérer.                  * -*                count     = quantité de ces prototypes.                      * -*                statusbar = barre de statut avec progression à mettre à jour.* -*                id        = identifiant du message affiché à l'utilisateur.  * -*                                                                             * -*  Description : S'assure que toutes les routines ont une taille définie.     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void limit_all_routines(GRenderingLine *lines, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) -{ -    size_t i;                               /* Boucle de parcours          */ -    vmpa_t *starts;                         /* Adresses de départ          */ -    off_t *lengths;                         /* Tailles des routines        */ -    GRenderingLine *line;                   /* Ligne de départ / d'arrivée */ -    vmpa_t start;                           /* Adresse de début de routine */ -    vmpa_t last;                            /* Meilleur dernière adresse   */ -    GArchInstruction *instr;                /* Instruction à ausculter     */ -    off_t length;                           /* Taille du code              */ - -    if (count == 0) return; - -    starts = (vmpa_t *)calloc(count, sizeof(vmpa_t)); -    lengths = (off_t *)calloc(count, sizeof(off_t)); - -    for (i = 0; i < count; i++) -    { -        starts[i] = g_binary_routine_get_address(routines[i]); -        lengths[i] = g_binary_routine_get_size(routines[i]); - -        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / (count * 2)); - -    } - -    for (i = 0; i < count; i++) -    { -        /* Instruction de départ */ - -        /* FIXME : faire mieux ! */ - -        line = g_rendering_line_find_by_address(lines, NULL, starts[i]); -        if (line != NULL) line = g_rendering_line_loop_for_code(line, NULL); - -        if (line != NULL) -        { -            instr = g_code_line_get_instruction(G_CODE_LINE(line)); - -            g_binary_routine_set_instructions(routines[i], instr); - -        } - - -        if (lengths[i] > 0) continue; - -        start = g_binary_routine_get_address(routines[i]); -        line = g_rendering_line_find_by_address(lines, NULL, start); - -        /* Si le symbole est hors du code analysé (routine de PLT par exemple) */ -        if (line == NULL) continue; - -        last = find_best_ending_address_for_routine(line, i, starts, lengths, count); - -        line = g_rendering_line_find_by_address(lines, NULL, last); -        line = g_rendering_line_loop_for_code(line, NULL); - -        instr = g_code_line_get_instruction(G_CODE_LINE(line)); -        g_arch_instruction_get_location(instr, NULL, &length, NULL); - -        lengths[i] = last - start + length; -        g_binary_routine_set_size(routines[i], lengths[i]); - -        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1 + count) * 1.0 / (count * 2)); - -    } - -    free(starts); -    free(lengths); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : line    = ligne de départ du parcours.                       * -*                index   = indice de la routine traitée dans la liste.        * -*                starts  = adresse de départ des autres routines.             * -*                lengths = taille des différentes routines, valides ou nulles.* -*                count   = quantité de routines présentes.                    * -*                                                                             * -*  Description : Cherche l'adresse de fin d'une routine.                      * -*                                                                             * -*  Retour      : Plus grande adresse de dernière instruction de routine.      * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static vmpa_t find_best_ending_address_for_routine(GRenderingLine *line, size_t index, const vmpa_t *starts, const off_t *lengths, size_t count) -{ -    vmpa_t result;                          /* Haute adresse à remonter    */ -    GRenderingLine *iter;                   /* Boucle de parcours #1       */ -    vmpa_t candidate;                       /* Candidat potentiel          */ -    size_t i;                               /* Boucle de parcours #2       */ -    GArchInstruction *instr;                /* Instruction à ausculter     */ - -    result = starts[index]; - -    for (iter = line; iter != NULL; iter = g_rendering_line_get_next_iter(line, iter, NULL)) -    { -        if (!G_IS_CODE_LINE(iter)) continue; - -        candidate = get_rendering_line_address(iter); - -        /* Regarde si on n'empiète pas sur une autre routine */ - -        for (i = 0; i < count; i++) -        { -            if (i == index) continue; - -            if (starts[i] <= candidate && candidate < (starts[i] + lengths[i])) -                break; - -        } - -        if (i != count) break; -        else result = candidate; - -        /* Retour de fonction ? */ - -        instr = g_code_line_get_instruction(G_CODE_LINE(iter)); -        if (g_arch_instruction_is_return(instr)) break; - -    } - -    return result; - -} - - -#endif - - -  /* Indique le type défini pour une description de fichier binaire. */  G_DEFINE_TYPE(GOpenidaBinary, g_openida_binary, G_TYPE_OBJECT); diff --git a/src/analysis/disass/Makefile.am b/src/analysis/disass/Makefile.am index 784731a..ce27d15 100644 --- a/src/analysis/disass/Makefile.am +++ b/src/analysis/disass/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libanalysisdisass.la  libanalysisdisass_la_SOURCES =			\  	disassembler.h disassembler.c		\  	fetch.h fetch.c						\ +	limit.h limit.c						\  	links.h links.c						\  	output.h output.c diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 5a866c0..dc374db 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -33,6 +33,7 @@  #include "fetch.h" +#include "limit.h"  #include "links.h"  #include "output.h"  #include "../../decomp/lang/asm.h" @@ -244,17 +245,17 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta      establish_links_between_lines(disass->instrs, routines, routines_count, statusbar, id);      gtk_extended_status_bar_remove(statusbar, id); -#if 0 +      /* Troisième  étape */      id = gtk_extended_status_bar_push(statusbar, _("Finding remaining limits..."), true);      qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); -    limit_all_routines(disass->lines, routines, routines_count, statusbar, id); +    limit_all_routines(disass->instrs, routines, routines_count, statusbar, id);      gtk_extended_status_bar_remove(statusbar, id); -#endif +      /* Quatrième étape */      id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index e487dd2..6bd9795 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -69,8 +69,8 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar      result = NULL; -    format = g_openida_binary_get_format(binary); -    proc = get_arch_processor_from_format(format); +    format = G_BIN_FORMAT(g_openida_binary_get_format(binary)); +    proc = get_arch_processor_from_format(G_EXE_FORMAT(format));      bin_data = g_openida_binary_get_data(binary, &bin_length);      /* Préparation du suivi de la progression */ diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c new file mode 100644 index 0000000..2598d7e --- /dev/null +++ b/src/analysis/disass/limit.c @@ -0,0 +1,156 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * limit.c - détermination des bornes des routines + * + * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. + */ + + +#include "limit.h" + + +#include <malloc.h> + + + +/* Cherche l'adresse de fin d'une routine. */ +static vmpa_t find_best_ending_address_for_routine(GArchInstruction *, size_t, const vmpa_t *, const off_t *, size_t); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : list      = ensemble d'instructions désassemblées.           * +*                routines  = prototypes existants à insérer.                  * +*                count     = quantité de ces prototypes.                      * +*                statusbar = barre de statut avec progression à mettre à jour.* +*                id        = identifiant du message affiché à l'utilisateur.  * +*                                                                             * +*  Description : S'assure que toutes les routines ont une taille définie.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void limit_all_routines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) +{ +    size_t i;                               /* Boucle de parcours          */ +    vmpa_t *starts;                         /* Adresses de départ          */ +    off_t *lengths;                         /* Tailles des routines        */ +    GArchInstruction *instr;                /* Instr. de départ / arrivée  */ + +    if (count == 0) return; + +    starts = (vmpa_t *)calloc(count, sizeof(vmpa_t)); +    lengths = (off_t *)calloc(count, sizeof(off_t)); + +    for (i = 0; i < count; i++) +    { +        starts[i] = g_binary_routine_get_address(routines[i]); +        lengths[i] = g_binary_routine_get_size(routines[i]); + +        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / (count * 2)); + +    } + +    for (i = 0; i < count; i++) +    { +        /* Instruction de départ */ + +        instr = g_arch_instruction_find_by_address(list, starts[i], true); +        g_binary_routine_set_instructions(routines[i], instr); + +        if (lengths[i] > 0) goto lar_next; + +        /* Si le symbole est hors du code analysé (routine de PLT par exemple) */ +        if (instr == NULL) goto lar_next; + +        /* Taille de la routine */ + +        lengths[i] = find_best_ending_address_for_routine(instr, i, starts, lengths, count); +        lengths[i] -= starts[i]; + +        g_binary_routine_set_size(routines[i], lengths[i]); + + lar_next: + +        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1 + count) * 1.0 / (count * 2)); + +    } + +    free(starts); +    free(lengths); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : first   = première instruction de la routine courante.       * +*                index   = indice de la routine traitée dans la liste.        * +*                starts  = adresse de départ des autres routines.             * +*                lengths = taille des différentes routines, valides ou nulles.* +*                count   = quantité de routines présentes.                    * +*                                                                             * +*  Description : Cherche l'adresse de fin d'une routine.                      * +*                                                                             * +*  Retour      : Plus grande adresse de dernière instruction de routine.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static vmpa_t find_best_ending_address_for_routine(GArchInstruction *first, size_t index, const vmpa_t *starts, const off_t *lengths, size_t count) +{ +    vmpa_t result;                          /* Haute adresse à remonter    */ +    GArchInstruction *iter;                 /* Boucle de parcours #1       */ +    vmpa_t candidate;                       /* Candidat potentiel          */ +    size_t i;                               /* Boucle de parcours #2       */ + +    result = starts[index]; + +    for (iter = first; +         iter != NULL; +         iter = g_arch_instruction_get_next_iter(first, iter, VMPA_MAX)) +    { +        g_arch_instruction_get_location(iter, NULL, NULL, &candidate); + +        /* Regarde si on n'empiète pas sur une autre routine */ + +        for (i = 0; i < count; i++) +        { +            if (i == index) continue; + +            if (starts[i] <= candidate && candidate < (starts[i] + lengths[i])) +                break; + +        } + +        if (i != count) break; +        else result = candidate; + +        /* Retour de fonction ? */ +        if (g_arch_instruction_is_return(iter)) break; + +    } + +    return result; + +} diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h new file mode 100644 index 0000000..7ef9396 --- /dev/null +++ b/src/analysis/disass/limit.h @@ -0,0 +1,38 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * limit.h - prototypes pour la détermination des bornes des routines + * + * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_DISASS_LIMIT_H +#define _ANALYSIS_DISASS_LIMIT_H + + +#include "../routine.h" +#include "../../gtkext/gtkextstatusbar.h" + + + +/* S'assure que toutes les routines ont une taille définie. */ +void limit_all_routines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); + + + +#endif  /* _ANALYSIS_DISASS_LIMIT_H */ diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 0209a97..343973f 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -45,7 +45,7 @@  *                                                                             *  ******************************************************************************/ -void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, const GArchInstruction *instrs, const GBinRoutine **routines, size_t count) +void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *format, const GArchInstruction *instrs, GBinRoutine * const *routines, size_t count)  {      GLangOutput *output;                    /* Modèle de sortie adéquat    */      GArchProcessor *proc;                   /* Architecture du binaire     */ diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h index 40e7536..7e0a3cc 100644 --- a/src/analysis/disass/output.h +++ b/src/analysis/disass/output.h @@ -32,7 +32,7 @@  /* Transcrit du code désassemblé en texte humainement lisible. */ -void print_disassembled_instructions(GCodeBuffer *, const GExeFormat *, const GArchInstruction *, const GBinRoutine **, size_t); +void print_disassembled_instructions(GCodeBuffer *, const GExeFormat *, const GArchInstruction *, GBinRoutine * const *, size_t); | 
