summaryrefslogtreecommitdiff
path: root/src/arch/dalvik
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-10-14 16:24:34 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-10-14 16:24:34 (GMT)
commit722539ffc6005c6cd9c8ebd37f93999014ae6d24 (patch)
tree5f78dce6057f904d689c9ff073cc69f33d057abf /src/arch/dalvik
parent8dff3daac4d2dc98b90adaecea834fb65db4fb10 (diff)
Handled Dalvik simple switch cases without fallthrough.
Diffstat (limited to 'src/arch/dalvik')
-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
6 files changed, 187 insertions, 1 deletions
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
+
+ }
+
}