/* Chrysalide - Outil d'analyse de fichiers binaires
* limit.c - détermination des bornes des routines
*
* 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 "limit.h"
#include
/* Recherche la zone correspond à une adresse donnée. */
static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *);
/******************************************************************************
* *
* Paramètres : ranges = liste de zones offrant une exécution et disponibles.*
* count = taille de cette liste. *
* *
* Description : Recherche la zone correspond à une adresse donnée. *
* *
* Retour : Zone trouvée ou NULL si aucune ne correspond. *
* *
* Remarques : - *
* *
******************************************************************************/
static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t count, const vmpa2t *addr)
{
const mrange_t *result; /* Zone à retourner */
size_t i; /* Boucle de parcours */
result = NULL;
for (i = 0; i < count && result == NULL; i++)
if (mrange_contains_addr(&ranges[i], addr))
result = &ranges[i];
return result;
}
/******************************************************************************
* *
* Paramètres : format = format du binaire concerné par la procédure. *
* proc = 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(GExeFormat *format, const GArchProcessor *proc, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
mrange_t *exe_ranges; /* Liste de zones exécutables */
size_t exe_count; /* Nombre de ces zones */
size_t i; /* Boucle de parcours */
const mrange_t *range; /* Emplacement courant */
vmpa2t addr; /* Adresse à conserver */
GArchInstruction *start; /* Première instruction */
phys_t diff; /* Taille définie par déduction*/
mrange_t new; /* Nouvel emplacement taillé */
exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
for (i = 0; i < count; i++)
{
//gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count);
range = g_binary_routine_get_range(routines[i]);
if (get_mrange_length(range) > 0) continue;
copy_vmpa(&addr, get_mrange_addr(range));
/* Marquage de la première instruction */
start = g_arch_processor_find_instr_by_address(proc, &addr);
g_arch_instruction_set_flag(start, AIF_ROUTINE_START);
/* Si on peut se raccrocher à la routine suivante... */
if ((i + 1) < count)
{
range = g_binary_routine_get_range(routines[i + 1]);
diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
}
/* Sinon on va jusqu'à la fin de la zone ! */
else
{
range = find_x_range_for_addr(exe_ranges, exe_count, &addr);
if (range == NULL) continue;
diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
diff = get_mrange_length(range) - diff;
}
init_mrange(&new, &addr, diff);
g_binary_routine_set_range(routines[i], &new);
}
if (exe_ranges != NULL)
free(exe_ranges);
do
{
const mrange_t *_range;
vmpa2t _end;
printf("LIMIT == %zu routines\n", count);
for (i = 0; i < count; i++)
{
_range = g_binary_routine_get_range(routines[i]);
compute_mrange_end_addr(_range, &_end);
printf(" 0x%08x <-> 0x%08x '%s'\n",
(unsigned int)((get_mrange_addr(_range))->virtual),
(unsigned int)_end.virtual,
g_binary_routine_to_string(routines[i]));
}
} while (0);
}