From ea60c6e86b0b86319cf2fc01ca1a7608c5fac9c0 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 14 Jan 2019 21:52:47 +0100
Subject: Looked for code blocks by any contained address.

---
 plugins/pychrysalide/analysis/block.c | 14 ++++++------
 src/analysis/block-int.h              | 10 +++------
 src/analysis/block.c                  | 12 +++++-----
 src/analysis/block.h                  |  7 ++++--
 src/analysis/disass/block.c           | 42 ++++++++++++++++++++++++++---------
 5 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/plugins/pychrysalide/analysis/block.c b/plugins/pychrysalide/analysis/block.c
index c484ba6..ca4ac09 100644
--- a/plugins/pychrysalide/analysis/block.c
+++ b/plugins/pychrysalide/analysis/block.c
@@ -58,8 +58,8 @@ static PyObject *py_code_block_get_destinations(PyObject *, void *);
 /* ------------------------- REGROUPEMENT EN LISTE DE BLOCS ------------------------- */
 
 
-/* Recherche un bloc de code débutant à une adresse donnée. */
-static PyObject *py_block_list_find_by_starting_addr(PyObject *, PyObject *);
+/* Recherche un bloc de code contenant une adresse donnée. */
+static PyObject *py_block_list_find_by_addr(PyObject *, PyObject *);
 
 /* Itère sur l'ensemble des blocs de code inclus dans une liste. */
 static PyObject *py_block_list_iter(PyObject *);
@@ -343,7 +343,7 @@ bool ensure_python_code_block_is_registered(void)
 *  Paramètres  : self = classe représentant une liste de blocs de code.       *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
-*  Description : Recherche un bloc de code débutant à une adresse donnée.     *
+*  Description : Recherche un bloc de code contenant une adresse donnée.      *
 *                                                                             *
 *  Retour      : Bloc de code trouvé ou None si aucun.                        *
 *                                                                             *
@@ -351,7 +351,7 @@ bool ensure_python_code_block_is_registered(void)
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_block_list_find_by_starting_addr(PyObject *self, PyObject *args)
+static PyObject *py_block_list_find_by_addr(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Conclusion à retourner      */
     vmpa2t addr;                            /* Emplacement ciblé           */
@@ -364,7 +364,7 @@ static PyObject *py_block_list_find_by_starting_addr(PyObject *self, PyObject *a
 
     list = G_BLOCK_LIST(pygobject_get(self));
 
-    found = g_block_list_find_by_starting_addr(list, &addr);
+    found = g_block_list_find_by_addr(list, &addr);
 
     if (found != NULL)
     {
@@ -471,9 +471,9 @@ PyTypeObject *get_python_block_list_type(void)
 {
     static PyMethodDef py_block_list_methods[] = {
         {
-            "find_by_starting_addr", py_block_list_find_by_starting_addr,
+            "find_by_addr", py_block_list_find_by_addr,
             METH_VARARGS,
-            "find_by_starting_addr($self, addr, /)\n--\n\nFind a code block starting at a given address."
+            "find_by_addr($self, addr, /)\n--\n\nFind a code block containing a given address."
         },
         { NULL }
     };
diff --git a/src/analysis/block-int.h b/src/analysis/block-int.h
index ca38703..8988091 100644
--- a/src/analysis/block-int.h
+++ b/src/analysis/block-int.h
@@ -35,8 +35,8 @@
 /* ----------------------------- BLOC DE CODE GENERIQUE ----------------------------- */
 
 
-/* Détermine si un bloc de code débute à une adresse donnée. */
-typedef bool (* block_is_starting_fc) (const GCodeBlock *, const vmpa2t *);
+/* Détermine si un bloc de code contient une adresse donnée. */
+typedef bool (* block_contains_fc) (const GCodeBlock *, const vmpa2t *);
 
 /* Fournit les détails des origines d'un bloc de code donné. */
 typedef block_link_t * (* block_get_links_fc) (const GCodeBlock *, const GBlockList *, size_t *);
@@ -66,7 +66,7 @@ struct _GCodeBlockClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
-    block_is_starting_fc is_starting;       /* Analyse d'adresse initiale  */
+    block_contains_fc contains;             /* Possession d'une adresse    */
     block_get_links_fc get_src;             /* Obtention des origines      */
     block_get_links_fc get_dest;            /* Obtention des destinations  */
     block_build_view_fc build;              /* Construction d'une vue      */
@@ -74,9 +74,5 @@ struct _GCodeBlockClass
 };
 
 
-/* Détermine si un bloc de code débute à une adresse donnée. */
-bool g_code_block_is_starting_with(const GCodeBlock *, const vmpa2t *);
-
-
 
 #endif  /* _ANALYSIS_BLOCK_INT_H */
diff --git a/src/analysis/block.c b/src/analysis/block.c
index 7003ccd..8bc0d4b 100644
--- a/src/analysis/block.c
+++ b/src/analysis/block.c
@@ -259,7 +259,7 @@ size_t g_code_block_get_index(const GCodeBlock *block)
 *  Paramètres  : block = bloc de code à consulter.                            *
 *                addr  = localisation à comparer.                             *
 *                                                                             *
-*  Description : Détermine si un bloc de code débute à une adresse donnée.    *
+*  Description : Détermine si un bloc de code contient une adresse donnée.    *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -267,14 +267,14 @@ size_t g_code_block_get_index(const GCodeBlock *block)
 *                                                                             *
 ******************************************************************************/
 
-bool g_code_block_is_starting_with(const GCodeBlock *block, const vmpa2t *addr)
+bool g_code_block_contains_addr(const GCodeBlock *block, const vmpa2t *addr)
 {
     bool result;                            /* Bilan à retourner           */
     GCodeBlockClass *class;                 /* Classe des blocs de code    */
 
     class = G_CODE_BLOCK_GET_CLASS(block);
 
-    result = class->is_starting(block, addr);
+    result = class->contains(block, addr);
 
     return result;
 
@@ -679,7 +679,7 @@ GCodeBlock *g_block_list_get_block(const GBlockList *list, size_t index)
 *  Paramètres  : list = liste de blocs de code à consulter.                   *
 *                addr = localisation à comparer.                              *
 *                                                                             *
-*  Description : Recherche un bloc de code débutant à une adresse donnée.     *
+*  Description : Recherche un bloc de code contenant une adresse donnée.      *
 *                                                                             *
 *  Retour      : Bloc de code trouvé ou NULL si aucun.                        *
 *                                                                             *
@@ -687,7 +687,7 @@ GCodeBlock *g_block_list_get_block(const GBlockList *list, size_t index)
 *                                                                             *
 ******************************************************************************/
 
-GCodeBlock *g_block_list_find_by_starting_addr(const GBlockList *list, const vmpa2t *addr)
+GCodeBlock *g_block_list_find_by_addr(const GBlockList *list, const vmpa2t *addr)
 {
     GCodeBlock *result;                     /* Trouvaille à retourner      */
     size_t i;                               /* Boucle de parcours          */
@@ -709,7 +709,7 @@ GCodeBlock *g_block_list_find_by_starting_addr(const GBlockList *list, const vmp
         if (block == NULL)
             continue;
 
-        if (g_code_block_is_starting_with(block, addr))
+        if (g_code_block_contains_addr(block, addr))
         {
             result = block;
             g_object_ref(G_OBJECT(result));
diff --git a/src/analysis/block.h b/src/analysis/block.h
index 23637d7..4ae0def 100644
--- a/src/analysis/block.h
+++ b/src/analysis/block.h
@@ -65,6 +65,9 @@ const bitfield_t *g_code_block_get_domination(const GCodeBlock *);
 /* Indique l'indice d'intégration du bloc dans une liste. */
 size_t g_code_block_get_index(const GCodeBlock *);
 
+/* Détermine si un bloc de code contient une adresse donnée. */
+bool g_code_block_contains_addr(const GCodeBlock *, const vmpa2t *);
+
 /* Fournit le rang du bloc de code dans le flot d'exécution. */
 size_t g_code_block_get_rank(const GCodeBlock *);
 
@@ -136,8 +139,8 @@ void g_block_list_resolve_links(const GBlockList *);
 /* Fournit le bloc de code correspondant à un indice de liste. */
 GCodeBlock *g_block_list_get_block(const GBlockList *, size_t);
 
-/* Recherche un bloc de code débutant à une adresse donnée. */
-GCodeBlock *g_block_list_find_by_starting_addr(const GBlockList *, const vmpa2t *);
+/*  Recherche un bloc de code contenant une adresse donnée. */
+GCodeBlock *g_block_list_find_by_addr(const GBlockList *, const vmpa2t *);
 
 
 
diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c
index 23393f6..ec8cf2a 100644
--- a/src/analysis/disass/block.c
+++ b/src/analysis/disass/block.c
@@ -68,8 +68,8 @@ static void g_basic_block_dispose(GBasicBlock *);
 /* Procède à la libération totale de la mémoire. */
 static void g_basic_block_finalize(GBasicBlock *);
 
-/* Détermine si un bloc de code débute à une adresse donnée. */
-static bool g_basic_block_is_starting_with(const GBasicBlock *, const vmpa2t *);
+/* Détermine si un bloc de code contient une adresse donnée. */
+static bool g_basic_block_contains_addr(const GBasicBlock *, const vmpa2t *);
 
 /* Fournit les détails des origines d'un bloc de code donné. */
 static block_link_t *g_basic_block_get_sources(const GBasicBlock *, const GBlockList *, size_t *);
@@ -115,7 +115,7 @@ static void g_basic_block_class_init(GBasicBlockClass *class)
 
     block = G_CODE_BLOCK_CLASS(class);
 
-    block->is_starting = (block_is_starting_fc)g_basic_block_is_starting_with;
+    block->contains = (block_contains_fc)g_basic_block_contains_addr;
     block->get_src = (block_get_links_fc)g_basic_block_get_sources;
     block->get_dest = (block_get_links_fc)g_basic_block_get_destinations;
     block->build = (block_build_view_fc)g_basic_block_build_view;
@@ -229,7 +229,7 @@ GCodeBlock *g_basic_block_new(GLoadedBinary *binary, GArchInstruction *first, GA
 *  Paramètres  : block = bloc de code à consulter.                            *
 *                addr  = localisation à comparer.                             *
 *                                                                             *
-*  Description : Détermine si un bloc de code débute à une adresse donnée.    *
+*  Description : Détermine si un bloc de code contient une adresse donnée.    *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -237,14 +237,36 @@ GCodeBlock *g_basic_block_new(GLoadedBinary *binary, GArchInstruction *first, GA
 *                                                                             *
 ******************************************************************************/
 
-static bool g_basic_block_is_starting_with(const GBasicBlock *block, const vmpa2t *addr)
+static bool g_basic_block_contains_addr(const GBasicBlock *block, const vmpa2t *addr)
 {
     bool result;                            /* Bilan à retourner           */
-    const mrange_t *range;                  /* Couverture d'instruction    */
+    const mrange_t *frange;                 /* Couverture d'instruction #1 */
+    const mrange_t *lrange;                 /* Couverture d'instruction #2 */
+    phys_t diff;                            /* Ecart entre les positions   */
+    mrange_t coverage;                      /* Couverture du bloc          */
+
+    frange = g_arch_instruction_get_range(block->first);
+
+    result = (cmp_vmpa(addr, get_mrange_addr(frange)) == 0);
+
+    if (!result)
+    {
+        lrange = g_arch_instruction_get_range(block->last);
+
+        result = (cmp_vmpa(addr, get_mrange_addr(lrange)) == 0);
 
-    range = g_arch_instruction_get_range(block->first);
+        if (!result)
+        {
+            diff = compute_vmpa_diff(get_mrange_addr(frange), get_mrange_addr(lrange));
+            diff += get_mrange_length(lrange);
+
+            init_mrange(&coverage, get_mrange_addr(frange), diff);
+
+            result = mrange_contains_addr(&coverage, addr);
 
-    result = (cmp_vmpa(addr, get_mrange_addr(range)) == 0);
+        }
+
+    }
 
     return result;
 
@@ -287,7 +309,7 @@ static block_link_t *g_basic_block_get_sources(const GBasicBlock *block, const G
 
         range = g_arch_instruction_get_range(src->linked);
 
-        target = g_block_list_find_by_starting_addr(list, get_mrange_addr(range));
+        target = g_block_list_find_by_addr(list, get_mrange_addr(range));
 
         /**
          * Les liens ne sont pas toujours internes !
@@ -359,7 +381,7 @@ static block_link_t *g_basic_block_get_destinations(const GBasicBlock *block, co
 
         range = g_arch_instruction_get_range(dest->linked);
 
-        target = g_block_list_find_by_starting_addr(list, get_mrange_addr(range));
+        target = g_block_list_find_by_addr(list, get_mrange_addr(range));
 
         /**
          * Les sauts ne se font pas toujours à l'intérieur d'une même fonction.
-- 
cgit v0.11.2-87-g4458