summaryrefslogtreecommitdiff
path: root/src/arch/dalvik/context.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-10-10 20:03:23 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-10-10 20:03:23 (GMT)
commit8dff3daac4d2dc98b90adaecea834fb65db4fb10 (patch)
tree39a747f8fcdcbf525bb64a7e4173ff2a5b360d28 /src/arch/dalvik/context.c
parentf3e84729588f7e2e518f82116e908455d957f9ca (diff)
Handled switch and fill-array data pseudo-instructions without plugin.
Diffstat (limited to 'src/arch/dalvik/context.c')
-rw-r--r--src/arch/dalvik/context.c227
1 files changed, 174 insertions, 53 deletions
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c
index 0eb8b48..b093345 100644
--- a/src/arch/dalvik/context.c
+++ b/src/arch/dalvik/context.c
@@ -25,31 +25,39 @@
#include <malloc.h>
+#include <stdlib.h>
#include <string.h>
#include "operands/register.h"
#include "../context-int.h"
+#include "../raw.h"
+#include "../../analysis/contents/restricted.h"
+#include "../../common/sort.h"
#include "../../decomp/context-int.h"
#include "../../decomp/expr/pseudo.h"
#include "../../format/dex/dex-int.h"
-/* Mémorisation d'un saut dans le code */
-typedef struct _skipped_dalvik_area skipped_dalvik_area;
+/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */
+/* Mémorisation de données brutes dans le code */
+typedef struct _raw_data_area
+{
+ mrange_t range; /* Couverture à laisser en 1er */
-/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */
+ phys_t item_len; /* Taille de chaque élément */
+} raw_data_area;
/* Définition d'un contexte pour processeur Dalkvik (instance) */
struct _GDalvikContext
{
GProcContext parent; /* A laisser en premier */
- skipped_dalvik_area *skip; /* Liste de Zones à écarter */
+ raw_data_area *data; /* Liste de zones brutes */
size_t count; /* Taille de cette liste */
};
@@ -69,18 +77,11 @@ static void g_dalvik_context_class_init(GDalvikContextClass *);
/* Initialise une instance de contexte de processeur Dalkvik. */
static void g_dalvik_context_init(GDalvikContext *);
+/* Supprime toutes les références externes. */
+static void g_dalvik_context_dispose(GDalvikContext *);
-
-/* ------------------------- MEMORISATION DES SAUTS DE CODE ------------------------- */
-
-
-/* Mémorisation d'un saut dans le code */
-struct _skipped_dalvik_area
-{
- vmpa_t start; /* Début de la zone concernée */
- vmpa_t end; /* Fin de la zone concernée */
-
-};
+/* Procède à la libération totale de la mémoire. */
+static void g_dalvik_context_finalize(GDalvikContext *);
@@ -154,6 +155,12 @@ G_DEFINE_TYPE(GDalvikContext, g_dalvik_context, G_TYPE_PROC_CONTEXT);
static void g_dalvik_context_class_init(GDalvikContextClass *klass)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_context_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dalvik_context_finalize;
}
@@ -178,6 +185,47 @@ static void g_dalvik_context_init(GDalvikContext *ctx)
/******************************************************************************
* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_context_dispose(GDalvikContext *ctx)
+{
+ G_OBJECT_CLASS(g_dalvik_context_parent_class)->dispose(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dalvik_context_finalize(GDalvikContext *ctx)
+{
+ if (ctx->data != NULL)
+ free(ctx->data);
+
+ G_OBJECT_CLASS(g_dalvik_context_parent_class)->finalize(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
* Description : Crée un contexte pour l'exécution du processeur Dalvik. *
@@ -199,82 +247,155 @@ GDalvikContext *g_dalvik_context_new(void)
}
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage Dalvik à actualiser. *
+* start = début de la zone à considérer. *
+* length = taille de la zone couverte. *
+* *
+* Description : Mémorise une zone comme étant des données de branchements. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
-/* ---------------------------------------------------------------------------------- */
-/* MEMORISATION DES SAUTS DE CODE */
-/* ---------------------------------------------------------------------------------- */
+bool g_dalvik_context_register_switch_data(GDalvikContext *ctx, const vmpa2t *start, phys_t length)
+{
+ bool result; /* Bilan à retourner */
+ raw_data_area new; /* Nouvel élément à insérer */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ /* Vérification quant aux chevauchements */
+
+ init_mrange(&new.range, start, length);
+
+ for (i = 0; i < ctx->count && result; i++)
+ result = !mrange_intersects_mrange(&ctx->data[i].range, &new.range);
+
+ /* Insertion d'une nouvelle zone */
+
+ if (result)
+ {
+ new.item_len = 4;
+
+ ctx->data = qinsert(ctx->data, &ctx->count, sizeof(raw_data_area),
+ (__compar_fn_t)cmp_mrange_with_vmpa_swapped, &new);
+
+ }
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : ctx = instance à mettre à jour. *
-* start = début de la zone à écarter du traitement. *
-* end = fin de la zone à écarter du traitement. *
+* Paramètres : ctx = contexte de désassemblage Dalvik à actualiser. *
+* start = début de la zone à considérer. *
+* width = taille de chacun des éléments. *
+* length = taille de la zone couverte. *
* *
-* Description : Mémorise une nouvelle zone de code comme étant des données. *
+* Description : Mémorise une zone comme étant des données d'un tableau. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_dalvik_context_skip_new_area(GDalvikContext *ctx, vmpa_t start, vmpa_t end)
+bool g_dalvik_context_register_array_data(GDalvikContext *ctx, const vmpa2t *start, uint16_t width, phys_t length)
{
- ctx->skip = (skipped_dalvik_area *)realloc(ctx->skip,
- ++ctx->count * sizeof(skipped_dalvik_area));
+ bool result; /* Bilan à retourner */
+ raw_data_area new; /* Nouvel élément à insérer */
+ size_t i; /* Boucle de parcours */
+
+ result = true;
+
+ /* Vérification quant aux chevauchements */
+
+ init_mrange(&new.range, start, length);
+
+ for (i = 0; i < ctx->count && result; i++)
+ result = !mrange_intersects_mrange(&ctx->data[i].range, &new.range);
+
+ /* Insertion d'une nouvelle zone */
+
+ if (result)
+ {
+ new.item_len = width;
+
+ ctx->data = qinsert(ctx->data, &ctx->count, sizeof(raw_data_area),
+ (__compar_fn_t)cmp_mrange_with_vmpa_swapped, &new);
+
+ }
- ctx->skip[ctx->count - 1].start = start;
- ctx->skip[ctx->count - 1].end = end;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : ctx = instance à consulter. *
-* addr = adresse à mainupuler. *
+* Paramètres : ctx = contexte de désassemblage Dalvik à consulter. *
+* content = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
* *
-* Description : Indique si l'adresse est considérée comme zone de données. *
+* Description : Place une donnée en tant qu'instruction si besoin est. *
* *
-* Retour : true si l'adresse est considérée comme zone de données. *
+* Retour : Instruction mise en place ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_dalvik_context_have_to_skip(GDalvikContext *ctx, vmpa_t addr)
+GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos)
{
- bool result; /* verdict à retourner */
- size_t i; /* Boucle de parcours */
+ GArchInstruction *result; /* Instruction à retourner */
+ raw_data_area *found; /* Zone de couverture trouvée */
+ GBinContent *restricted; /* Zone de lecture effective */
- result = false;
+ result = NULL;
- for (i = 0; i < ctx->count && !result; i++)
- if (ctx->skip[i].start <= addr && addr < ctx->skip[i].end)
- {
- result = true;
- ctx->skip[i].start += sizeof(uint16_t);
+ found = bsearch(pos, ctx->data, ctx->count, sizeof(raw_data_area),
+ (__compar_fn_t)cmp_mrange_with_vmpa_swapped);
- /* BUG_ON(ctx->skip[i].start > ctx->skip[i].end) */
+ if (found)
+ {
+ restricted = g_restricted_content_new_ro(content, &found->range);
- if (ctx->skip[i].start >= ctx->skip[i].end)
- {
- if (i <= (ctx->count - 1))
- memmove(&ctx->skip[i], &ctx->skip[i + 1], ctx->count - i - 1);
+ switch (found->item_len)
+ {
+ case 1:
+ result = g_raw_instruction_new_array(restricted, MDS_8_BITS_UNSIGNED, 1, pos, SRE_LITTLE);
+ break;
- if (--ctx->count == 0)
- ctx->skip = NULL;
- else
- ctx->skip = (skipped_dalvik_area *)realloc(ctx->skip,
- ++ctx->count * sizeof(skipped_dalvik_area));
+ case 2:
+ result = g_raw_instruction_new_array(restricted, MDS_16_BITS_UNSIGNED, 1, pos, SRE_LITTLE);
+ break;
- }
+ case 4:
+ result = g_raw_instruction_new_array(restricted, MDS_32_BITS_UNSIGNED, 1, pos, SRE_LITTLE);
+ break;
+
+ case 8:
+ result = g_raw_instruction_new_array(restricted, MDS_64_BITS_UNSIGNED, 1, pos, SRE_LITTLE);
+ break;
- break;
+ default:
+ result = g_raw_instruction_new_array(restricted, MDS_8_BITS_UNSIGNED,
+ found->item_len, pos, SRE_LITTLE);
+ break;
}
+ g_object_unref(G_OBJECT(restricted));
+
+ }
+
return result;
}