/* Chrysalide - Outil d'analyse de fichiers binaires * routines.c - étude des flots d'exécution dans les routines * * Copyright (C) 2016 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 "routines.h" #include "dragon.h" #include "loop.h" #include "macro.h" #include "rank.h" #include "../../glibext/delayed-int.h" /* Fraction de routines à limiter (instance) */ struct _GRoutinesStudy { GDelayedWork parent; /* A laisser en premier */ const GArchProcessor *proc; /* Processeurs avec ses instr. */ mrange_t *exe_ranges; /* Liste de zones exécutables */ size_t exe_count; /* Nombre de ces zones */ GBinRoutine **routines; /* Liste de routines à traiter */ size_t count; /* Taille de cette liste */ size_t begin; /* Point de départ du parcours */ size_t end; /* Point d'arrivée exclu */ activity_id_t id; /* Identifiant pour messages */ }; /* Fraction de routines à limiter (classe) */ struct _GRoutinesStudyClass { GDelayedWorkClass parent; /* A laisser en premier */ }; /* Indique le type défini pour les tâches d'étude de routines. */ GType g_routines_study_get_type(void); /* Initialise la classe des tâches d'étude de routines. */ static void g_routines_study_class_init(GRoutinesStudyClass *); /* Initialise une tâche d'étude de routines. */ static void g_routines_study_init(GRoutinesStudy *); /* Supprime toutes les références externes. */ static void g_routines_study_dispose(GRoutinesStudy *); /* Procède à la libération totale de la mémoire. */ static void g_routines_study_finalize(GRoutinesStudy *); /* Assure l'étude des routines en différé. */ static void g_routines_study_process(GRoutinesStudy *, GtkStatusStack *); /* Indique le type défini pour les tâches d'étude de routines. */ G_DEFINE_TYPE(GRoutinesStudy, g_routines_study, G_TYPE_DELAYED_WORK); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des tâches d'étude de routines. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_routines_study_class_init(GRoutinesStudyClass *klass) { GObjectClass *object; /* Autre version de la classe */ GDelayedWorkClass *work; /* Version en classe parente */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_routines_study_dispose; object->finalize = (GObjectFinalizeFunc)g_routines_study_finalize; work = G_DELAYED_WORK_CLASS(klass); work->run = (run_task_fc)g_routines_study_process; } /****************************************************************************** * * * Paramètres : computing = instance à initialiser. * * * * Description : Initialise une tâche d'étude de routines. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_routines_study_init(GRoutinesStudy *study) { } /****************************************************************************** * * * Paramètres : computing = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_routines_study_dispose(GRoutinesStudy *computing) { G_OBJECT_CLASS(g_routines_study_parent_class)->dispose(G_OBJECT(computing)); } /****************************************************************************** * * * Paramètres : computing = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_routines_study_finalize(GRoutinesStudy *computing) { G_OBJECT_CLASS(g_routines_study_parent_class)->finalize(G_OBJECT(computing)); } /****************************************************************************** * * * Paramètres : proc = ensemble d'instructions désassemblées. * * routines = prototypes existants à insérer. * * count = quantité de ces prototypes. * * begin = point de départ du parcours de liste. * * end = point d'arrivée exclu du parcours. * * id = identifiant du message affiché à l'utilisateur. * * * * Description : Crée une tâche d'étude de routines différée. * * * * Retour : Tâche créée. * * * * Remarques : - * * * ******************************************************************************/ GRoutinesStudy *g_routines_study_new(const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id) { GRoutinesStudy *result; /* Tâche à retourner */ result = g_object_new(G_TYPE_ROUTINES_STUDY, NULL); result->proc = proc; result->exe_ranges = exe_ranges; result->exe_count = exe_count; result->routines = routines; result->count = count; result->begin = begin; result->end = end; result->id = id; return result; } /****************************************************************************** * * * Paramètres : study = étude de routines à mener. * * status = barre de statut à tenir informée. * * * * Description : Assure l'étude des routines en différé. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_routines_study_process(GRoutinesStudy *study, GtkStatusStack *status) { size_t i; /* Boucle de parcours */ GBinRoutine *routine; /* Routine en traitement */ const mrange_t *range; /* Couverture d'une routine */ const vmpa2t *start; /* Adresse de départ */ const instr_coverage *coverage; /* Instructions couvertes */ dragon_knight *knight; /* Complexité de code posée */ //dragon_node *nodes; /* Liste des noeuds détectés */ //size_t count; /* Taille de cette liste */ for (i = study->begin; i < study->end; i++) { //gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); routine = study->routines[i]; /* Préparatifs communs */ range = g_binary_routine_get_range(routine); start = get_mrange_addr(range); coverage = g_arch_processor_find_coverage_by_address(study->proc, start); knight = begin_dragon_knight(study->proc, coverage, range, start); detect_loops_in_code(knight); /* Phase AAAA : regroupement des instructions par blocs */ group_routine_instructions(routine, knight); rank_routine_blocks(routine); /* Nettoyage final */ end_dragon_knight(knight); } }