From f0682e7b195acbd4d83148f3829479d682f9ee9f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 20 Jul 2019 17:59:12 +0200
Subject: Marked some Dex strings as structural.

---
 plugins/dalvik/operands/pool.c       |   2 +-
 plugins/dex/class.c                  |   2 +-
 plugins/dex/method.c                 |   2 +-
 plugins/dex/pool.c                   |  49 +++++++-------
 plugins/dex/pool.h                   |   2 +-
 plugins/dex/python/pool.c            |   2 +-
 plugins/pychrysalide/format/strsym.c | 125 ++++++++++++++++++++++++++++-------
 src/format/strsym.c                  |  55 +++++++++++++++
 src/format/strsym.h                  |   8 +++
 src/gui/panels/strings.c             |   3 +
 10 files changed, 198 insertions(+), 52 deletions(-)

diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c
index e9f1d60..cbf3ea3 100644
--- a/plugins/dalvik/operands/pool.c
+++ b/plugins/dalvik/operands/pool.c
@@ -281,7 +281,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
 
         case DPT_STRING:
 
-            string = g_dex_pool_get_string(pool, operand->index, NULL);
+            string = g_dex_pool_get_string(pool, operand->index, NULL, NULL);
 
             if (string != NULL)
             {
diff --git a/plugins/dex/class.c b/plugins/dex/class.c
index b5ec462..9defac7 100644
--- a/plugins/dex/class.c
+++ b/plugins/dex/class.c
@@ -741,7 +741,7 @@ const char *g_dex_class_get_source_file(const GDexClass *class)
 
     pool = g_dex_format_get_pool(class->format);
 
-    result = g_dex_pool_get_string(pool, class->definition.source_file_idx, NULL);
+    result = g_dex_pool_get_string(pool, class->definition.source_file_idx, (bool []) { true }, NULL);
 
     g_object_unref(G_OBJECT(pool));
 
diff --git a/plugins/dex/method.c b/plugins/dex/method.c
index 75293b7..e93e185 100644
--- a/plugins/dex/method.c
+++ b/plugins/dex/method.c
@@ -283,7 +283,7 @@ GDexMethod *g_dex_method_new_callable(GDexFormat *format, const method_id_item *
 
     ns = g_dex_pool_get_type_(pool, id_item->class_idx);
 
-    name = g_dex_pool_get_string(pool, id_item->name_idx, NULL);
+    name = g_dex_pool_get_string(pool, id_item->name_idx, (bool []) { true }, NULL);
     if (name == NULL) goto gdmne_exit;
 
     routine = g_dex_pool_get_prototype(pool, id_item->proto_idx);
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index e7dd205..c24617a 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -24,6 +24,7 @@
 #include "pool.h"
 
 
+#include <assert.h>
 #include <malloc.h>
 #include <string.h>
 
@@ -282,6 +283,7 @@ uint32_t g_dex_pool_count_strings(const GDexPool *pool)
 *                                                                             *
 *  Paramètres  : pool  = table de resources pour format Dex à consulter.      *
 *                index = index de la chaîne recherchée.                       *
+*                mark  = marque la chaîne comme structurelle si définie.      *
 *                range = éventuelle couverture à renseigner ou NULL. [OUT]    *
 *                                                                             *
 *  Description : Extrait une chaîne de caractères d'une table DEX.            *
@@ -292,7 +294,7 @@ uint32_t g_dex_pool_count_strings(const GDexPool *pool)
 *                                                                             *
 ******************************************************************************/
 
-const char *g_dex_pool_get_string(const GDexPool *pool, uint32_t index, mrange_t *range)
+const char *g_dex_pool_get_string(const GDexPool *pool, uint32_t index, bool *mark, mrange_t *range)
 {
     uint32_t count;                         /* Nombre d'éléments présents  */
     GDexFormat *format;                     /* Format associé à la table   */
@@ -322,6 +324,15 @@ const char *g_dex_pool_get_string(const GDexPool *pool, uint32_t index, mrange_t
     if (!read_dex_string_data_item(format, &addr, &inter, &str_data))
         return NULL;
 
+    if (mark != NULL)
+    {
+        assert(*mark);
+
+        assert(pool->strings[index] != NULL);
+        g_string_symbol_set_structural(G_STR_SYMBOL(pool->strings[index]), true);
+
+    }
+
     if (range != NULL)
     {
         diff = compute_vmpa_diff(&inter, &addr);
@@ -367,7 +378,7 @@ GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *pool, uint32_t index)
 
     if (pool->strings[index] == NULL)
     {
-        string = g_dex_pool_get_string(pool, index, &range);
+        string = g_dex_pool_get_string(pool, index, NULL, &range);
         if (string == NULL) goto gssfdp_error;
 
         base = G_BIN_FORMAT(pool->format);
@@ -549,11 +560,7 @@ GDataType *g_dex_pool_get_type_(GDexPool *pool, uint32_t index)
 {
     GDataType *result;                      /* Instance à retourner        */
     type_id_item type_id;                   /* Définition de la classe     */
-    GDexFormat *format;                     /* Format associé à la table   */
-    phys_t pos;                             /* Tête de lecture             */
-    vmpa2t addr;                            /* Tête de lecture générique   */
-    string_id_item str_id;                  /* Identifiant de chaîne       */
-    string_data_item str_data;              /* Description de chaîne       */
+    const char *desc;                       /* Description de type         */
 
     result = NULL;
 
@@ -562,21 +569,10 @@ GDataType *g_dex_pool_get_type_(GDexPool *pool, uint32_t index)
         if (!g_dex_pool_get_raw_type(pool, index, &type_id))
             goto no_type_id;
 
-        format = pool->format;
-
-        pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item);
-        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
-
-        if (!read_dex_string_id_item(format, &addr, &str_id))
-            goto type_error;
-
-        pos = str_id.string_data_off;
-        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
-
-        if (!read_dex_string_data_item(format, &addr, NULL, &str_data))
-            goto type_error;
+        desc = g_dex_pool_get_string(pool, type_id.descriptor_idx, (bool []) { true }, NULL);
+        if (desc == NULL) goto type_error;
 
-        pool->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(format), (char *)str_data.data);
+        pool->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(pool->format), desc);
 
     }
 
@@ -760,9 +756,9 @@ GBinVariable *g_dex_pool_get_field(GDexPool *pool, uint32_t index)
         type = g_dex_pool_get_type_(pool, field_id.type_idx);
         if (type == NULL) goto type_error;
 
-        name = g_dex_pool_get_string(pool, field_id.name_idx, NULL);
+        name = g_dex_pool_get_string(pool, field_id.name_idx, (bool []) { true }, NULL);
         if (name == NULL) goto bad_name;
-  
+
         field = g_binary_variable_new(type);
         g_binary_variable_set_name(field, name);
 
@@ -909,6 +905,13 @@ GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index)
      * autres champs de la structure, donc l'information paraît redondante.
      */
 
+    /**
+     * On marque cependant la chaîne de description comme étant structurelle.
+     */
+
+    assert(pool->strings[proto_id.shorty_idx] != NULL);
+    g_string_symbol_set_structural(G_STR_SYMBOL(pool->strings[proto_id.shorty_idx]), true);
+
     /* Type de retour */
 
     type = g_dex_pool_get_type_(pool, proto_id.return_type_idx);
diff --git a/plugins/dex/pool.h b/plugins/dex/pool.h
index c8f9b01..1ab227d 100644
--- a/plugins/dex/pool.h
+++ b/plugins/dex/pool.h
@@ -63,7 +63,7 @@ bool g_dex_pool_load_all_string_symbols(GDexPool *, wgroup_id_t, GtkStatusStack
 uint32_t g_dex_pool_count_strings(const GDexPool *);
 
 /* Extrait une chaîne de caractères d'une table DEX. */
-const char *g_dex_pool_get_string(const GDexPool *, uint32_t, mrange_t *);
+const char *g_dex_pool_get_string(const GDexPool *, uint32_t, bool *, mrange_t *);
 
 /* Extrait un symbole de chaîne d'une table DEX. */
 GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *, uint32_t);
diff --git a/plugins/dex/python/pool.c b/plugins/dex/python/pool.c
index 971f163..450c76c 100644
--- a/plugins/dex/python/pool.c
+++ b/plugins/dex/python/pool.c
@@ -427,7 +427,7 @@ static PyObject *py_dex_pool_get_strings(PyObject *self, void *closure)
 
     for (i = 0; i < count; i++)
     {
-        string = g_dex_pool_get_string(pool, i, NULL);
+        string = g_dex_pool_get_string(pool, i, NULL, NULL);
 
         if (string == NULL)
         {
diff --git a/plugins/pychrysalide/format/strsym.c b/plugins/pychrysalide/format/strsym.c
index 8c210a2..94edd24 100644
--- a/plugins/pychrysalide/format/strsym.c
+++ b/plugins/pychrysalide/format/strsym.c
@@ -42,15 +42,21 @@
 
 
 
+/* Indique si une chaîne de caractères est liée au format. */
+static PyObject *py_string_symbol_get_structural(PyObject *, void *);
+
+/* Définit si une chaîne de caractères est liée au format. */
+static int py_string_symbol_set_structural(PyObject *, PyObject *, void *);
+
+/* Fournit l'encodage d'une chaîne de caractères. */
+static PyObject *py_string_symbol_get_encoding(PyObject *, void *);
+
 /* Fournit la chaîne brute de caractères du symbole. */
 static PyObject *py_string_symbol_get_raw(PyObject *, void *);
 
 /* Fournit la chaîne de caractères du symbole. */
 static PyObject *py_string_symbol_get_utf8(PyObject *, void *);
 
-/* Fournit l'encodage d'une chaîne de caractères. */
-static PyObject *py_string_symbol_get_encoding(PyObject *, void *);
-
 /* Définit les constantes pour les chaînes de caractères. */
 static bool py_string_symbol_define_constants(PyTypeObject *);
 
@@ -61,25 +67,32 @@ static bool py_string_symbol_define_constants(PyTypeObject *);
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
-*  Description : Fournit la chaîne brute de caractères du symbole.            *
+*  Description : Indique si une chaîne de caractères est liée au format.      *
 *                                                                             *
-*  Retour      : Chaîne de caractères d'origine.                              *
+*  Retour      : Indication sur l'emploi de la chaîne.                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_string_symbol_get_raw(PyObject *self, void *closure)
+static PyObject *py_string_symbol_get_structural(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Valeur à retourner          */
     GStrSymbol *symbol;                     /* Elément à consulter         */
-    size_t len;                             /* Taille de la chaîne         */
-    const char *data;                       /* Données à manipuler         */
+    bool status;                            /* Etat à transmettre          */
+
+#define STRING_SYMBOL_STRUCTURAL_ATTRIB PYTHON_GETSET_DEF_FULL                  \
+(                                                                               \
+    structural, py_string_symbol,                                               \
+    "True if the string symbol is linked to the file structure, else False."    \
+)
 
     symbol = G_STR_SYMBOL(pygobject_get(self));
-    data = g_string_symbol_get_raw(symbol, &len);
 
-    result = PyBytes_FromStringAndSize(data, len);
+    status = g_string_symbol_is_structural(symbol);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
 
     return result;
 
@@ -89,29 +102,30 @@ static PyObject *py_string_symbol_get_raw(PyObject *self, void *closure)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
-*                closure = non utilisé ici.                                   *
+*                value   = valeur fournie à intégrer ou prendre en compte.    *
+*                closure = adresse non utilisée ici.                          *
 *                                                                             *
-*  Description : Fournit la chaîne de caractères du symbole.                  *
+*  Description : Définit si une chaîne de caractères est liée au format.      *
 *                                                                             *
-*  Retour      : Chaîne de caractères, à priori en UTF-8.                     *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_string_symbol_get_utf8(PyObject *self, void *closure)
+static int py_string_symbol_set_structural(PyObject *self, PyObject *value, void *closure)
 {
-    PyObject *result;                       /* Valeur à retourner          */
+    int ret;                                /* Bilan d'analyse             */
     GStrSymbol *symbol;                     /* Elément à consulter         */
-    size_t len;                             /* Taille de la chaîne         */
-    const char *data;                       /* Données à manipuler         */
+
+    ret = PyBool_Check(value);
+    if (!ret) return -1;
 
     symbol = G_STR_SYMBOL(pygobject_get(self));
-    data = g_string_symbol_get_utf8(symbol, &len);
 
-    result = PyUnicode_FromStringAndSize(data, len);
+    g_string_symbol_set_structural(symbol, value == Py_True);
 
-    return result;
+    return 0;
 
 }
 
@@ -147,6 +161,66 @@ static PyObject *py_string_symbol_get_encoding(PyObject *self, void *closure)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la chaîne brute de caractères du symbole.            *
+*                                                                             *
+*  Retour      : Chaîne de caractères d'origine.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_string_symbol_get_raw(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GStrSymbol *symbol;                     /* Elément à consulter         */
+    size_t len;                             /* Taille de la chaîne         */
+    const char *data;                       /* Données à manipuler         */
+
+    symbol = G_STR_SYMBOL(pygobject_get(self));
+    data = g_string_symbol_get_raw(symbol, &len);
+
+    result = PyBytes_FromStringAndSize(data, len);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la chaîne de caractères du symbole.                  *
+*                                                                             *
+*  Retour      : Chaîne de caractères, à priori en UTF-8.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_string_symbol_get_utf8(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GStrSymbol *symbol;                     /* Elément à consulter         */
+    size_t len;                             /* Taille de la chaîne         */
+    const char *data;                       /* Données à manipuler         */
+
+    symbol = G_STR_SYMBOL(pygobject_get(self));
+    data = g_string_symbol_get_utf8(symbol, &len);
+
+    result = PyUnicode_FromStringAndSize(data, len);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
 *                                                                             *
 *  Description : Définit les constantes pour les chaînes de caractères.       *
@@ -163,6 +237,8 @@ static bool py_string_symbol_define_constants(PyTypeObject *obj_type)
 
     result = true;
 
+    result &= PyDict_AddULongMacro(obj_type, SET_NONE);
+
     result &= PyDict_AddULongMacro(obj_type, SET_ASCII);
     result &= PyDict_AddULongMacro(obj_type, SET_UTF_8);
     result &= PyDict_AddULongMacro(obj_type, SET_MUTF_8);
@@ -193,6 +269,11 @@ PyTypeObject *get_python_string_symbol_type(void)
     };
 
     static PyGetSetDef py_str_symbol_getseters[] = {
+        STRING_SYMBOL_STRUCTURAL_ATTRIB,
+        {
+            "encoding", py_string_symbol_get_encoding, NULL,
+            "Encoding of the string.", NULL
+        },
         {
             "raw", py_string_symbol_get_raw, NULL,
             "String content as raw data.", NULL
@@ -201,10 +282,6 @@ PyTypeObject *get_python_string_symbol_type(void)
             "utf8", py_string_symbol_get_utf8, NULL,
             "String content as UTF-8 data.", NULL
         },
-        {
-            "encoding", py_string_symbol_get_encoding, NULL,
-            "Encoding of the string.", NULL
-        },
         { NULL }
     };
 
diff --git a/src/format/strsym.c b/src/format/strsym.c
index 4e8479e..ed38a6b 100644
--- a/src/format/strsym.c
+++ b/src/format/strsym.c
@@ -44,6 +44,8 @@ struct _GStrSymbol
 {
     GBinSymbol parent;                      /* A laisser en premier        */
 
+    bool structural;                        /* Nature d'emploi de la chaîne*/
+
     StringEncodingType encoding;            /* Encodage de la chaîne liée  */
 
     union
@@ -150,6 +152,13 @@ static void g_string_symbol_class_init(GStrSymbolClass *klass)
 
 static void g_string_symbol_init(GStrSymbol *symbol)
 {
+    symbol->structural = false;
+
+    symbol->encoding = SET_NONE;
+
+    symbol->string = NULL;
+
+    symbol->has_content = false;
 
 }
 
@@ -321,6 +330,10 @@ static void g_string_symbol_check_encoding(GStrSymbol *symbol)
 
     switch (symbol->encoding)
     {
+        case SET_NONE:
+            assert(false);
+            break;
+
         case SET_ASCII:
             break;
 
@@ -378,6 +391,48 @@ static void g_string_symbol_check_encoding(GStrSymbol *symbol)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : symbol = symbole à venir actualiser.                         *
+*                                                                             *
+*  Description : Définit si une chaîne de caractères est liée au format.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_string_symbol_set_structural(GStrSymbol *symbol, bool status)
+{
+    symbol->structural = status;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = symbole à venir consulter.                          *
+*                                                                             *
+*  Description : Indique si une chaîne de caractères est liée au format.      *
+*                                                                             *
+*  Retour      : Indication sur l'emploi de la chaîne.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_string_symbol_is_structural(const GStrSymbol *symbol)
+{
+    bool result;                            /* Statut à retourner          */
+
+    result = symbol->structural;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : symbol = symbole à venir consulter.                          *
 *                                                                             *
 *  Description : Fournit l'encodage d'une chaîne de caractères.               *
diff --git a/src/format/strsym.h b/src/format/strsym.h
index 4a1404b..a4c7d58 100644
--- a/src/format/strsym.h
+++ b/src/format/strsym.h
@@ -39,6 +39,8 @@
 /* Types de chaînes */
 typedef enum _StringEncodingType
 {
+    SET_NONE,                               /* Valeur d'initialisation     */
+
     SET_ASCII,                              /* Format brut                 */
     SET_UTF_8,                              /* Format UTF-8                */
     SET_MUTF_8,                             /* Format UTF-8 modifié        */
@@ -72,6 +74,12 @@ GBinSymbol *g_string_symbol_new_read_only(GBinFormat *, const mrange_t *, String
 /* Crée un nouveau symbole pour chaîne de caractères. */
 GBinSymbol *g_string_symbol_new_dynamic(const char *, const vmpa2t *, StringEncodingType);
 
+/* Définit si une chaîne de caractères est liée au format. */
+void g_string_symbol_set_structural(GStrSymbol *, bool);
+
+/* Indique si une chaîne de caractères est liée au format. */
+bool g_string_symbol_is_structural(const GStrSymbol *);
+
 /* Fournit l'encodage d'une chaîne de caractères. */
 StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *);
 
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index a99b40c..879b37b 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -770,6 +770,9 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat
         if (!G_IS_STR_SYMBOL(symbol))
             goto rsfnlv_next;
 
+        if (g_string_symbol_is_structural(G_STR_SYMBOL(symbol)))
+            goto rsfnlv_next;
+
         range = g_binary_symbol_get_range(symbol);
         addr = get_mrange_addr(range);
 
-- 
cgit v0.11.2-87-g4458