diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 11:11:00 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 11:11:00 (GMT) |
commit | 24731773b654f40cb1d59c3da5216a3be90e2d6f (patch) | |
tree | 71395d91b57da3a769f43e86dc808097783b9e08 /src/analysis/blocks/flow.c | |
parent | 932ea7c83c07d3982fee605c6dd9895fd2753874 (diff) |
Deleted old code.
Diffstat (limited to 'src/analysis/blocks/flow.c')
-rw-r--r-- | src/analysis/blocks/flow.c | 711 |
1 files changed, 0 insertions, 711 deletions
diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c deleted file mode 100644 index 041a134..0000000 --- a/src/analysis/blocks/flow.c +++ /dev/null @@ -1,711 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * flow.c - encadrement des instructions par blocs d'exécution - * - * Copyright (C) 2012-2013 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 "flow.h" - - -#include <malloc.h> -#include <sys/param.h> - - -#include "../block-int.h" - - - -/* Description d'un bloc d'exécution d'instructions (instance) */ -struct _GFlowBlock -{ - GInstrBlock parent; /* A laisser en premier */ - - unsigned int rank; /* Rang dans l'exécution */ - unsigned int next_rank; /* Rang suivant de l'exécution */ - - GArchProcessor *proc; /* Liste complète d'instruct° */ - GArchInstruction *first; /* Première instruction */ - GArchInstruction *last; /* Dernière instruction */ - - GRAccessList *regs; /* Accès aux registres */ - GRAccessList *awaited; /* Registres définis pour après*/ - -}; - -/* Description d'un bloc d'exécution d'instructions (classe) */ -struct _GFlowBlockClass -{ - GInstrBlockClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des blocs d'instructions. */ -static void g_flow_block_class_init(GFlowBlockClass *); - -/* Initialise un bloc d'instructions. */ -static void g_flow_block_init(GFlowBlock *); - -/* Supprime toutes les références externes. */ -static void g_flow_block_dispose(GFlowBlock *); - -/* Procède à la libération totale de la mémoire. */ -static void g_flow_block_finalize(GFlowBlock *); - -/* Recherche le bloc contenant une adresse donnée. */ -static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *, const vmpa2t *, bool); - -/* Parcourt le bloc d'instructions dans un ordre donné. */ -static bool g_flow_block_visit(GFlowBlock *, instr_block_visitor_cb, void *); - -/* Etablit la liste de tous les blocs présents. */ -static void g_flow_block_list_all_blocks(const GFlowBlock *, GInstrBlock ***, size_t *); - -/* Etablit la liste de tous les blocs terminaux. */ -static void g_flow_block_list_leafs_blocks(const GFlowBlock *, GInstrBlock ***, size_t *); - -/* Prend note de l'usage d'un registre, au besoin. */ -static void g_flow_block_memorize_access(GFlowBlock *, GArchRegister *, RegAccessType, vmpa_t); - -/* Note les différents accès aux registres. */ -static void g_flow_block_compute_regs_access(GFlowBlock *); - -/* Fournit les différents accès aux registres. */ -//static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *, size_t *); - - - -/* Indique le type défini pour un bloc d'exécution d'instructions. */ -G_DEFINE_TYPE(GFlowBlock, g_flow_block, G_TYPE_INSTR_BLOCK); - - -/****************************************************************************** -* * -* Paramètres : class = classe à initialiser. * -* * -* Description : Initialise la classe des blocs d'instructions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_class_init(GFlowBlockClass *class) -{ - GObjectClass *object; /* Autre version de la classe */ - GInstrBlockClass *block_class; /* Version parente du la classe*/ - - object = G_OBJECT_CLASS(class); - block_class = G_INSTR_BLOCK_CLASS(class); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_flow_block_dispose; - object->finalize = (GObjectFinalizeFunc)g_flow_block_finalize; - - block_class->find_by_addr = (find_by_addr_fc)g_flow_block_find_by_addr; - block_class->visit_blocks = (visit_all_blocks_fc)g_flow_block_visit; - block_class->list_blocks = (list_all_blocks_fc)g_flow_block_list_all_blocks; - block_class->list_leafs = (list_leafs_blocks_fc)g_flow_block_list_leafs_blocks; - //block_class->list_regs = (list_regs_accesses_fc)g_flow_block_list_regs_accesses; - -} - - -/****************************************************************************** -* * -* Paramètres : block = instance à initialiser. * -* * -* Description : Initialise un bloc d'instructions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_init(GFlowBlock *block) -{ - g_flow_block_set_rank(block, 0); - - block->regs = g_raccess_list_new(); - block->awaited = g_raccess_list_new(); - -} - - -/****************************************************************************** -* * -* Paramètres : block = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_dispose(GFlowBlock *block) -{ - //g_object_unref(G_OBJECT(block->proc)); - g_object_unref(G_OBJECT(block->first)); - g_object_unref(G_OBJECT(block->last)); - - g_object_unref(G_OBJECT(block->regs)); - g_object_unref(G_OBJECT(block->awaited)); - - G_OBJECT_CLASS(g_flow_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_flow_block_finalize(GFlowBlock *block) -{ - G_OBJECT_CLASS(g_flow_block_parent_class)->finalize(G_OBJECT(block)); - -} - - -/****************************************************************************** -* * -* Paramètres : proc = liste de toutes les instructions. * -* first = première instruction du bloc. * -* last = dernière instruction du bloc. * -* * -* Description : Crée un bloc d'exécution d'instructions. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GInstrBlock *g_flow_block_new(GArchProcessor *proc, GArchInstruction *first, GArchInstruction *last) -{ - GFlowBlock *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_FLOW_BLOCK, NULL); - - /* FIXME : proc non utilisé ! */ - - result->proc = proc; - result->first = first; - result->last = last; - - //g_object_ref(G_OBJECT(result->proc)); - g_object_ref(G_OBJECT(result->first)); - g_object_ref(G_OBJECT(result->last)); - - //g_flow_block_compute_regs_access(result); - - return G_INSTR_BLOCK(result); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instruction à consulter. * -* * -* Description : Fournit le rang du bloc dans le flot d'exécution. * -* * -* Retour : Indice supérieur ou égal à zéro. * -* * -* Remarques : - * -* * -******************************************************************************/ - -unsigned int g_flow_block_get_rank(const GFlowBlock *block) -{ - return block->rank; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instruction à consulter. * -* rank = Indice supérieur à zéro à prendre en compte. * -* * -* Description : Définit le rang du bloc dans le flot d'exécution. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_flow_block_set_rank(GFlowBlock *block, unsigned int rank) -{ - block->rank = rank; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc de départ des recherches. * -* addr = ensemble de blocs à parcourir. * -* final = indique si la cible ou le conteneur est renvoyée. * -* * -* Description : Recherche le bloc contenant une adresse donnée. * -* * -* Retour : bloc basique trouvé ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *block, const vmpa2t *addr, bool final) -{ - GInstrBlock *result; /* Resultat à retourner */ - vmpa2t start; /* Adresse de début du bloc */ - vmpa2t end; /* Adresse de fin du bloc */ - mrange_t range; /* Couverture globale */ - - g_flow_block_get_boundary_addresses(block, &start, &end); - - init_mrange(&range, &start, compute_vmpa_diff(&start, &end)); - - if (mrange_contains_addr(&range, addr)) - result = G_INSTR_BLOCK(block); - - else - result = NULL; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions concerné par la visite. * -* callback = ensemble de blocs à parcourir. * -* data = donnée utilisateur à associer au parcours. * -* * -* Description : Parcourt le bloc d'instructions dans un ordre donné. * -* * -* Retour : true si le parcours a été jusqu'à son terme, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_flow_block_visit(GFlowBlock *block, instr_block_visitor_cb callback, void *data) -{ - return callback(G_INSTR_BLOCK(block), BVO_PENDING, data); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à consulter. * -* list = ensemble de blocs à compléter. [OUT] * -* count = nombre de blocs au total. [OUT] * -* * -* Description : Etablit la liste de tous les blocs présents. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_list_all_blocks(const GFlowBlock *block, GInstrBlock ***list, size_t *count) -{ - (*list) = (GInstrBlock **)realloc(*list, ++(*count) * sizeof(GInstrBlock *)); - - (*list)[*count - 1] = G_INSTR_BLOCK(block); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à consulter. * -* list = ensemble de blocs à compléter. [OUT] * -* count = nombre de blocs au total. [OUT] * -* * -* Description : Etablit la liste de tous les blocs terminaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_list_leafs_blocks(const GFlowBlock *block, GInstrBlock ***list, size_t *count) -{ - (*list) = (GInstrBlock **)realloc(*list, ++(*count) * sizeof(GInstrBlock *)); - - (*list)[*count - 1] = G_INSTR_BLOCK(block); - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à mettre à jour. * -* reg = registre visé par l'opération. * -* type = type d'accès à l'opérande. * -* addr = adresse de l'instruction associée. * -* * -* Description : Prend note de l'usage d'un registre, au besoin. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_memorize_access(GFlowBlock *block, GArchRegister *reg, RegAccessType type, vmpa_t addr) -{ - reg_access *found; /* Accès à mettre à jour */ - reg_access access; /* Accès à mettre en place */ - - found = g_raccess_list_find(block->regs, reg); - - /* Simpple mise à jour ? */ - if (found != NULL) - { - if (type == RAT_WRITE) - found->last_write = addr; - } - - /* Ou ajout pur et simple ? */ - else - { - access.reg = reg; - access.first_access = type; - access.last_write = (type == RAT_WRITE ? addr : VMPA_MAX); - - g_raccess_list_add(block->regs, &access); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à parcourir. * -* * -* Description : Note les différents accès aux registres. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_flow_block_compute_regs_access(GFlowBlock *block) -{ - GArchInstruction *iter; /* Boucle de parcours #1 */ - vmpa_t max; /* Adresse de fin */ - vmpa_t addr; /* Adresse d'instruction */ - GArchRegister **rregs; /* Liste des registres lus */ - size_t rcount; /* Nombre de registres lus */ - GArchRegister **wregs; /* Liste des registres écrits */ - size_t wcount; /* Nombre de registres écrits */ - size_t i; /* Boucle de parcours #2 */ - - g_arch_instruction_get_location(block->last, NULL, NULL, &max); - max++; - - for (iter = block->first; - iter != NULL; - iter = NULL/* FIXME g_arch_instruction_get_next_iter(block->instrs, iter, max)*/) - { - g_arch_instruction_get_location(iter, NULL, NULL, &addr); - - g_arch_instruction_get_rw_registers(iter, &rregs, &rcount, &wregs, &wcount); - - for (i = 0; i < rcount; i++) - { - g_flow_block_memorize_access(block, rregs[i], RAT_READ, addr); - g_object_unref(G_OBJECT(rregs[i])); - } - - for (i = 0; i < wcount; i++) - { - g_flow_block_memorize_access(block, wregs[i], RAT_WRITE, addr); - g_object_unref(G_OBJECT(wregs[i])); - } - - if (rregs != NULL) free(rregs); - if (wregs != NULL) free(wregs); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à consulter. * -* * -* Description : Donne le processeur d'appartenance des instructions du bloc. * -* * -* Retour : Liste de l'ensemble des instructions. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchProcessor *g_flow_block_get_processor(const GFlowBlock *block) -{ - return block->proc; - -} - - -/****************************************************************************** -* * -* 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 d'exécution. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_flow_block_get_boundary(const GFlowBlock *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 d'exécution. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_flow_block_get_boundary_addresses(const GFlowBlock *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 démarrant la visite. * -* list = ensemble des blocs basiques à parcourir. * -* target = bloc de fin de parcours. * -* * -* Description : Détermine si un bloc peut conduire à un autre. * -* * -* Retour : true si un lien existe entre les deux blocs fournis. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_flow_block_is_looping_to(GFlowBlock *block, const GInstrBlock *list, GFlowBlock *target) -{ - bool result; /* Bilan à retourner */ - instr_link_t *dests; /* Instr. visées par une autre */ - size_t dcount; /* Nombre de liens de dest. */ - size_t i; /* Boucle de parcours */ - vmpa_t addr; /* Adresse de la destination */ - GInstrBlock *next; /* Bloc suivant à visiter */ - - result = (block == target); - - g_arch_instruction_rlock_dest(block->last); - dcount = g_arch_instruction_get_destinations(block->last, &dests); - - for (i = 0; i < dcount && !result; i++) - switch (dests[i].type) - { - case ILT_EXEC_FLOW: - case ILT_JUMP: - case ILT_CASE_JUMP: - case ILT_JUMP_IF_TRUE: - case ILT_JUMP_IF_FALSE: - g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - result = g_flow_block_is_looping_to(G_FLOW_BLOCK(next), list, target); - break; - - case ILT_LOOP: - g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - result = (G_FLOW_BLOCK(next) == target); - default: - break; - - } - - g_arch_instruction_runlock_dest(block->last); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions démarrant la visite. * -* list = ensemble des blocs basiques à parcourir. * -* mask = points de passage à marquer. * -* callback = ensemble de blocs à parcourir. * -* data = donnée utilisateur à associer au parcours. * -* * -* Description : Suit le flot d'excution bloc par bloc. * -* * -* Retour : true si le parcours a été jusqu'à son terme, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollowPosition mask, flow_block_follow_cb callback, void *data) -{ - bool result; /* Bilan à retourner */ - instr_link_t *dests; /* Instr. visées par une autre */ - size_t dcount; /* Nombre de liens de dest. */ - size_t i; /* Boucle de parcours */ - vmpa_t addr; /* Adresse de la destination */ - GInstrBlock *next; /* Bloc suivant à visiter */ - - result = true; - - if (mask & BFP_ENTER) - result = callback(block, BFP_ENTER, data); - - g_arch_instruction_rlock_dest(block->last); - dcount = g_arch_instruction_get_destinations(block->last, &dests); - - for (i = 0; i < dcount && result; i++) - switch (dests[i].type) - { - case ILT_EXEC_FLOW: - case ILT_JUMP: - case ILT_CASE_JUMP: - case ILT_JUMP_IF_TRUE: - case ILT_JUMP_IF_FALSE: - - g_arch_instruction_get_location(dests[i].linked, NULL, NULL, &addr); - next = g_instr_block_find_by_addr(list, addr, true); - - if (next) - { - result = callback(block, BFP_FOLLOW, data); - result &= g_flow_block_follow(G_FLOW_BLOCK(next), list, mask, callback, data); - result &= callback(block, BFP_BACK, data); - } - break; - - default: - break; - - } - - g_arch_instruction_runlock_dest(block->last); - - if (mask & BFP_EXIT) - result &= callback(block, BFP_EXIT, data); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à consulter. * -* * -* Description : Fournit les différents accès aux registres. * -* * -* Retour : Liste des accès aux registres. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const GRAccessList *g_flow_block_list_regs_accesses(const GFlowBlock *block) -{ - return block->regs; - -} - - -/****************************************************************************** -* * -* Paramètres : block = bloc d'instructions à consulter. * -* * -* Description : Fournit les registres écrits par le bloc et utilisées après. * -* * -* Retour : Liste des accès aux registres. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GRAccessList *g_flow_block_list_awaited_regs(const GFlowBlock *block) -{ - return block->awaited; - -} |