From 73fb6dd90282dd10a6c3febe7348ad698c0336a8 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 29 Dec 2015 02:40:13 +0100
Subject: Avoided to crash by being too strict with addresses provided by
 clicks on the binary strip.

---
 ChangeLog            | 10 ++++++++++
 src/arch/processor.c | 34 ++++++++++++++++++++++++----------
 src/arch/processor.h | 10 ++++++++--
 src/gui/status.c     |  4 +++-
 4 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5d253fc..25e74e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 15-12-29  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/arch/processor.c:
+	* src/arch/processor.h:
+	Make it possible to find instructions by their addresses in a flexible way.
+
+	* src/gui/status.c:
+	Avoid to crash by being too strict with addresses provided by clicks on
+	the binary strip.
+
+15-12-29  Cyrille Bagard <nocbos@gmail.com>
+
 	* plugins/mobicore/mclf.c:
 	* src/analysis/disass/area.c:
 	* src/analysis/disass/output.c:
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 6b60c8c..cb00a2d 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -511,14 +511,11 @@ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProc
 }
 
 
-
-
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : proc = processeur recensant diverses instructions.           *
-*                addr = position en mémoire ou physique à chercher.           *
+*  Paramètres  : proc   = processeur recensant diverses instructions.         *
+*                addr   = position en mémoire ou physique à chercher.         *
+*                nearby = la recherche s'effectue-t-elle de façon stricte ?   *
 *                                                                             *
 *  Description : Recherche une instruction d'après son adresse.               *
 *                                                                             *
@@ -528,7 +525,7 @@ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProc
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr)
+GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr, bool nearby)
 {
     GArchInstruction *result;               /* Trouvaille à retourner      */
     const instr_coverage *coverage;         /* Couverture fine à fouiller  */
@@ -536,7 +533,7 @@ GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *p
     coverage = g_arch_processor_find_coverage_by_address(proc, addr);
 
     if (coverage != NULL)
-        result = g_arch_processor_find_covered_instr_by_address(proc, coverage, addr);
+        result = _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, nearby);
     else
         result = NULL;
 
@@ -550,6 +547,7 @@ GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *p
 *  Paramètres  : proc     = processeur recensant diverses instructions.       *
 *                coverage = zone de couverture fine à fouiller.               *
 *                addr     = position en mémoire ou physique à chercher.       *
+*                nearby   = la recherche s'effectue-t-elle de façon stricte ? *
 *                                                                             *
 *  Description : Recherche rapidement une instruction d'après son adresse.    *
 *                                                                             *
@@ -559,10 +557,11 @@ GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *p
 *                                                                             *
 ******************************************************************************/
 
-GArchInstruction *g_arch_processor_find_covered_instr_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr)
+GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)
 {
     GArchInstruction *result;               /* Trouvaille à retourner      */
     void *ptr;                              /* Résultat des recherches     */
+    __compar_fn_t fn;                       /* Fonction auxiliaire adaptée */
 
     int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b)
     {
@@ -574,8 +573,23 @@ GArchInstruction *g_arch_processor_find_covered_instr_by_address(const GArchProc
 
     }
 
+    int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b)
+    {
+        const mrange_t *range_b;            /* Emplacement pour l'instr. B */
+
+        range_b = g_arch_instruction_get_range(*b);
+
+        return cmp_mrange_with_vmpa(range_b, a);
+
+    }
+
+    if (nearby)
+        fn = (__compar_fn_t)search_for_instr_by_nearby_addr;
+    else
+        fn = (__compar_fn_t)search_for_instr_by_addr;
+
     ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count,
-                  sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr);
+                  sizeof(GArchInstruction *), fn);
 
     result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
 
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 45b9012..dd93960 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -95,10 +95,16 @@ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProc
 const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *);
 
 /* Recherche une instruction d'après son adresse. */
-GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *);
+GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *, bool);
 
 /* Recherche rapidement une instruction d'après son adresse. */
-GArchInstruction *g_arch_processor_find_covered_instr_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *);
+GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool);
+
+#define g_arch_processor_find_instr_by_address(proc, addr)      \
+    _g_arch_processor_find_instr_by_address(proc, addr, false)
+
+#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr)    \
+    _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false)
 
 /* Fournit l'instruction qui en précède une autre. */
 GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *, const GArchInstruction *);
diff --git a/src/gui/status.c b/src/gui/status.c
index f466193..de80049 100644
--- a/src/gui/status.c
+++ b/src/gui/status.c
@@ -25,6 +25,7 @@
 #include "status.h"
 
 
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 
@@ -303,7 +304,8 @@ static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binar
 
     proc = g_loaded_binary_get_processor(binary);
 
-    instr = g_arch_processor_find_instr_by_address(proc, addr);
+    instr = _g_arch_processor_find_instr_by_address(proc, addr, true);
+    assert(instr != NULL);
 
     item = G_EDITOR_ITEM(info);
     gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr);
-- 
cgit v0.11.2-87-g4458