summaryrefslogtreecommitdiff
path: root/src/analysis/disass/macro.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-04-01 21:45:29 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-04-01 21:45:29 (GMT)
commit3293a5b3b13271ea1499718d310c1bd0284762a3 (patch)
tree65f564c8fb56d1d28ac4da9ef62d65db06c29591 /src/analysis/disass/macro.c
parent5cc7bd39ae41af40a0c939acf98f90bf1375effd (diff)
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
Diffstat (limited to 'src/analysis/disass/macro.c')
-rw-r--r--src/analysis/disass/macro.c83
1 files changed, 75 insertions, 8 deletions
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;
}