From 3293a5b3b13271ea1499718d310c1bd0284762a3 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
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 <nocbos@gmail.com>
 
+	* 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 <nocbos@gmail.com>
+
 	* 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#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