summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/context-int.h5
-rw-r--r--src/arch/context.c127
-rw-r--r--src/arch/context.h7
-rw-r--r--src/arch/dalvik/Makefile.am2
-rw-r--r--src/arch/dalvik/context.c16
-rw-r--r--src/arch/dalvik/link.c154
-rw-r--r--src/arch/dalvik/link.h4
-rw-r--r--src/arch/dalvik/opdefs/switch_2b.d6
-rw-r--r--src/arch/dalvik/opdefs/switch_2c.d6
-rw-r--r--src/arch/link.c2
10 files changed, 327 insertions, 2 deletions
diff --git a/src/arch/context-int.h b/src/arch/context-int.h
index 1ea8b6c..df62090 100644
--- a/src/arch/context-int.h
+++ b/src/arch/context-int.h
@@ -56,6 +56,11 @@ struct _GProcContext
gint *counter;
+ GDbItem **items; /* Eléments à insérer plus tard*/
+ size_t items_allocated; /* Taille allouée à la liste */
+ size_t items_count; /* Nombre d'éléments présents */
+ GMutex items_mutex; /* Accès à la liste */
+
};
diff --git a/src/arch/context.c b/src/arch/context.c
index 979a403..dacd5ed 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -33,12 +33,22 @@
+/* Taille des blocs d'allocations */
+#define DB_ALLOC_SIZE 20
+
+
/* Initialise la classe des contextes de processeur. */
static void g_proc_context_class_init(GProcContextClass *);
/* Initialise une instance de contexte de processeur. */
static void g_proc_context_init(GProcContext *);
+/* Supprime toutes les références externes. */
+static void g_proc_context_dispose(GProcContext *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_proc_context_finalize(GProcContext *);
+
/* Ajoute une adresse virtuelle comme point de départ de code. */
static void _g_proc_context_push_drop_point(GProcContext *, DisassPriorityLevel, virt_t, va_list);
@@ -63,6 +73,13 @@ G_DEFINE_TYPE(GProcContext, g_proc_context, G_TYPE_OBJECT);
static void g_proc_context_class_init(GProcContextClass *klass)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_proc_context_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_proc_context_finalize;
+
klass->push_point = (push_drop_point_fc)_g_proc_context_push_drop_point;
g_signal_new("drop-point-pushed",
@@ -105,6 +122,56 @@ static void g_proc_context_init(GProcContext *ctx)
ctx->esyms_count = 0;
g_mutex_init(&ctx->es_access);
+ g_mutex_init(&ctx->items_mutex);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_proc_context_dispose(GProcContext *ctx)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < ctx->items_count; i++)
+ g_object_unref(G_OBJECT(ctx->items[i]));
+
+ g_mutex_clear(&ctx->items_mutex);
+
+ G_OBJECT_CLASS(g_proc_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_proc_context_finalize(GProcContext *ctx)
+{
+ if (ctx->items != NULL)
+ free(ctx->items);
+
+ G_OBJECT_CLASS(g_proc_context_parent_class)->finalize(G_OBJECT(ctx));
+
}
@@ -304,3 +371,63 @@ bool g_proc_context_pop_new_symbol_at(GProcContext *ctx, vmpa2t *addr)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage générique à consulter. *
+* item = élément pour base de données à conserver. *
+* *
+* Description : Note la mise en place d'un élément pendant le désassemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_proc_context_add_db_item(GProcContext *ctx, GDbItem *item)
+{
+ g_mutex_lock(&ctx->items_mutex);
+
+ if ((ctx->items_count + 1) > ctx->items_allocated)
+ {
+ ctx->items_allocated += DB_ALLOC_SIZE;
+
+ ctx->items = (GDbItem **)realloc(ctx->items, sizeof(GDbItem *) * ctx->items_allocated);
+
+ }
+
+ ctx->items[ctx->items_count++] = item;
+
+ g_mutex_unlock(&ctx->items_mutex);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage générique à consulter. *
+* func = fonction à appeler pour chaque élément. *
+* data = éventuelles données à associer à l'appel. *
+* *
+* Description : Effectue un traitement sur chaque élement de base de données.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_proc_context_foreach_db_item(GProcContext *ctx, GFunc func, void *data)
+{
+ size_t i; /* Boucle de parcours */
+
+ g_mutex_lock(&ctx->items_mutex);
+
+ for (i = 0; i < ctx->items_count; i++)
+ func(ctx->items[i], data);
+
+ g_mutex_unlock(&ctx->items_mutex);
+
+}
diff --git a/src/arch/context.h b/src/arch/context.h
index d8b5793..dee6d81 100644
--- a/src/arch/context.h
+++ b/src/arch/context.h
@@ -30,6 +30,7 @@
#include "vmpa.h"
+#include "../analysis/db/item.h"
@@ -78,6 +79,12 @@ void g_proc_context_push_new_symbol_at(GProcContext *, const vmpa2t *);
/* Dépile une adresse de nouveau symbole à prendre en compte. */
bool g_proc_context_pop_new_symbol_at(GProcContext *, vmpa2t *);
+/* Note la mise en place d'un élément pendant le désassemblage. */
+void g_proc_context_add_db_item(GProcContext *, GDbItem *);
+
+/* Effectue un traitement sur chaque élement de base de données. */
+void g_proc_context_foreach_db_item(GProcContext *, GFunc, void *);
+
#endif /* _ARCH_CONTEXT_H */
diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am
index f0c6ced..0d1fa88 100644
--- a/src/arch/dalvik/Makefile.am
+++ b/src/arch/dalvik/Makefile.am
@@ -8,7 +8,7 @@ libarchdalvik_la_SOURCES = \
instruction-def.h \
instruction-int.h \
instruction.h instruction.c \
- link.h \
+ link.h link.c \
operand.h operand.c \
post.h \
processor.h processor.c \
diff --git a/src/arch/dalvik/context.c b/src/arch/dalvik/context.c
index b093345..dad9008 100644
--- a/src/arch/dalvik/context.c
+++ b/src/arch/dalvik/context.c
@@ -59,6 +59,7 @@ struct _GDalvikContext
raw_data_area *data; /* Liste de zones brutes */
size_t count; /* Taille de cette liste */
+ GMutex mutex; /* Accès à la liste */
};
@@ -179,6 +180,7 @@ static void g_dalvik_context_class_init(GDalvikContextClass *klass)
static void g_dalvik_context_init(GDalvikContext *ctx)
{
+ g_mutex_init(&ctx->mutex);
}
@@ -197,6 +199,8 @@ static void g_dalvik_context_init(GDalvikContext *ctx)
static void g_dalvik_context_dispose(GDalvikContext *ctx)
{
+ g_mutex_clear(&ctx->mutex);
+
G_OBJECT_CLASS(g_dalvik_context_parent_class)->dispose(G_OBJECT(ctx));
}
@@ -269,6 +273,8 @@ bool g_dalvik_context_register_switch_data(GDalvikContext *ctx, const vmpa2t *st
result = true;
+ g_mutex_lock(&ctx->mutex);
+
/* Vérification quant aux chevauchements */
init_mrange(&new.range, start, length);
@@ -287,6 +293,8 @@ bool g_dalvik_context_register_switch_data(GDalvikContext *ctx, const vmpa2t *st
}
+ g_mutex_unlock(&ctx->mutex);
+
return result;
}
@@ -315,6 +323,8 @@ bool g_dalvik_context_register_array_data(GDalvikContext *ctx, const vmpa2t *sta
result = true;
+ g_mutex_lock(&ctx->mutex);
+
/* Vérification quant aux chevauchements */
init_mrange(&new.range, start, length);
@@ -333,6 +343,8 @@ bool g_dalvik_context_register_array_data(GDalvikContext *ctx, const vmpa2t *sta
}
+ g_mutex_unlock(&ctx->mutex);
+
return result;
}
@@ -360,6 +372,8 @@ GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinC
result = NULL;
+ g_mutex_lock(&ctx->mutex);
+
found = bsearch(pos, ctx->data, ctx->count, sizeof(raw_data_area),
(__compar_fn_t)cmp_mrange_with_vmpa_swapped);
@@ -396,6 +410,8 @@ GArchInstruction *g_dalvik_context_get_raw_data(GDalvikContext *ctx, const GBinC
}
+ g_mutex_unlock(&ctx->mutex);
+
return result;
}
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c
new file mode 100644
index 0000000..b698f03
--- /dev/null
+++ b/src/arch/dalvik/link.c
@@ -0,0 +1,154 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.c - édition des liens après la phase de désassemblage
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "link.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <stdio.h>
+
+
+#include <i18n.h>
+
+
+#include "pseudo/switch.h"
+#include "../target.h"
+
+
+
+/******************************************************************************
+* *
+* 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 tous les liens liés à un embranchement compressé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ virt_t virt; /* Adresse virtuelle */
+ vmpa2t addr; /* Adresse de destination */
+ GArchInstruction *switch_ins; /* Instruction de branchements */
+ const mrange_t *range; /* Zone d'occupation */
+ const vmpa2t *start_addr; /* Adresse de référentiel */
+ vmpa2t def_addr; /* Traitement par défaut */
+ GArchInstruction *target; /* Ligne visée par la référence*/
+ GDbComment *comment; /* Indication sur la condition */
+ const uint32_t *keys; /* Conditions de sauts */
+ const uint32_t *targets; /* Positions relatives liées */
+ uint16_t count; /* Taille de ces tableaux */
+ uint16_t i; /* Boucle de parcours */
+ char *int_val;/* Valeur en chaîne de carac. */
+
+ assert(g_arch_instruction_count_operands(instr) == 2);
+
+ op = g_arch_instruction_get_operand(instr, 1);
+
+ virt = VMPA_NO_VIRTUAL;
+
+ if (G_IS_TARGET_OPERAND(op))
+ virt = g_target_operand_get_addr(G_TARGET_OPERAND(op));
+
+ else if (G_IS_IMM_OPERAND(op))
+ {
+ if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+ virt = VMPA_NO_VIRTUAL;
+ }
+
+ if (virt != VMPA_NO_VIRTUAL)
+ {
+ /* TODO : utiliser format pour contruire une adresse avec une position physique,
+ * ce qui accélèrerait les recherches.
+ */
+ init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+ switch_ins = g_arch_processor_find_instr_by_address(proc, &addr);
+
+ if (G_IS_DALVIK_SWITCH_INSTR(switch_ins))
+ {
+ range = g_arch_instruction_get_range(instr);
+
+ start_addr = get_mrange_addr(range);
+
+ /* Cas par défaut */
+
+ compute_mrange_end_addr(range, &def_addr);
+
+ target = g_arch_processor_find_instr_by_address(proc, &def_addr);
+
+ if (target != NULL)
+ {
+ comment = g_db_comment_new_area(&def_addr, BLF_NONE, _("Defaut case"), true);
+
+ // FIXME g_db_item_set_volatile(G_DB_ITEM(comment), true);
+ g_proc_context_add_db_item(context, G_DB_ITEM(comment));
+
+ g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP);
+
+ }
+
+ /* Autres cas */
+
+ assert(G_IS_DALVIK_SWITCH_INSTR(switch_ins));
+
+ count = g_dalvik_switch_get_data(G_DALVIK_SWITCH_INSTR(switch_ins), &keys, &targets);
+
+ for (i = 0; i < count; i++)
+ {
+ copy_vmpa(&addr, start_addr);
+ advance_vmpa(&addr, targets[i] * sizeof(uint16_t));
+
+ if (cmp_vmpa(&addr, &def_addr) == 0)
+ continue;
+
+ target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+ if (target != NULL)
+ {
+ asprintf(&int_val, _("Case %d"), keys[i]);
+ comment = g_db_comment_new_area(&addr, BLF_NONE, int_val, true);
+ free(int_val);
+
+ // FIXME g_db_item_set_volatile(G_DB_ITEM(comment), true);
+ g_proc_context_add_db_item(context, G_DB_ITEM(comment));
+
+ g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP);
+
+ }
+
+ }
+
+ }
+
+ }
+
+}
diff --git a/src/arch/dalvik/link.h b/src/arch/dalvik/link.h
index 14af01d..4e4418f 100644
--- a/src/arch/dalvik/link.h
+++ b/src/arch/dalvik/link.h
@@ -40,5 +40,9 @@ static inline void handle_dalvik_ifz_branch_as_link(GArchInstruction *ins, GArch
}
+/* Etablit tous les liens liés à un embranchement compressé. */
+void handle_dalvik_packed_switch_links(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+
#endif /* _ARCH_DALVIK_LINK_H */
diff --git a/src/arch/dalvik/opdefs/switch_2b.d b/src/arch/dalvik/opdefs/switch_2b.d
index 2d13992..2ff6b33 100644
--- a/src/arch/dalvik/opdefs/switch_2b.d
+++ b/src/arch/dalvik/opdefs/switch_2b.d
@@ -27,4 +27,10 @@
@format 31t
+ @hooks {
+
+ link = handle_dalvik_packed_switch_links
+
+ }
+
}
diff --git a/src/arch/dalvik/opdefs/switch_2c.d b/src/arch/dalvik/opdefs/switch_2c.d
index b56cd9d..0a4d248 100644
--- a/src/arch/dalvik/opdefs/switch_2c.d
+++ b/src/arch/dalvik/opdefs/switch_2c.d
@@ -27,4 +27,10 @@
@format 31t
+ @hooks {
+
+ link = handle_dalvik_packed_switch_links
+
+ }
+
}
diff --git a/src/arch/link.c b/src/arch/link.c
index 48bc3a3..9f341d1 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -88,7 +88,7 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
* Remarques : - *
* *
******************************************************************************/
-#include "instruction-int.h" // REMME
+
void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format, size_t index)
{
GArchOperand *op; /* Opérande numérique en place */