From 3154db88ce14aa681cc553a8910edba1e69d8c2b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 28 May 2016 16:39:56 +0200 Subject: Built the basic blocks list simply at loading. --- ChangeLog | 20 ++ src/analysis/disass/Makefile.am | 2 +- src/analysis/disass/block.c | 546 ++++++++++++++++++++++++++++++++++++++++ src/analysis/disass/block.h | 111 ++++++++ src/analysis/disass/dragon.c | 44 ++++ src/analysis/disass/dragon.h | 4 + src/analysis/disass/rank.c | 128 ++++++++++ src/analysis/disass/routines.c | 5 +- src/analysis/routine.c | 6 +- src/analysis/routine.h | 6 +- 10 files changed, 864 insertions(+), 8 deletions(-) create mode 100644 src/analysis/disass/block.c create mode 100644 src/analysis/disass/block.h diff --git a/ChangeLog b/ChangeLog index 444dbb0..c8bb2c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 16-05-28 Cyrille Bagard + * src/analysis/disass/Makefile.am: + Add the 'block.[ch]' files to libanalysisdisass_la_SOURCES, and remove + the 'macro.[ch]' ones. + + * src/analysis/disass/block.c: + * src/analysis/disass/block.h: + New entries: build the basic blocks list simply at loading. + + * src/analysis/disass/dragon.c: + * src/analysis/disass/dragon.h: + Translate dragon nodes into basic blocks. + + * src/analysis/disass/rank.c: + * src/analysis/disass/routines.c: + * src/analysis/routine.c: + * src/analysis/routine.h: + Update code. + +16-05-28 Cyrille Bagard + * configure.ac: Remove the Makefile from the 'plugins/python/androperms' directory. diff --git a/src/analysis/disass/Makefile.am b/src/analysis/disass/Makefile.am index 7223e5a..b6d123c 100644 --- a/src/analysis/disass/Makefile.am +++ b/src/analysis/disass/Makefile.am @@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libanalysisdisass.la libanalysisdisass_la_SOURCES = \ area.h area.c \ + block.h block.c \ disassembler.h disassembler.c \ dragon.h dragon.c \ fetch.h fetch.c \ @@ -10,7 +11,6 @@ libanalysisdisass_la_SOURCES = \ limit.h limit.c \ links.h links.c \ loop.h loop.c \ - macro.h macro.c \ output.h output.c \ rank.h rank.c \ routines.h routines.c diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c new file mode 100644 index 0000000..ff780e6 --- /dev/null +++ b/src/analysis/disass/block.c @@ -0,0 +1,546 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * block.c - encadrement des instructions par blocs + * + * Copyright (C) 2012-2013 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "block.h" + + +#include + + + +/* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */ + + +/* Description d'un bloc basique d'instructions (instance) */ +struct _GBasicBlock +{ + GObject parent; /* A laisser en premier */ + + GArchInstruction *first; /* Première instruction */ + GArchInstruction *last; /* Dernière instruction */ + + unsigned int rank; /* Rang dans l'exécution */ + +}; + +/* Description d'un bloc basique d'instructions (classe) */ +struct _GBasicBlockClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des blocs d'instructions basique. */ +static void g_basic_block_class_init(GBasicBlockClass *); + +/* Initialise un bloc d'instructions basique. */ +static void g_basic_block_init(GBasicBlock *); + +/* Supprime toutes les références externes. */ +static void g_basic_block_dispose(GBasicBlock *); + +/* Procède à la libération totale de la mémoire. */ +static void g_basic_block_finalize(GBasicBlock *); + + + +/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */ + + +/* Description d'une liste de blocs basiques (instance) */ +struct _GBlockList +{ + GObject parent; /* A laisser en premier */ + + GBasicBlock **blocks; /* Blocs basiques rassemblés */ + size_t count; /* Quantité de ces blocs */ + +}; + +/* Description d'une liste de blocs basiques (classe) */ +struct _GBlockListClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des listes de blocs basiques. */ +static void g_block_list_class_init(GBlockListClass *); + +/* Initialise une liste de blocs basiques. */ +static void g_block_list_init(GBlockList *); + +/* Supprime toutes les références externes. */ +static void g_block_list_dispose(GBlockList *); + +/* Procède à la libération totale de la mémoire. */ +static void g_block_list_finalize(GBlockList *); + + + +/* ---------------------------------------------------------------------------------- */ +/* MISE EN PLACE DES BLOCS BASIQUES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un bloc d'instructions basique. */ +G_DEFINE_TYPE(GBasicBlock, g_basic_block, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : class = classe à initialiser. * +* * +* Description : Initialise la classe des blocs d'instructions basique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_basic_block_class_init(GBasicBlockClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_basic_block_dispose; + object->finalize = (GObjectFinalizeFunc)g_basic_block_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : block = instance à initialiser. * +* * +* Description : Initialise un bloc d'instructions basique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_basic_block_init(GBasicBlock *block) +{ + block->rank = -1; + +} + + +/****************************************************************************** +* * +* Paramètres : block = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_basic_block_dispose(GBasicBlock *block) +{ + g_object_ref(G_OBJECT(block->first)); + g_object_ref(G_OBJECT(block->last)); + + G_OBJECT_CLASS(g_basic_block_parent_class)->dispose(G_OBJECT(block)); + +} + + +/****************************************************************************** +* * +* Paramètres : block = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_basic_block_finalize(GBasicBlock *block) +{ + G_OBJECT_CLASS(g_basic_block_parent_class)->finalize(G_OBJECT(block)); + +} + + +/****************************************************************************** +* * +* Paramètres : first = première instruction du bloc. * +* last = dernière instruction du bloc. * +* * +* Description : Crée un bloc basique d'exécution d'instructions. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBasicBlock *g_basic_block_new(GArchInstruction *first, GArchInstruction *last) +{ + GBasicBlock *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BASIC_BLOCK, NULL); + + result->first = first; + result->last = last; + + g_object_ref(G_OBJECT(result->first)); + g_object_ref(G_OBJECT(result->last)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc d'instructions à consulter. * +* first = instruction de départ du bloc. [OUT] * +* last = dernière instruction du bloc. [OUT] * +* * +* Description : Fournit les instructions limites d'un bloc basique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_basic_block_get_boundary(const GBasicBlock *block, GArchInstruction **first, GArchInstruction **last) +{ + if (first != NULL) + *first = block->first; + + if (last != NULL) + *last = block->last; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc d'instructions à consulter. * +* start = adresse de départ du bloc. [OUT] * +* end = dernière adresse du bloc. [OUT] * +* * +* Description : Fournit les adresses limites d'un bloc basique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_basic_block_get_boundary_addresses(const GBasicBlock *block, vmpa2t *start, vmpa2t *end) +{ + const mrange_t *range; /* Couverture d'instruction */ + + if (start != NULL) + { + range = g_arch_instruction_get_range(block->first); + copy_vmpa(start, get_mrange_addr(range)); + } + + if (end != NULL) + { + range = g_arch_instruction_get_range(block->last); + copy_vmpa(end, get_mrange_addr(range)); + } + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc d'instructions à consulter. * +* * +* Description : Fournit le rang du bloc basique dans le flot d'exécution. * +* * +* Retour : Indice supérieur ou égal à zéro. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int g_basic_block_get_rank(const GBasicBlock *block) +{ + return block->rank; + +} + + +/****************************************************************************** +* * +* Paramètres : block = bloc d'instructions à consulter. * +* rank = Indice supérieur à zéro à prendre en compte. * +* * +* Description : Définit le rang du bloc basique dans le flot d'exécution. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_basic_block_set_rank(GBasicBlock *block, unsigned int rank) +{ + block->rank = rank; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* REGROUPEMENT EN LISTE DE BLOCS */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une liste de blocs basiques. */ +G_DEFINE_TYPE(GBlockList, g_block_list, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : class = classe à initialiser. * +* * +* Description : Initialise la classe des listes de blocs basiques. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_block_list_class_init(GBlockListClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_block_list_dispose; + object->finalize = (GObjectFinalizeFunc)g_block_list_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : block = instance à initialiser. * +* * +* Description : Initialise une liste de blocs basiques. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_block_list_init(GBlockList *list) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : block = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_block_list_dispose(GBlockList *list) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < list->count; i++) + if (list->blocks[i] != NULL) + g_object_unref(G_OBJECT(list->blocks[i])); + + G_OBJECT_CLASS(g_block_list_parent_class)->dispose(G_OBJECT(list)); + +} + + +/****************************************************************************** +* * +* Paramètres : block = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_block_list_finalize(GBlockList *list) +{ + G_OBJECT_CLASS(g_block_list_parent_class)->finalize(G_OBJECT(list)); + +} + + +/****************************************************************************** +* * +* Paramètres : count = quantité finale de blocs présentie. * +* * +* Description : Crée une liste de blocs basiques. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBlockList *g_block_list_new(size_t count) +{ + GBlockList *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BASIC_BLOCK, NULL); + + result->blocks = (GBasicBlock **)calloc(count, sizeof(GBasicBlock *)); + + result->count = count; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs basiques à consulter. * +* * +* Description : Compte le nombre de blocs basiques représentés. * +* * +* Retour : Quantité de blocs basiques rassemblés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_block_list_count_blocks(const GBlockList *list) +{ + return list->count; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs basiques à compléter. * +* block = bloc d'instructions basique à intégrer. * +* index = indice de la position d'insertion du bloc. * +* * +* Description : Ajoute un bloc basique à une liste définie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_block_list_add_block(GBlockList *list, GBasicBlock *block, size_t index) +{ + assert(index < list->count); + assert(list->blocks[index] == NULL); + + list->blocks[index] = block; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs basiques à consulter. * +* index = indice de la position du bloc recherché. * +* * +* Description : Fournit un bloc basique à d'une liste définie. * +* * +* Retour : Bloc d'instructions basique trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBasicBlock *g_block_list_get_block(GBlockList *list, size_t index) +{ + assert(index < list->count); + + return list->blocks[index]; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de blocs basiques à consulter. * +* instr = instruction de début de bloc recherchée. * +* * +* Description : Recherche un bloc basique selon une première instruction. * +* * +* Retour : Bloc basique trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBasicBlock *g_block_list_find_by_starting_instr(const GBlockList *list, GArchInstruction *instr) +{ + GBasicBlock *result; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + GBasicBlock *block; /* Bloc basique analysé */ + GArchInstruction *first; /* Première instruction du bloc*/ + + result = NULL; + + for (i = 0; i < list->count && result == NULL; i++) + { + block = list->blocks[i]; + + g_basic_block_get_boundary(block, &first, NULL); + + if (instr == first) + result = block; + + } + + return result; + +} diff --git a/src/analysis/disass/block.h b/src/analysis/disass/block.h new file mode 100644 index 0000000..8d38976 --- /dev/null +++ b/src/analysis/disass/block.h @@ -0,0 +1,111 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * block.h - prototypes pour l'encadrement des instructions par blocs + * + * Copyright (C) 2012-2013 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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_DISASS_BLOCK_H +#define _ANALYSIS_DISASS_BLOCK_H + + +#include + + +#include "../../arch/instruction.h" + + + +/* ------------------------ MISE EN PLACE DES BLOCS BASIQUES ------------------------ */ + + +#define G_TYPE_BASIC_BLOCK g_basic_block_get_type() +#define G_BASIC_BLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_basic_block_get_type(), GBasicBlock)) +#define G_IS_BASIC_BLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_basic_block_get_type())) +#define G_BASIC_BLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_BLOCK, GBasicBlockClass)) +#define G_IS_BASIC_BLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_BLOCK)) +#define G_BASIC_BLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_BLOCK, GBasicBlockClass)) + + +/* Description d'un bloc basique d'instructions (instance) */ +typedef struct _GBasicBlock GBasicBlock; + +/* Description d'un bloc basique d'instructions (classe) */ +typedef struct _GBasicBlockClass GBasicBlockClass; + + +/* Indique le type défini pour un bloc d'instructions basique. */ +GType g_basic_block_get_type(void); + +/* Crée un bloc basique d'exécution d'instructions. */ +GBasicBlock *g_basic_block_new(GArchInstruction *, GArchInstruction *); + +/* Fournit les instructions limites d'un bloc basique. */ +void g_basic_block_get_boundary(const GBasicBlock *, GArchInstruction **, GArchInstruction **); + +/* Fournit les adresses limites d'un bloc basique. */ +void g_basic_block_get_boundary_addresses(const GBasicBlock *, vmpa2t *, vmpa2t *); + +/* Fournit le rang du bloc basique dans le flot d'exécution. */ +unsigned int g_basic_block_get_rank(const GBasicBlock *); + +/* Définit le rang du bloc basique dans le flot d'exécution. */ +void g_basic_block_set_rank(GBasicBlock *, unsigned int); + + + +/* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */ + + +#define G_TYPE_BLOCK_LIST g_block_list_get_type() +#define G_BLOCK_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_block_list_get_type(), GBasicBlock)) +#define G_IS_BLOCK_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_block_list_get_type())) +#define G_BLOCK_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BLOCK_LIST, GBasicBlockClass)) +#define G_IS_BLOCK_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BLOCK_LIST)) +#define G_BLOCK_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BLOCK_LIST, GBasicBlockClass)) + + +/* Description d'une liste de blocs basiques (instance) */ +typedef struct _GBlockList GBlockList; + +/* Description d'une liste de blocs basiques (classe) */ +typedef struct _GBlockListClass GBlockListClass; + + +/* Indique le type défini pour une liste de blocs basiques. */ +GType g_block_list_get_type(void); + +/* Crée une liste de blocs basiques. */ +GBlockList *g_block_list_new(size_t); + +/* Compte le nombre de blocs basiques représentés. */ +size_t g_block_list_count_blocks(const GBlockList *); + +/* Ajoute un bloc basique à une liste définie. */ +void g_block_list_add_block(GBlockList *, GBasicBlock *, size_t); + +/* Fournit un bloc basique à d'une liste définie. */ +GBasicBlock *g_block_list_get_block(GBlockList *, size_t ); + +/* Recherche un bloc basique selon une première instruction. */ +GBasicBlock *g_block_list_find_by_starting_instr(const GBlockList *, GArchInstruction *); + + + +#endif /* _ANALYSIS_DISASS_BLOCK_H */ diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c index 75b8bb7..98b1cd6 100644 --- a/src/analysis/disass/dragon.c +++ b/src/analysis/disass/dragon.c @@ -735,3 +735,47 @@ dragon_node *find_knight_node_for_instruction(const dragon_knight *knight, bool return result; } + + +/****************************************************************************** +* * +* Paramètres : knight = rassemblement des complexités de code. * +* * +* Description : Traduit une complexité de noeuds en liste de blocs basiques. * +* * +* Retour : Liste de blocs basiques créés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBlockList *translate_dragon_knight(const dragon_knight *knight) +{ + GBlockList *result; /* Liste à retourner */ + dragon_node *nodes; /* Liste des noeuds détectés */ + size_t count; /* Taille de cette liste */ + size_t i; /* Boucle de parcours */ + dragon_node *node; /* Noeud à traiter */ + GArchInstruction *first; /* Première instruction */ + GArchInstruction *last; /* Dernière instruction */ + GBasicBlock *block; /* Nouveau bloc basique */ + + get_dragon_knight_content(knight, &nodes, &count); + + result = g_block_list_new(count); + + for (i = 0; i < count; i++) + { + node = get_dragon_node(nodes, i); + + get_dragon_node_bounding_instructions(node, &first, &last); + + block = g_basic_block_new(first, last); + + g_block_list_add_block(result, block, i); + + } + + return result; + +} diff --git a/src/analysis/disass/dragon.h b/src/analysis/disass/dragon.h index 3449e6f..9e206f3 100644 --- a/src/analysis/disass/dragon.h +++ b/src/analysis/disass/dragon.h @@ -25,6 +25,7 @@ #define _ANALYSIS_DISASS_DRAGON_H +#include "block.h" #include "../../arch/processor.h" #include "../../common/bits.h" @@ -88,6 +89,9 @@ size_t get_dragon_knight_node_index(const dragon_knight *, dragon_node *); /* Recherche un noeud selon son intruction de départ. */ dragon_node *find_knight_node_for_instruction(const dragon_knight *, bool, const GArchInstruction *); +/* Traduit une complexité de noeuds en liste de blocs basiques. */ +GBlockList *translate_dragon_knight(const dragon_knight *); + #endif /* _ANALYSIS_DISASS_DRAGON_H */ diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 85d9e66..3694d04 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -24,6 +24,10 @@ #include "rank.h" + + +#if 0 + #include #include @@ -263,3 +267,127 @@ void rank_routine_blocks(GBinRoutine *routine) } + + + +#endif + + + + + + + +#include + + + +/* Classe les blocs basiques d'une routine. */ +void rank_routine_block(const GBlockList *, GBasicBlock *); + + + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de blocs basiques à traiter. * +* block = bloc d'analyse courant. * +* * +* Description : Classe les blocs basiques d'une routine. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void rank_routine_block(const GBlockList *list, GBasicBlock *block) +{ + unsigned int next; /* Rang suivant obtenu */ + GArchInstruction *last; /* Dernière instruction du bloc*/ + GArchInstruction **dests; /* Instr. visée par une autre */ + InstructionLinkType *types; /* Type de lien entre lignes */ + size_t dcount; /* Nombre de liens de dest. */ + size_t i; /* Boucle de parcours */ + GBasicBlock *target; /* Bloc ciblé par un lien */ + unsigned int rank; /* Rang à constituer */ + + next = g_basic_block_get_rank(block) + 1; + + g_basic_block_get_boundary(block, NULL, &last); + + g_arch_instruction_rlock_dest(last); + dcount = g_arch_instruction_get_destinations(last, &dests, &types, NULL); + + for (i = 0; i < dcount; i++) + { + /* La boucle de remontée n'abaisse pas les rangs */ + if (types[i] == ILT_LOOP) continue; + + target = g_block_list_find_by_starting_instr(list, dests[i]); + + /** + * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. + * Par exemple sous ARM : + * + * 00008358 : + * .... + * 8362: f7ff bfcf b.w 8304 <_init+0x38> + * .... + * + */ + + if (target != NULL) + { + rank = g_basic_block_get_rank(target); + + if (next > rank) + { + g_basic_block_set_rank(target, rank); + + rank_routine_block(list, target); + + } + + } + + } + + g_arch_instruction_runlock_dest(last); + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine regroupant les blocs à traiter. * +* * +* Description : Classe les blocs des routines. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void rank_routine_blocks(GBinRoutine *routine) +{ + GBlockList *blocks; /* Ensemble des blocs d'instr. */ + GBasicBlock *start; /* Bloc basique de départ */ + + blocks = g_binary_routine_get_basic_blocks(routine); + + start = g_block_list_get_block(blocks, 0 /* FIXME */); + assert(start != NULL); + + + + + rank_routine_block(blocks, start); + + + + + + +} diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c index de515d0..9f9c3b6 100644 --- a/src/analysis/disass/routines.c +++ b/src/analysis/disass/routines.c @@ -292,6 +292,7 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, size_t index) const vmpa2t *start; /* Adresse de départ */ const instr_coverage *coverage; /* Instructions couvertes */ dragon_knight *knight; /* Complexité de code posée */ + GBlockList *blocks; /* Liste de blocs basiques */ routine = study->routines[index]; @@ -320,7 +321,9 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, size_t index) detect_loops_in_code(knight); - group_routine_instructions(routine, knight); + blocks = translate_dragon_knight(knight); + + g_binary_routine_set_basic_blocks(routine, blocks); rank_routine_blocks(routine); diff --git a/src/analysis/routine.c b/src/analysis/routine.c index a91e53a..559b9bf 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -56,7 +56,7 @@ struct _GBinRoutine size_t locals_count; /* Nombre de variables locales */ GArchInstruction *instr; /* Instructions natives */ - GInstrBlock *blocks; /* Blocs basiques d'instruct° */ + GBlockList *blocks; /* Blocs basiques d'instruct° */ GDecInstruction *dinstr; /* Instructions décompilées */ }; @@ -757,7 +757,7 @@ void g_binary_routine_set_instructions(GBinRoutine *routine, GArchInstruction *i * * ******************************************************************************/ -GInstrBlock *g_binary_routine_get_basic_blocks(const GBinRoutine *routine) +GBlockList *g_binary_routine_get_basic_blocks(const GBinRoutine *routine) { return routine->blocks; @@ -777,7 +777,7 @@ GInstrBlock *g_binary_routine_get_basic_blocks(const GBinRoutine *routine) * * ******************************************************************************/ -void g_binary_routine_set_basic_blocks(GBinRoutine *routine, GInstrBlock *blocks) +void g_binary_routine_set_basic_blocks(GBinRoutine *routine, GBlockList *blocks) { if (routine->blocks != NULL) g_object_unref(G_OBJECT(routine->blocks)); diff --git a/src/analysis/routine.h b/src/analysis/routine.h index 177547b..9ee2c2f 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -30,8 +30,8 @@ #include -#include "block.h" #include "variable.h" +#include "disass/block.h" //#include "../arch/instruction.h" #include "../decomp/instruction.h" @@ -164,10 +164,10 @@ GArchInstruction *g_binary_routine_get_instructions(const GBinRoutine *); void g_binary_routine_set_instructions(GBinRoutine *, GArchInstruction *); /* Fournit les blocs basiques de la routine. */ -GInstrBlock *g_binary_routine_get_basic_blocks(const GBinRoutine *); +GBlockList *g_binary_routine_get_basic_blocks(const GBinRoutine *); /* Définit les blocs basiques de la routine. */ -void g_binary_routine_set_basic_blocks(GBinRoutine *, GInstrBlock *); +void g_binary_routine_set_basic_blocks(GBinRoutine *, GBlockList *); /* Fournit les instructions décompilées correspondantes. */ GDecInstruction *g_binary_routine_get_decomp_instructions(const GBinRoutine *); -- cgit v0.11.2-87-g4458