From 3293a5b3b13271ea1499718d310c1bd0284762a3 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 1 Apr 2015 21:45:29 +0000 Subject: Fixed the definition of inner blocks by cutting at the right starting position. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@498 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 22 ++++++++++ src/analysis/disass/macro.c | 83 ++++++++++++++++++++++++++++++++++---- src/arch/arm/Makefile.am | 1 + src/arch/arm/instruction.c | 1 + src/arch/arm/link.c | 65 +++++++++++++++++++++++++++++ src/arch/arm/link.h | 39 ++++++++++++++++++ src/arch/arm/v7/opdefs/Makefile.am | 2 +- src/arch/arm/v7/opdefs/b_A8818.d | 10 ++--- 8 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 src/arch/arm/link.c create mode 100644 src/arch/arm/link.h diff --git a/ChangeLog b/ChangeLog index 0d4288c..cbc0d57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,27 @@ 15-04-01 Cyrille Bagard + * src/analysis/disass/macro.c: + Fix the definition of inner blocks by cutting at the right starting + position. Fix the final debug output. + + * src/arch/arm/instruction.c: + Define the default execution condition for ARM instructions. + + * src/arch/arm/link.c: + * src/arch/arm/link.h: + New entries: select jumps or branchs depending on current conditions. + + * src/arch/arm/Makefile.am: + Add the 'link.[ch]' files to libarcharm_la_SOURCES. + + * src/arch/arm/v7/opdefs/b_A8818.d: + Update definitions. + + * src/arch/arm/v7/opdefs/Makefile.am: + Update included headers. + +15-04-01 Cyrille Bagard + * src/analysis/disass/area.c: Update code by changing IPH_LINK to IPH_FETCH. diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 087f1ae..75032fa 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -42,6 +42,8 @@ typedef struct _code_coverage { mrange_t range; /* Couverture totale */ + vmpa2t start; /* Position butoir de début */ + vmpa2t *ends; /* Positions butoir de fin */ size_t ends_count; /* Quantité de fins possibles */ @@ -60,6 +62,9 @@ static code_coverage *dup_code_coverage(const code_coverage *, const vmpa2t *); /* Détruit des délimitations d'une zone de code. */ static void delete_code_coverage(code_coverage *); +/* Précise la position de départ courante pour une analyse. */ +static const vmpa2t *get_code_coverage_start_addr(const code_coverage *); + /* Indique si une adresse est hors zone ou non. */ static bool code_coverage_stop_here(const code_coverage *coverage, const vmpa2t *); @@ -83,6 +88,8 @@ typedef struct _branch_info vmpa2t *hops; /* Jalons de la branche */ size_t count; /* Quantité de ces jalons */ + vmpa2t entry; /* Valeur du jalon d'entrée */ + } branch_info; @@ -98,6 +105,9 @@ static bool is_addr_in_branch(const branch_info *, const vmpa2t *); /* Ajoute un nouveau jalon dans l'exécution d'une branche. */ static bool add_hop_into_branch(branch_info *, const vmpa2t *); +/* Retourne le premier point d'exécution d'une branche donnée. */ +static const vmpa2t *get_entry_to_branch(const branch_info *); + /* Identifie les différents points de passage d'une branche. */ static void find_next_hops(GArchInstruction *, const vmpa2t *, const code_coverage *, branch_info *); @@ -201,6 +211,8 @@ static code_coverage *create_code_coverage(const mrange_t *range) copy_mrange(&result->range, range); + copy_vmpa(&result->start, get_mrange_addr(range)); + result->ends = (vmpa2t *)calloc(1, sizeof(vmpa2t)); result->ends_count = 1; @@ -241,6 +253,8 @@ static code_coverage *dup_code_coverage(const code_coverage *src, const vmpa2t * copy_mrange(&result->range, &src->range); + copy_vmpa(&result->start, new); + result->ends = (vmpa2t *)calloc(src->ends_count, sizeof(vmpa2t)); result->ends_count = src->ends_count; @@ -283,6 +297,25 @@ static void delete_code_coverage(code_coverage *coverage) /****************************************************************************** * * * Paramètres : coverage = informations de couverture à consulter. * +* * +* Description : Précise la position de départ courante pour une analyse. * +* * +* Retour : Position de départ pour une analyse d'une portion de zone. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const vmpa2t *get_code_coverage_start_addr(const code_coverage *coverage) +{ + return &coverage->start; + +} + + +/****************************************************************************** +* * +* Paramètres : coverage = informations de couverture à consulter. * * addr = localisation à tester. * * * * Description : Indique si une adresse est hors zone ou non. * @@ -499,6 +532,9 @@ static bool add_hop_into_branch(branch_info *info, const vmpa2t *addr) if (result) { + if (info->count == 0) + copy_vmpa(&info->entry, addr); + info->hops = (vmpa2t *)realloc(info->hops, ++info->count * sizeof(vmpa2t)); copy_vmpa(&info->hops[info->count - 1], addr); @@ -514,6 +550,25 @@ static bool add_hop_into_branch(branch_info *info, const vmpa2t *addr) /****************************************************************************** * * +* Paramètres : info = informations de flot à consulter. * +* * +* Description : Retourne le premier point d'exécution d'une branche donnée. * +* * +* Retour : Point de départ d'une branche. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const vmpa2t *get_entry_to_branch(const branch_info *info) +{ + return &info->entry; + +} + + +/****************************************************************************** +* * * Paramètres : instrs = ensemble des instructions d'assemblage. * * start = position du début de bloc. * * coverage = liste des adresses de fin butoir. * @@ -874,12 +929,12 @@ static GInstrBlock *build_instruction_blocks_case(GArchInstruction *instrs, code for (i = 0; i < cases->count; i++) { - sub_coverage = dup_code_coverage(coverage, &cases->branches[i].hops[0]); + sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(&cases->branches[i])); add_ending_address_code_coverage(sub_coverage, next); for (j = 0; j < cases->count; j++) - add_ending_address_code_coverage(sub_coverage, &cases->branches[j].hops[0]); + add_ending_address_code_coverage(sub_coverage, get_entry_to_branch(&cases->branches[j])); block = build_instruction_blocks(instrs, sub_coverage); @@ -942,12 +997,12 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ if (br0->count > 0) { - sub_coverage = dup_code_coverage(coverage, &br0->hops[0]); + sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(br0)); add_ending_address_code_coverage(sub_coverage, next); if (br1->count > 0) - add_ending_address_code_coverage(sub_coverage, &br1->hops[0]); + add_ending_address_code_coverage(sub_coverage, get_entry_to_branch(br1)); result = build_instruction_blocks(instrs, sub_coverage); @@ -963,6 +1018,8 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ block = build_instr_block_bi(instrs, coverage, true_branch, false_branch, next); + printf("===> TRUE_BRANCH = %p\n", block); + if (block != NULL) g_virtual_block_add_child(G_VIRTUAL_BLOCK(result), block); @@ -970,6 +1027,8 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_ block = build_instr_block_bi(instrs, coverage, false_branch, true_branch, next); + printf("===> FALSE_BRANCH = %p\n", block); + if (block != NULL) g_virtual_block_add_child(G_VIRTUAL_BLOCK(result), block); @@ -1016,7 +1075,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca has_stop = compute_first_common_addr(main_branch, &exceptions->branches[i], &stop_addr); if (!has_stop) continue; - sub_coverage = dup_code_coverage(coverage, &exceptions->branches[i].hops[0]); + sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(&exceptions->branches[i])); add_ending_address_code_coverage(sub_coverage, &stop_addr); block = build_instruction_blocks(instrs, sub_coverage); @@ -1075,9 +1134,17 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove last = NULL; init_branch_info(&main_branch); - find_next_hops(instrs, get_mrange_addr(&coverage->range), coverage, &main_branch); + find_next_hops(instrs, get_code_coverage_start_addr(coverage), coverage, &main_branch); + + + printf("//////////////////////////\n"); + printf("/// Cutting for 0x%08x -> %p\n", + get_code_coverage_start_addr(coverage)->virtual, + g_arch_instruction_find_by_address(instrs, get_code_coverage_start_addr(coverage), true)); + printf("//////////////////////////\n"); + - for (iter = g_arch_instruction_find_by_address(instrs, get_mrange_addr(&coverage->range), true); + for (iter = g_arch_instruction_find_by_address(instrs, get_code_coverage_start_addr(coverage), true); iter != NULL; ) { @@ -1347,7 +1414,7 @@ void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, break; case BVO_OUT: - (*indent)++; + (*indent)--; break; } diff --git a/src/arch/arm/Makefile.am b/src/arch/arm/Makefile.am index 0fde813..c0bbdf7 100644 --- a/src/arch/arm/Makefile.am +++ b/src/arch/arm/Makefile.am @@ -7,6 +7,7 @@ libarcharm_la_SOURCES = \ context.h context.c \ instruction-int.h \ instruction.h instruction.c \ + link.h link.c \ processor.h processor.c \ register-int.h \ register.h register.c diff --git a/src/arch/arm/instruction.c b/src/arch/arm/instruction.c index 6ce115c..47c9b4b 100644 --- a/src/arch/arm/instruction.c +++ b/src/arch/arm/instruction.c @@ -95,6 +95,7 @@ static void g_arm_instruction_class_init(GArmInstructionClass *klass) static void g_arm_instruction_init(GArmInstruction *instr) { + instr->cond = ACC_AL; } diff --git a/src/arch/arm/link.c b/src/arch/arm/link.c new file mode 100644 index 0000000..c0f1f54 --- /dev/null +++ b/src/arch/arm/link.c @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * link.c - édition des liens après la phase de désassemblage ARM + * + * Copyright (C) 2015 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 "link.h" + + +#include "cond.h" +#include "instruction.h" +#include "../link.h" + + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARM à traiter. * +* proc = représentation de l'architecture utilisée. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* * +* Description : Etablit un lien conditionnel selon une instruction donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void handle_arm_conditional_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ + switch (g_arm_instruction_get_cond(G_ARM_INSTRUCTION(instr))) + { + case ACC_AL: + handle_jump_as_link(instr, proc, context, format); + break; + + case ACC_NV: + break; + + default: + handle_branch_if_true_as_link(instr, proc, context, format); + break; + + } + +} diff --git a/src/arch/arm/link.h b/src/arch/arm/link.h new file mode 100644 index 0000000..7529dc4 --- /dev/null +++ b/src/arch/arm/link.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * link.h - prototypes pour l'édition des liens après la phase de désassemblage ARM + * + * Copyright (C) 2015 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 _ARCH_ARM_LINK_H +#define _ARCH_ARM_LINK_H + + +#include "../instruction.h" +#include "../processor.h" +#include "../../format/format.h" + + + +/* Etablit un lien conditionnel selon une instruction donnée. */ +void handle_arm_conditional_branch_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); + + + +#endif /* _ARCH_ARM_LINK_H */ diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index b95b588..b897f1d 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -106,7 +106,7 @@ fmk.done: $(ARMV7_DEFS) fix_includes_in_c_templates: @for f in `find .gen/ -name '*tmpl.c'`; do \ if grep -q '##INCLUDES##' $$f; then \ - $(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/fetch.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/link.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f; \ + $(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/fetch.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/link.h"\n#include "..\/..\/..\/link.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f; \ fi; \ done diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d index a275177..f06367b 100644 --- a/src/arch/arm/v7/opdefs/b_A8818.d +++ b/src/arch/arm/v7/opdefs/b_A8818.d @@ -39,7 +39,7 @@ @hooks { fetch = help_fetching_with_instruction_b_from_thumb - link = handle_branch_if_true_as_link + link = handle_arm_conditional_branch_as_link post = post_process_branch_instructions } @@ -69,7 +69,7 @@ @hooks { fetch = help_fetching_with_instruction_b_from_thumb - link = handle_branch_if_true_as_link + link = handle_arm_conditional_branch_as_link post = post_process_branch_instructions } @@ -99,7 +99,7 @@ @hooks { fetch = help_fetching_with_instruction_b_from_thumb - link = handle_branch_if_true_as_link + link = handle_arm_conditional_branch_as_link post = post_process_branch_instructions } @@ -131,7 +131,7 @@ @hooks { fetch = help_fetching_with_instruction_b_from_thumb - link = handle_branch_if_true_as_link + link = handle_arm_conditional_branch_as_link post = post_process_branch_instructions } @@ -161,7 +161,7 @@ @hooks { fetch = help_fetching_with_instruction_b_from_arm - link = handle_branch_if_true_as_link + link = handle_arm_conditional_branch_as_link post = post_process_branch_instructions } -- cgit v0.11.2-87-g4458