diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-10-14 16:24:34 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-10-14 16:24:34 (GMT) |
commit | 722539ffc6005c6cd9c8ebd37f93999014ae6d24 (patch) | |
tree | 5f78dce6057f904d689c9ff073cc69f33d057abf /src/arch/dalvik | |
parent | 8dff3daac4d2dc98b90adaecea834fb65db4fb10 (diff) |
Handled Dalvik simple switch cases without fallthrough.
Diffstat (limited to 'src/arch/dalvik')
-rw-r--r-- | src/arch/dalvik/Makefile.am | 2 | ||||
-rw-r--r-- | src/arch/dalvik/context.c | 16 | ||||
-rw-r--r-- | src/arch/dalvik/link.c | 154 | ||||
-rw-r--r-- | src/arch/dalvik/link.h | 4 | ||||
-rw-r--r-- | src/arch/dalvik/opdefs/switch_2b.d | 6 | ||||
-rw-r--r-- | src/arch/dalvik/opdefs/switch_2c.d | 6 |
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 + + } + } |