summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--src/analysis/disass/macro.c83
-rw-r--r--src/arch/arm/Makefile.am1
-rw-r--r--src/arch/arm/instruction.c1
-rw-r--r--src/arch/arm/link.c65
-rw-r--r--src/arch/arm/link.h39
-rw-r--r--src/arch/arm/v7/opdefs/Makefile.am2
-rw-r--r--src/arch/arm/v7/opdefs/b_A8818.d10
8 files changed, 209 insertions, 14 deletions
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
}