summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-07-10 18:08:17 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-07-10 18:08:17 (GMT)
commiteca08119377ce38232581d444f48e28e0d02692b (patch)
tree5114641c42dfe8505bc92e762ac2c67955f25327
parente5ca6221a35ab26d170dbdfd4ec52e010864cf99 (diff)
Linked all used Dalvik strings with their origin.
-rw-r--r--plugins/dalvik/link.c65
-rw-r--r--plugins/dalvik/link.h4
-rw-r--r--plugins/dalvik/v35/opdefs/const_1a.d6
-rw-r--r--plugins/dalvik/v35/opdefs/const_1b.d6
-rw-r--r--plugins/dex/dex-int.c6
-rw-r--r--plugins/dex/dex-int.h3
-rw-r--r--plugins/dex/format.c3
-rw-r--r--plugins/dex/pool.c148
-rw-r--r--plugins/dex/pool.h7
-rw-r--r--plugins/readdex/ids.c14
10 files changed, 216 insertions, 46 deletions
diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c
index aaed263..c37abb8 100644
--- a/plugins/dalvik/link.c
+++ b/plugins/dalvik/link.c
@@ -34,8 +34,10 @@
#include <analysis/db/items/comment.h>
#include <arch/target.h>
#include <common/extstr.h>
+#include <plugins/dex/pool.h>
+#include "operands/pool.h"
#include "pseudo/switch.h"
@@ -63,6 +65,69 @@ typedef struct _case_comment
#define COMMENT_LINE_SEP "\n"
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à 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 une référence entre utilisation et origine de chaîne.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_links_for_dalvik_string(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GExeFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ uint32_t index; /* Indice dans la table Dex */
+ GBinSymbol *string; /* Emplacement de la chaîne */
+ const mrange_t *range; /* Zone d'occupation */
+ GArchInstruction *target; /* Ligne visée par la référence*/
+
+ g_arch_instruction_lock_operands(instr);
+
+ assert(_g_arch_instruction_count_operands(instr) == 2);
+
+ op = _g_arch_instruction_get_operand(instr, 1);
+
+ g_arch_instruction_unlock_operands(instr);
+
+ assert(G_IS_DALVIK_POOL_OPERAND(op));
+
+ assert(g_dalvik_pool_operand_get_pool_type(G_DALVIK_POOL_OPERAND(op)) == DPT_STRING);
+
+ index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(op));
+
+ string = get_string_symbol_from_dex_pool(G_DEX_FORMAT(format), index);
+
+ if (string != NULL)
+ {
+ range = g_binary_symbol_get_range(string);
+
+ target = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
+
+ if (target != NULL)
+ {
+ g_arch_instruction_link_with(instr, target, ILT_REF);
+
+ g_object_unref(G_OBJECT(target));
+
+ }
+
+ g_object_unref(G_OBJECT(string));
+
+ }
+
+ g_object_unref(G_OBJECT(op));
+
+}
+
+
/******************************************************************************
* *
* Paramètres : instr = instruction ARMv7 à traiter. *
diff --git a/plugins/dalvik/link.h b/plugins/dalvik/link.h
index 38dfd46..3b4a91f 100644
--- a/plugins/dalvik/link.h
+++ b/plugins/dalvik/link.h
@@ -29,6 +29,10 @@
+/* Etablit une référence entre utilisation et origine de chaîne. */
+void handle_links_for_dalvik_string(GArchInstruction *, GArchProcessor *, GProcContext *, GExeFormat *);
+
+
static inline void handle_dalvik_if_branch_as_link(GArchInstruction *ins, GArchProcessor *proc, GProcContext *ctx, GExeFormat *fmt)
{
handle_branch_as_link(ins, proc, ctx, fmt, 2);
diff --git a/plugins/dalvik/v35/opdefs/const_1a.d b/plugins/dalvik/v35/opdefs/const_1a.d
index 54101cd..ff01dbc 100644
--- a/plugins/dalvik/v35/opdefs/const_1a.d
+++ b/plugins/dalvik/v35/opdefs/const_1a.d
@@ -35,4 +35,10 @@
@format 21c | pool_string
+ @hooks {
+
+ link = handle_links_for_dalvik_string
+
+ }
+
}
diff --git a/plugins/dalvik/v35/opdefs/const_1b.d b/plugins/dalvik/v35/opdefs/const_1b.d
index 0aef637..9153206 100644
--- a/plugins/dalvik/v35/opdefs/const_1b.d
+++ b/plugins/dalvik/v35/opdefs/const_1b.d
@@ -35,4 +35,10 @@
@format 31c | pool_string
+ @hooks {
+
+ link = handle_links_for_dalvik_string
+
+ }
+
}
diff --git a/plugins/dex/dex-int.c b/plugins/dex/dex-int.c
index e3121b6..287ec7a 100644
--- a/plugins/dex/dex-int.c
+++ b/plugins/dex/dex-int.c
@@ -145,6 +145,7 @@ bool read_dex_string_id_item(const GDexFormat *format, vmpa2t *pos, string_id_it
* *
* Paramètres : format = informations chargées à consulter. *
* pos = position de début de lecture. [OUT] *
+* inter = position intermédiaire à conserver. [OUT] *
* str_data = structure lue à retourner. [OUT] *
* *
* Description : Procède à la lecture de proriétés de chaîne DEX. *
@@ -155,7 +156,7 @@ bool read_dex_string_id_item(const GDexFormat *format, vmpa2t *pos, string_id_it
* *
******************************************************************************/
-bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *pos, string_data_item *str_data)
+bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *pos, vmpa2t *inter, string_data_item *str_data)
{
bool result; /* Bilan à retourner */
GBinContent *content; /* Contenu binaire à lire */
@@ -166,6 +167,9 @@ bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *pos, string_dat
if (result)
{
+ if (inter != NULL)
+ copy_vmpa(inter, pos);
+
str_data->data = g_binary_content_get_raw_access(content, pos, str_data->utf16_size);
result = (str_data->data != NULL);
}
diff --git a/plugins/dex/dex-int.h b/plugins/dex/dex-int.h
index 4016b1c..5180b58 100644
--- a/plugins/dex/dex-int.h
+++ b/plugins/dex/dex-int.h
@@ -41,6 +41,7 @@ struct _GDexFormat
dex_header header; /* En-tête du programme */
+ GBinSymbol **strings; /* Symboles pour les chaînes */
GDataType **types; /* Types partagés pour Dalvik */
GBinVariable **fields; /* Champs de données partagés */
GDexClass **classes; /* Classes retrouvées */
@@ -80,7 +81,7 @@ bool read_dex_header(const GDexFormat *, vmpa2t *, dex_header *);
bool read_dex_string_id_item(const GDexFormat *, vmpa2t *, string_id_item *);
/* Procède à la lecture de proriétés de chaîne DEX. */
-bool read_dex_string_data_item(const GDexFormat *, vmpa2t *, string_data_item *);
+bool read_dex_string_data_item(const GDexFormat *, vmpa2t *, vmpa2t *, string_data_item *);
/* Procède à la lecture d'un identifiant de type DEX. */
bool read_dex_type_id_item(const GDexFormat *, vmpa2t *, type_id_item *);
diff --git a/plugins/dex/format.c b/plugins/dex/format.c
index f185cc3..b69cc76 100644
--- a/plugins/dex/format.c
+++ b/plugins/dex/format.c
@@ -396,6 +396,9 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS
/* TODO : vérifier que les *_id ne se chevauchent pas */
+ if (!load_all_dex_string_symbols(format, gid, status))
+ goto gdfa_error;
+
if (!load_all_dex_types(format, gid, status))
goto gdfa_error;
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index 8c740bc..8a421b2 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -41,9 +41,11 @@
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à analyser. *
+* Paramètres : format = description de l'exécutable à compléter. *
+* gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
* *
-* Description : Charge en mémoire toutes les chaînes trouvées. *
+* Description : Charge en mémoire l'ensemble des chaînes du format DEX. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -51,38 +53,58 @@
* *
******************************************************************************/
-bool find_all_dex_strings(GDexFormat *format)
+bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)
{
- GBinFormat *base; /* Autre version du format */
+ bool result; /* Bilan à retourner */
uint32_t count; /* Nombre d'éléments présents */
- uint32_t i; /* Boucle de parcours */
- mrange_t range; /* Couverture associée */
- const char *text; /* Texte issu du binaire */
- GBinSymbol *symbol; /* Nouveau symbole construit */
- char *label; /* Désignation de la chaîne */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ uint32_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ activity_id_t msg; /* Message de progression */
+ guint i; /* Boucle de parcours */
+ uint32_t begin; /* Début de bloc de traitement */
+ uint32_t end; /* Fin d'un bloc de traitement */
+ GDexLoading *loading; /* Tâche de chargement à lancer*/
- base = G_BIN_FORMAT(format);
+ result = true;
+
+ /* Préparation du réceptacle */
count = count_strings_in_dex_pool(format);
- for (i = 0; i < count; i++)
- {
- text = get_string_from_dex_pool(format, i, &range);
- if (text == NULL) continue;
+ format->strings = (GBinSymbol **)calloc(count, sizeof(GBinSymbol *));
- symbol = g_binary_symbol_new(&range, STP_STRING);
+ /* Lancement des chargements */
- label = create_string_label(base, get_mrange_addr(&range), get_mrange_length(&range));
+ runs_count = get_max_online_threads();
- g_binary_symbol_set_alt_label(symbol, label);
+ run_size = count / runs_count;
- free(label);
+ queue = get_work_queue();
+
+ msg = gtk_status_stack_add_activity(status, _("Loading all strings from the Dex pool..."), count);
+
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = i * run_size;
+
+ if ((i + 1) == runs_count)
+ end = count;
+ else
+ end = begin + run_size;
+
+ loading = g_dex_loading_new(format, begin, end, msg,
+ (dex_loading_cb)get_string_symbol_from_dex_pool, &result);
- g_binary_format_add_symbol(base, symbol);
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid);
}
- return true;
+ g_work_queue_wait_for_completion(queue, gid);
+
+ gtk_status_stack_remove_activity(status, msg);
+
+ return result;
}
@@ -113,12 +135,12 @@ uint32_t count_strings_in_dex_pool(const GDexFormat *format)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
-* index = index du type recherchée. *
+* index = index de la chaîne recherchée. *
* range = éventuelle couverture à renseigner ou NULL. [OUT] *
* *
* Description : Extrait une chaîne de caractères d'une table DEX. *
* *
-* Retour : Chaîne de caractères trouvées ou NULL en cas d'erreur. *
+* Retour : Chaîne de caractères trouvée ou NULL en cas d'erreur. *
* *
* Remarques : - *
* *
@@ -130,8 +152,8 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m
off_t pos; /* Tête de lecture */
vmpa2t addr; /* Tête de lecture générique */
string_id_item str_id; /* Identifiant de chaîne */
+ vmpa2t inter; /* Position intermédiaire */
string_data_item str_data; /* Description de chaîne */
- vmpa2t start; /* Début de la chaîne */
phys_t diff; /* Avancée de tête de lecture */
count = count_strings_in_dex_pool(format);
@@ -148,15 +170,14 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m
pos = str_id.string_data_off;
init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_string_data_item(format, &addr, &str_data))
+ if (!read_dex_string_data_item(format, &addr, &inter, &str_data))
return NULL;
if (range != NULL)
{
- init_vmpa(&start, pos, VMPA_NO_VIRTUAL);
- diff = compute_vmpa_diff(&start, &addr);
+ diff = compute_vmpa_diff(&inter, &addr);
- init_mrange(range, &start, diff);
+ init_mrange(range, &inter, diff);
}
@@ -167,6 +188,75 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m
/******************************************************************************
* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
+* index = index de la chaîne recherchée. *
+* *
+* Description : Extrait un symbole de chaîne d'une table DEX. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index)
+{
+ GBinSymbol *result; /* Instance à retourner */
+ uint32_t count; /* Nombre d'éléments présents */
+ mrange_t range; /* Emplacement de la chaîne */
+ const char *string; /* Chaîne de caractères liée */
+ GBinSymbol *new; /* Nouveau symbol créé */
+ GBinFormat *base; /* Autre version du format */
+ char *label; /* Désignation de la chaîne */
+ bool inserted; /* Bilan d'une insertion */
+
+ result = NULL;
+
+ count = count_strings_in_dex_pool(format);
+
+ if (index >= count)
+ goto gssfdp_error;
+
+ if (format->strings[index] == NULL)
+ {
+ string = get_string_from_dex_pool(format, index, &range);
+ if (string == NULL) goto gssfdp_error;
+
+ new = g_binary_symbol_new(&range, STP_RO_STRING);
+
+ base = G_BIN_FORMAT(format);
+
+ label = create_string_label(base, get_mrange_addr(&range), get_mrange_length(&range));
+
+ g_binary_symbol_set_alt_label(new, label);
+
+ free(label);
+
+ g_object_ref(G_OBJECT(new));
+ inserted = g_binary_format_add_symbol(base, new);
+
+ if (inserted)
+ format->strings[index] = new;
+
+ else
+ g_object_unref(G_OBJECT(new));
+
+ }
+
+ result = format->strings[index];
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ gssfdp_error:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = description de l'exécutable à compléter. *
* gid = groupe de travail impliqué. *
status = barre de statut à tenir informée. *
@@ -261,7 +351,7 @@ uint32_t count_types_in_dex_pool(const GDexFormat *format)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
-* index = index du type recherchée. *
+* index = index du type recherché. *
* *
* Description : Extrait une représentation de type d'une table DEX. *
* *
@@ -305,7 +395,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
pos = str_id.string_data_off;
init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_string_data_item(format, &addr, &str_data))
+ if (!read_dex_string_data_item(format, &addr, NULL, &str_data))
goto gtfdp_error;
format->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(format), (char *)str_data.data);
diff --git a/plugins/dex/pool.h b/plugins/dex/pool.h
index ed5b447..ac7db60 100644
--- a/plugins/dex/pool.h
+++ b/plugins/dex/pool.h
@@ -35,8 +35,8 @@
-/* Charge en mémoire toutes les chaînes trouvées. */
-bool find_all_dex_strings(GDexFormat *);
+/* Charge en mémoire l'ensemble des chaînes du format DEX. */
+bool load_all_dex_string_symbols(GDexFormat *, wgroup_id_t, GtkStatusStack *);
/* Compte le nombre de chaînes de caractères dans une table DEX. */
uint32_t count_strings_in_dex_pool(const GDexFormat *);
@@ -44,6 +44,9 @@ uint32_t count_strings_in_dex_pool(const GDexFormat *);
/* Extrait une chaîne de caractères d'une table DEX. */
const char *get_string_from_dex_pool(const GDexFormat *, uint32_t, mrange_t *);
+/* Extrait un symbole de chaîne d'une table DEX. */
+GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *, uint32_t);
+
/* Charge en mémoire l'ensemble des types du format DEX. */
bool load_all_dex_types(GDexFormat *, wgroup_id_t, GtkStatusStack *);
diff --git a/plugins/readdex/ids.c b/plugins/readdex/ids.c
index 82d17f4..702e071 100644
--- a/plugins/readdex/ids.c
+++ b/plugins/readdex/ids.c
@@ -253,9 +253,6 @@ bool annotate_dex_string_ids(const GDexFormat *format, GPreloadInfo *info, GtkSt
vmpa2t item_pos; /* Position d'un élément */
uleb128_t length; /* Taille de la chaîne en cours*/
GArchInstruction *instr; /* Instruction décodée */
- bool inserted; /* Bilan d'une insertion */
- const mrange_t *range; /* Espace occupé par une chaîne*/
- GBinSymbol *symbol; /* Symbole à intégrer */
content = g_binary_format_get_content(G_BIN_FORMAT(format));
@@ -333,16 +330,7 @@ bool annotate_dex_string_ids(const GDexFormat *format, GPreloadInfo *info, GtkSt
{
g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
- inserted = g_preload_info_add_instruction(info, instr);
-
- if (inserted)
- {
- range = g_arch_instruction_get_range(instr);
-
- symbol = g_binary_symbol_new(range, STP_RO_STRING);
- g_binary_format_add_symbol(bformat, symbol);
-
- }
+ g_preload_info_add_instruction(info, instr);
}