summaryrefslogtreecommitdiff
path: root/plugins/dalvik
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/dalvik')
-rw-r--r--plugins/dalvik/Makefile.am2
-rw-r--r--plugins/dalvik/fetch.h5
-rw-r--r--plugins/dalvik/link.c2
-rw-r--r--plugins/dalvik/post.c98
-rw-r--r--plugins/dalvik/post.h4
-rw-r--r--plugins/dalvik/processor-int.h2
-rw-r--r--plugins/dalvik/processor.c38
-rw-r--r--plugins/dalvik/v35/opdefs/array_26.d7
-rw-r--r--plugins/dalvik/v35/processor.c24
9 files changed, 160 insertions, 22 deletions
diff --git a/plugins/dalvik/Makefile.am b/plugins/dalvik/Makefile.am
index 33dab13..e60b3ed 100644
--- a/plugins/dalvik/Makefile.am
+++ b/plugins/dalvik/Makefile.am
@@ -13,7 +13,7 @@ libdalvik_la_SOURCES = \
instruction.h instruction.c \
link.h link.c \
operand.h operand.c \
- post.h \
+ post.h post.c \
processor-int.h \
processor.h processor.c \
register.h register.c
diff --git a/plugins/dalvik/fetch.h b/plugins/dalvik/fetch.h
index 45e6e1c..352353c 100644
--- a/plugins/dalvik/fetch.h
+++ b/plugins/dalvik/fetch.h
@@ -36,6 +36,11 @@
void help_fetching_with_dalvik_instruction(GArchInstruction *, GArchProcessor *, GDalvikContext *, GExeFormat *, size_t);
+static inline void help_fetching_with_dalvik_fill_array_data_instruction(GArchInstruction *ins, GArchProcessor *proc, GDalvikContext *ctx, GExeFormat *fmt)
+{
+ help_fetching_with_dalvik_instruction(ins, proc, ctx, fmt, 1);
+}
+
static inline void help_fetching_with_dalvik_goto_instruction(GArchInstruction *ins, GArchProcessor *proc, GDalvikContext *ctx, GExeFormat *fmt)
{
help_fetching_with_dalvik_instruction(ins, proc, ctx, fmt, 0);
diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c
index 3b4afb1..aaed263 100644
--- a/plugins/dalvik/link.c
+++ b/plugins/dalvik/link.c
@@ -95,7 +95,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
GArchInstruction *target; /* Ligne visée par la référence*/
case_comment *comment; /* Commentaire à éditer */
uint16_t i; /* Boucle de parcours #1 */
- uint16_t j; /* Boucle de parcours #2 */
+ uint16_t j; /* Boucle de parcours #2 */
int32_t tmp; /* Sauvegarde temporaire */
char *msg; /* Indication à imprimer */
size_t k; /* Boucle de parcours #3 */
diff --git a/plugins/dalvik/post.c b/plugins/dalvik/post.c
new file mode 100644
index 0000000..4a98c64
--- /dev/null
+++ b/plugins/dalvik/post.c
@@ -0,0 +1,98 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * post.h - prototypes pour les traitements complémentaires à la phase de désassemblage
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide 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.
+ *
+ * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "post.h"
+
+
+#include <assert.h>
+
+
+#include <arch/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 = accès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void post_process_data_payload_references(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GExeFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ virt_t addr; /* Adresse visée par le saut */
+ GBinFormat *bfmt; /* Version basique du format */
+ GTargetOperand *new; /* Instruction de ciblage */
+ vmpa2t target; /* Défination finale précise */
+ mrange_t trange; /* Etendue du symbole à créer */
+ VMPA_BUFFER(loc); /* Conversion en chaîne */
+ char name[12 + VMPA_MAX_LEN]; /* Etiquette de la destination */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+ g_arch_instruction_lock_operands(instr);
+
+ op = _g_arch_instruction_get_operand(instr, 1);
+ assert(G_IS_IMM_OPERAND(op));
+
+ if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &addr)
+ && g_exe_format_translate_address_into_vmpa(format, addr, &target))
+ {
+ bfmt = G_BIN_FORMAT(format);
+
+ new = G_TARGET_OPERAND(g_target_operand_new(MDS_32_BITS_UNSIGNED, &target));
+
+ if (!g_target_operand_resolve(new, bfmt, true))
+ {
+ init_mrange(&trange, &target, 0);
+
+ vmpa2_to_string(&target, MDS_UNDEFINED, loc, NULL);
+
+ snprintf(name, sizeof(name), "array_data_%s", loc + 2);
+
+ symbol = g_binary_symbol_new(&trange, STP_CODE_LABEL);
+ g_binary_symbol_set_alt_label(symbol, name);
+
+ g_binary_format_add_symbol(bfmt, symbol);
+
+ g_target_operand_resolve(new, bfmt, true);
+
+ }
+
+ _g_arch_instruction_replace_operand(instr, op, G_ARCH_OPERAND(new));
+
+ }
+
+ g_object_unref(G_OBJECT(op));
+
+ g_arch_instruction_unlock_operands(instr);
+
+}
diff --git a/plugins/dalvik/post.h b/plugins/dalvik/post.h
index 8306b26..a31cf37 100644
--- a/plugins/dalvik/post.h
+++ b/plugins/dalvik/post.h
@@ -48,5 +48,9 @@ static inline void post_process_dalvik_ifz_target_resolution(GArchInstruction *i
}
+/* Complète un désassemblage accompli pour une instruction. */
+void post_process_data_payload_references(GArchInstruction *, GArchProcessor *, GProcContext *, GExeFormat *);
+
+
#endif /* _PLUGINS_DALVIK_POST_H */
diff --git a/plugins/dalvik/processor-int.h b/plugins/dalvik/processor-int.h
index 7568533..f4f8b3b 100644
--- a/plugins/dalvik/processor-int.h
+++ b/plugins/dalvik/processor-int.h
@@ -52,7 +52,7 @@ struct _GDalvikProcessorClass
/* Décode une pseudo-instruction dans un flux de données. */
-GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *, GDalvikContext *, const GBinContent *, vmpa2t *, uint8_t);
+GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *, GDalvikContext *, const GBinContent *, vmpa2t *, uint8_t, bool *);
diff --git a/plugins/dalvik/processor.c b/plugins/dalvik/processor.c
index 8d24d5a..3ed0507 100644
--- a/plugins/dalvik/processor.c
+++ b/plugins/dalvik/processor.c
@@ -197,12 +197,13 @@ static GDalvikDContext *g_dalvik_processor_get_decomp_context(const GDalvikProce
/******************************************************************************
* *
-* Paramètres : proc = architecture visée par la procédure. *
-* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* end = limite des données à analyser. *
-* addr = adresse virtuelle de l'instruction. *
-* low8 = 8 bits de poids faible déjà lus. *
+* Paramètres : proc = architecture visée par la procédure. *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* end = limite des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* low8 = 8 bits de poids faible déjà lus. *
+* handled = dit si une pseudo-instruction était bien là. [OUT] *
* *
* Description : Décode une pseudo-instruction dans un flux de données. *
* *
@@ -212,22 +213,25 @@ static GDalvikDContext *g_dalvik_processor_get_decomp_context(const GDalvikProce
* *
******************************************************************************/
-GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *proc, GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos, uint8_t low8)
+GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *proc, GDalvikContext *ctx, const GBinContent *content, vmpa2t *pos, uint8_t low8, bool *handled)
{
GArchInstruction *result; /* Instruction à renvoyer */
vmpa2t tmp; /* Position modifiable */
uint8_t high8; /* Nouvelle octet à venir lire */
uint16_t ident; /* Valeur lue dans le code */
- /* Vérification astucieuse et rapide...*/
- if (low8 != 0x00 /* DOP_NOP */)
- return NULL;
+ /* Définition facultative, mais bon... */
+ *handled = false;
result = NULL;
+ /* Vérification astucieuse et rapide...*/
+ if (low8 != 0x00 /* DOP_NOP */)
+ goto gdpdp_exit;
+
copy_vmpa(&tmp, pos);
- if (!g_binary_content_read_u8(content, pos, &high8))
+ if (!g_binary_content_read_u8(content, &tmp, &high8))
goto gdpdp_exit;
ident = high8 << 8 | low8;
@@ -236,11 +240,13 @@ GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *pr
{
case DPO_PACKED_SWITCH:
case DPO_SPARSE_SWITCH:
- result = g_dalvik_switch_instr_new(ident, ctx, content, pos);
+ result = g_dalvik_switch_instr_new(ident, ctx, content, &tmp);
+ *handled = true;
break;
case DPO_FILL_ARRAY_DATA:
- result = g_dalvik_fill_instr_new(ident, ctx, content, pos);
+ result = g_dalvik_fill_instr_new(ident, ctx, content, &tmp);
+ *handled = true;
break;
default:
@@ -249,11 +255,11 @@ GArchInstruction *g_dalvik_processor_disassemble_pseudo(const GArchProcessor *pr
}
- gdpdp_exit:
-
- if (result == NULL)
+ if (result != NULL)
copy_vmpa(pos, &tmp);
+ gdpdp_exit:
+
return result;
}
diff --git a/plugins/dalvik/v35/opdefs/array_26.d b/plugins/dalvik/v35/opdefs/array_26.d
index efb3261..2236500 100644
--- a/plugins/dalvik/v35/opdefs/array_26.d
+++ b/plugins/dalvik/v35/opdefs/array_26.d
@@ -35,4 +35,11 @@
@format 31t
+ @hooks {
+
+ fetch = help_fetching_with_dalvik_fill_array_data_instruction
+ post = post_process_data_payload_references
+
+ }
+
}
diff --git a/plugins/dalvik/v35/processor.c b/plugins/dalvik/v35/processor.c
index 57b8875..19141e5 100644
--- a/plugins/dalvik/v35/processor.c
+++ b/plugins/dalvik/v35/processor.c
@@ -201,6 +201,7 @@ static GArchInstruction *g_dalvik35_processor_disassemble(const GArchProcessor *
{
GArchInstruction *result; /* Instruction à renvoyer */
uint8_t raw8; /* Donnée de 8 bits à analyser */
+ bool pseudo_handled; /* Détection de pseudo-instruc.*/
Dalvik35Opcodes id; /* Identifiant d'instruction */
static const disass_instr_fc decodings[DOP35_COUNT] = {
@@ -464,6 +465,10 @@ static GArchInstruction *g_dalvik35_processor_disassemble(const GArchProcessor *
};
+ vmpa2t ttmp;
+
+ copy_vmpa(&ttmp, pos);
+
/* Données brutes associées à une instruction ? */
result = g_dalvik_context_get_raw_data(ctx, content, pos);
@@ -475,9 +480,22 @@ static GArchInstruction *g_dalvik35_processor_disassemble(const GArchProcessor *
if (!g_binary_content_read_u8(content, pos, &raw8))
return NULL;
- result = g_dalvik_processor_disassemble_pseudo(proc, ctx, content, pos, raw8);
-
- if (result != NULL) goto gdpd_done;
+ result = g_dalvik_processor_disassemble_pseudo(proc, ctx, content, pos, raw8, &pseudo_handled);
+
+ /**
+ * Il faut distinguer :
+ *
+ * - result == NULL : ce n'était pas une pseudo-instruction.
+ *
+ * - result == NULL : c'était une pseudo-instruction, mais un thread
+ * parallèle avait déjà réservé la zone de donnée correspondante.
+ *
+ * Dans ce dernier cas, on ne chercher pas à désassembler d'avantage,
+ * car une pseudo-instruction est déjà en place et on ne veut surtout pas
+ * la remplacer par une instruction basique.
+ */
+
+ if (result != NULL || pseudo_handled) goto gdpd_done;
/* ... ou instruction classique */