summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog48
-rw-r--r--src/analysis/disass/fetch.c114
-rw-r--r--src/arch/arm/v7/Makefile.am1
-rw-r--r--src/arch/arm/v7/link.c113
-rw-r--r--src/arch/arm/v7/link.h41
-rw-r--r--src/arch/arm/v7/post.c175
-rw-r--r--src/arch/arm/v7/post.h5
-rw-r--r--src/arch/arm/v7/processor.c7
-rw-r--r--src/arch/context-int.h5
-rw-r--r--src/arch/context.c108
-rw-r--r--src/arch/context.h18
-rw-r--r--src/arch/dalvik/operand.c16
-rw-r--r--src/arch/immediate.c312
-rw-r--r--src/arch/immediate.h35
-rw-r--r--src/arch/instruction-int.h2
-rw-r--r--src/arch/instruction.c32
-rw-r--r--src/arch/instruction.h19
-rw-r--r--src/arch/raw.c2
-rw-r--r--src/arch/x86/operand.c9
-rw-r--r--src/arch/x86/operands/modrm.c13
-rw-r--r--src/arch/x86/operands/moffs.c3
-rw-r--r--src/format/elf/symbols.c7
-rw-r--r--src/format/format-int.h2
-rw-r--r--src/format/format.c19
-rw-r--r--src/format/format.h3
25 files changed, 710 insertions, 399 deletions
diff --git a/ChangeLog b/ChangeLog
index a75ae31..9f1a780 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+14-12-25 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/fetch.c:
+ Prepare a new way to disassemble code.
+
+ * src/arch/arm/v7/link.c:
+ * src/arch/arm/v7/link.h:
+ New entries: define links between some kinds of instructions.
+
+ * src/arch/arm/v7/Makefile.am:
+ Add the 'link.[ch]' files to libarcharmv7_la_SOURCES.
+
+ * src/arch/arm/v7/post.c:
+ * src/arch/arm/v7/post.h:
+ Clean and update code for symbols resolutions.
+
+ * src/arch/arm/v7/processor.c:
+ Register new hooks for instructions processing.
+
+ * src/arch/context.c:
+ * src/arch/context.h:
+ * src/arch/context-int.h:
+ Prepare a new way to disassemble code.
+
+ * src/arch/dalvik/operand.c:
+ Update code.
+
+ * src/arch/immediate.c:
+ * src/arch/immediate.h:
+ Clean all the code for immediate operands.
+
+ * src/arch/instruction.c:
+ * src/arch/instruction.h:
+ * src/arch/instruction-int.h:
+ Refine hooks registered for processing instructions.
+
+ * src/arch/raw.c:
+ * src/arch/x86/operand.c:
+ * src/arch/x86/operands/modrm.c:
+ * src/arch/x86/operands/moffs.c:
+ Update code.
+
+ * src/format/elf/symbols.c:
+ * src/format/format.c:
+ * src/format/format.h:
+ * src/format/format-int.h:
+ Provide the address of the found entry point.
+
14-12-24 Cyrille Bagard <nocbos@gmail.com>
* src/arch/arm/v7/opcodes/Makefile.am:
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index dea6645..1fd5550 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -434,8 +434,10 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
+ g_arch_instruction_call_hook(instr, IPH_LINK, NULL, format);
- g_arch_instruction_call_post_prod_function(instr, format); /* FIXME */
+
+ g_arch_instruction_call_hook(instr, IPH_POST, NULL, format);
@@ -447,6 +449,116 @@ static GArchInstruction *load_code_binary(const GLoadedBinary *binary, const vmp
}
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = représentation de binaire chargé. *
+* statusbar = barre de statut avec progression à mettre à jour.*
+* id = identifiant du message affiché à l'utilisateur. *
+* *
+* Description : Procède au désassemblage basique d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchInstruction *follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area *areas, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+{
+ GBinFormat *format; /* Format du fichier binaire */
+
+ virt_t addr;
+
+
+
+ mem_area *area; /* Zone de désassemblage */
+
+
+ format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+
+ /* Insertion du point de départ */
+
+ addr = g_binary_format_get_entry_point(format);
+
+ g_proc_context_push_drop_point(ctx, addr);
+
+ /* Suivi de l'exécution autant que possible */
+
+ while (g_proc_context_has_drop_points(ctx))
+ {
+ //virt = g_proc_context_pop_drop_point(ctx);
+
+
+ area = NULL;
+
+
+
+
+ }
+
+
+
+
+ // ctx.add(entry_point)
+
+ // while (ctx.has_pending_addresses)
+
+ // virt = ctx.pop
+ // find mem_area for virt
+
+ // if area.limit < virt then continue
+
+
+
+
+
+}
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = représentation de binaire chargé. *
+* statusbar = barre de statut avec progression à mettre à jour.*
+* id = identifiant du message affiché à l'utilisateur. *
+* *
+* Description : Procède au désassemblage basique d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *disassemble_binary_content_new(const GLoadedBinary *binary, GtkExtStatusBar *statusbar, bstatus_id_t id)
+{
+
+ GBinFormat *format; /* Format du fichier binaire */
+ GArchProcessor *proc; /* Architecture du binaire */
+
+ GProcContext *ctx; /* Contexte de désassemblage */
+
+
+
+ format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+ proc = get_arch_processor_from_format(G_EXE_FORMAT(format));
+
+
+ ctx = g_arch_processor_get_context(proc);
+
+
+
+}
+
+
+
/******************************************************************************
* *
* Paramètres : binary = représentation de binaire chargé. *
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am
index 704b3a6..28a899e 100644
--- a/src/arch/arm/v7/Makefile.am
+++ b/src/arch/arm/v7/Makefile.am
@@ -5,6 +5,7 @@ libarcharmv7_la_SOURCES = \
arm.h arm.c \
helpers.h helpers.c \
instruction.h instruction.c \
+ link.h link.c \
post.h post.c \
processor.h processor.c \
pseudo.h pseudo.c \
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
new file mode 100644
index 0000000..278b8d0
--- /dev/null
+++ b/src/arch/arm/v7/link.c
@@ -0,0 +1,113 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * post.c - traitements complémentaires à la phase de désassemblage
+ *
+ * Copyright (C) 2014 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>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+ const mrange_t *range; /* Emplacementt d'instruction */
+ virt_t pc; /* Position dans l'exécution */
+ GArchOperand *op; /* Opérande numérique en place */
+ int32_t offset; /* Décallage encodé en dur */
+
+ range = g_arch_instruction_get_range(instr);
+
+ pc = get_virt_addr(get_mrange_addr(range));
+
+ /**
+ * Qu'on se trouve en mode Thumb ou ARM, l'instruction
+ * ne peut qu'être encodée sur 4 octets.
+ */
+
+ assert(get_mrange_length(range) == 4);
+
+ pc += 4;
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+ g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+ const mrange_t *range; /* Emplacementt d'instruction */
+ virt_t pc; /* Position dans l'exécution */
+ GArchOperand *op; /* Opérande numérique en place */
+ int32_t offset; /* Décallage encodé en dur */
+
+ range = g_arch_instruction_get_range(instr);
+
+ pc = get_virt_addr(get_mrange_addr(range));
+
+ /**
+ * Qu'on se trouve en mode Thumb ou ARM, l'instruction
+ * ne peut qu'être encodée sur 4 octets.
+ */
+
+ assert(get_mrange_length(range) == 4);
+
+ pc += 4;
+ pc -= pc % 4;
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+ g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+}
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
new file mode 100644
index 0000000..79da9f3
--- /dev/null
+++ b/src/arch/arm/v7/link.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.h - prototypes pour l'édition des liens durant la phase de désassemblage
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+
+#ifndef _ARCH_ARM_V7_LINK_H
+#define _ARCH_ARM_V7_LINK_H
+
+
+#include "../../instruction.h"
+#include "../../../format/format.h"
+
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_thumb_instruction_bl(GArchInstruction *, GProcContext *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_thumb_instruction_blx(GArchInstruction *, GProcContext *, GBinFormat *);
+
+
+
+#endif /* _ARCH_ARM_V7_LINK_H */
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index 8ba12d8..f85fc91 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -24,19 +24,15 @@
#include "post.h"
-
-
-
#include "../../target.h"
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction ARMv7 à traiter. *
-* format = acès aux données du binaire d'origine. *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* 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. *
* *
@@ -46,22 +42,11 @@
* *
******************************************************************************/
-void post_process_thumb_instruction_bl(GArchInstruction *instr, GBinFormat *format)
+void post_process_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
{
-
-
- const mrange_t *range;
-
- virt_t pc;
-
-
-
-
-
- GArchOperand *op;
- vmpa_t val;
- GArchOperand *new;
-
+ GArchOperand *op; /* Opérande numérique en place */
+ uint32_t addr; /* Adresse visée par le saut */
+ GArchOperand *new; /* Instruction de ciblage */
vmpa2t target;
mrange_t trange;
VMPA_BUFFER(loc);
@@ -69,148 +54,38 @@ void post_process_thumb_instruction_bl(GArchInstruction *instr, GBinFormat *form
GBinRoutine *routine; /* Nouvelle routine trouvée */
GBinSymbol *symbol; /* Nouveau symbole construit */
-
-
-
- range = g_arch_instruction_get_range(instr);
-
- pc = get_virt_addr(get_mrange_addr(range)) + 4 /* PC++ */;
- printf(" -- PC = 0x%x\n", (unsigned int)pc);
-
-
op = g_arch_instruction_get_operand(instr, 0);
- g_imm_operand_to_vmpa_t(G_IMM_OPERAND(op), &val);
-
- printf(" -> %llx = %lld ==>> 0x%x\n", val, val, (unsigned int)(pc + val));
-
-
-
- new = g_target_operand_new(MDS_32_BITS, pc + val);
-
- if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
{
- init_vmpa(&target, VMPA_NO_PHYSICAL, pc + val);
- init_mrange(&trange, &target, 0);
-
- vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
- snprintf(name, sizeof(name), "loc_%s", loc + 2);
-
- routine = g_binary_routine_new();
- g_binary_routine_set_name(routine, strdup(name));
- //routine = try_to_demangle_routine(name);
-
- g_binary_routine_set_range(routine, &trange);
-
- symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
- g_binary_symbol_attach_routine(symbol, routine);
- g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+ new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
+ if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+ {
+ init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
+ init_mrange(&trange, &target, 0);
+ vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
+ snprintf(name, sizeof(name), "loc_%s", loc + 2);
- g_target_operand_resolve(G_TARGET_OPERAND(new), format);
+ routine = g_binary_routine_new();
+ g_binary_routine_set_name(routine, strdup(name));
+ //routine = try_to_demangle_routine(name);
+ g_binary_routine_set_range(routine, &trange);
- }
-
-
- g_arch_instruction_replace_operand(instr, new, op);
- //g_arch_instruction_attach_extra_operand(result, new);
+ symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
+ g_binary_symbol_attach_routine(symbol, routine);
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
-}
-
-
+ g_target_operand_resolve(G_TARGET_OPERAND(new), format);
+ }
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction ARMv7 à traiter. *
-* format = acès aux données du binaire d'origine. *
-* *
-* Description : Complète un désassemblage accompli pour une instruction. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void post_process_thumb_instruction_blx(GArchInstruction *instr, GBinFormat *format)
-{
-
-
-
-
-
- const mrange_t *range;
-
- virt_t pc;
-
-
-
- GArchOperand *op;
- vmpa_t val;
- GArchOperand *new;
-
- vmpa2t target;
- mrange_t trange;
- VMPA_BUFFER(loc);
- char name[5 + VMPA_MAX_LEN];
- GBinRoutine *routine; /* Nouvelle routine trouvée */
- GBinSymbol *symbol; /* Nouveau symbole construit */
-
-
-
- range = g_arch_instruction_get_range(instr);
-
- pc = get_virt_addr(get_mrange_addr(range)) + 4 /* PC++ */;
-
- printf(" -- PC = 0x%x -> 0x%x\n", (unsigned int)pc, (unsigned int)pc - pc % 4);
- pc = pc - pc % 4;
-
- op = g_arch_instruction_get_operand(instr, 0);
-
- g_imm_operand_to_vmpa_t(G_IMM_OPERAND(op), &val);
-
- printf(" -> %llx = %lld ==>> 0x%x\n", val, val, (unsigned int)(pc + val));
-
-
-
- new = g_target_operand_new(MDS_32_BITS, pc + val);
-
- if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
- {
- init_vmpa(&target, VMPA_NO_PHYSICAL, pc + val);
- init_mrange(&trange, &target, 0);
-
- vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
- snprintf(name, sizeof(name), "loc_%s", loc + 2);
-
- routine = g_binary_routine_new();
- g_binary_routine_set_name(routine, strdup(name));
- //routine = try_to_demangle_routine(name);
-
- g_binary_routine_set_range(routine, &trange);
-
- symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
- g_binary_symbol_attach_routine(symbol, routine);
- g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
-
-
-
- g_target_operand_resolve(G_TARGET_OPERAND(new), format);
-
+ g_arch_instruction_replace_operand(instr, new, op);
}
- g_arch_instruction_replace_operand(instr, new, op);
- //g_arch_instruction_attach_extra_operand(result, new);
-
-
-
-
}
-
diff --git a/src/arch/arm/v7/post.h b/src/arch/arm/v7/post.h
index d9ad99e..dec51b2 100644
--- a/src/arch/arm/v7/post.h
+++ b/src/arch/arm/v7/post.h
@@ -31,10 +31,7 @@
/* Complète un désassemblage accompli pour une instruction. */
-void post_process_thumb_instruction_bl(GArchInstruction *, GBinFormat *);
-
-/* Complète un désassemblage accompli pour une instruction. */
-void post_process_thumb_instruction_blx(GArchInstruction *, GBinFormat *);
+void post_process_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c
index 2b8617b..4ae933b 100644
--- a/src/arch/arm/v7/processor.c
+++ b/src/arch/arm/v7/processor.c
@@ -200,6 +200,7 @@ GArmV7Processor *g_armv7_processor_new(void)
* Remarques : - *
* *
******************************************************************************/
+#include "link.h"
#include "post.h"
static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmContext *ctx, const bin_t *data, vmpa2t *pos, phys_t end)
{
@@ -269,7 +270,8 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
{
- g_arch_instruction_set_post_prod_function(result, post_process_thumb_instruction_bl);
+ g_arch_instruction_set_hook(result, IPH_LINK, handle_links_with_thumb_instruction_bl);
+ g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
@@ -278,7 +280,8 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
if (strcmp(g_arch_instruction_get_keyword(result, 0), "blx") == 0/* && pc == 0x000085b2*/)
{
- g_arch_instruction_set_post_prod_function(result, post_process_thumb_instruction_blx);
+ g_arch_instruction_set_hook(result, IPH_LINK, handle_links_with_thumb_instruction_blx);
+ g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
}
diff --git a/src/arch/context-int.h b/src/arch/context-int.h
index 39d0278..3a65f79 100644
--- a/src/arch/context-int.h
+++ b/src/arch/context-int.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* context-int.h - prototypes internes pour le contexte lié à l'exécution d'un processeur
*
- * Copyright (C) 2011 Cyrille Bagard
+ * Copyright (C) 2011-2014 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -34,6 +34,9 @@ struct _GProcContext
{
GObject parent; /* A laisser en premier */
+ virt_t *drop_points; /* Liste de points de départ */
+ size_t dp_count; /* Taille de cette liste */
+
};
diff --git a/src/arch/context.c b/src/arch/context.c
index 220ed14..46c4dd1 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* context.c - contexte lié à l'exécution d'un processeur
*
- * Copyright (C) 2011 Cyrille Bagard
+ * Copyright (C) 2011-2014 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -24,6 +24,11 @@
#include "context.h"
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
#include "context-int.h"
@@ -73,5 +78,106 @@ static void g_proc_context_class_init(GProcContextClass *klass)
static void g_proc_context_init(GProcContext *ctx)
{
+ ctx->drop_points = NULL;
+ ctx->dp_count = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage à compléter. *
+* addr = adresse d'un nouveau point de départ à traiter. *
+* *
+* Description : Ajoute une adresse virtuelle comme point de départ de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr)
+{
+ ctx->drop_points = (virt_t *)realloc(ctx->drop_points, ++ctx->dp_count * sizeof(virt_t));
+
+ ctx->drop_points[ctx->dp_count - 1] = addr;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage à consulter. *
+* *
+* Description : Indique si des points de départ restent à traiter ou non. *
+* *
+* Retour : true s'il existe encore au moins un point, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_proc_context_has_drop_points(const GProcContext *ctx)
+{
+ return ctx->dp_count > 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage à consulter. *
+* addr = adresse de mémoire virtuelle à rechercher. *
+* *
+* Description : Précise si une adresse donnée figure comme point de départ. *
+* *
+* Retour : true si l'adresse est connue en interne, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_proc_context_has_addr_as_drop_points(const GProcContext *ctx, virt_t addr)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = false;
+
+ for (i = 0; i < ctx->dp_count && !result; i++)
+ result = (ctx->drop_points[i] == addr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage à compléter. *
+* *
+* Description : Fournit une adresse virtuelle comme point de départ de code. *
+* *
+* Retour : Adresse d'un point de départ de code à traiter. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+virt_t g_proc_context_pop_drop_point(GProcContext *ctx)
+{
+ virt_t result; /* Adresse à retourner */
+
+ assert(ctx->dp_count > 0);
+
+ result = ctx->drop_points[0];
+
+ if (ctx->dp_count > 1)
+ memmove(&ctx->drop_points[0], &ctx->drop_points[1], (ctx->dp_count - 1) * sizeof(virt_t));
+
+ ctx->drop_points = (virt_t *)realloc(ctx->drop_points, --ctx->dp_count * sizeof(virt_t));
+
+ return result;
}
diff --git a/src/arch/context.h b/src/arch/context.h
index 0632970..9bb7cd3 100644
--- a/src/arch/context.h
+++ b/src/arch/context.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* context.h - prototypes pour le contexte lié à l'exécution d'un processeur
*
- * Copyright (C) 2011 Cyrille Bagard
+ * Copyright (C) 2011-2014 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -26,6 +26,10 @@
#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "vmpa.h"
@@ -47,6 +51,18 @@ typedef struct _GProcContextClass GProcContextClass;
/* Indique le type définit par la GLib pour le contexte de processeur. */
GType g_proc_context_get_type(void);
+/* Ajoute une adresse virtuelle comme point de départ de code. */
+void g_proc_context_push_drop_point(GProcContext *, virt_t);
+
+/* Indique si des points de départ restent à traiter ou non. */
+bool g_proc_context_has_drop_points(const GProcContext *);
+
+/* Précise si une adresse donnée figure comme point de départ. */
+bool g_proc_context_has_addr_as_drop_points(const GProcContext *, virt_t);
+
+/* Fournit une adresse virtuelle comme point de départ de code. */
+virt_t g_proc_context_pop_drop_point(GProcContext *);
+
#endif /* _ARCH_CONTEXT_H */
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c
index ee033e7..a63369c 100644
--- a/src/arch/dalvik/operand.c
+++ b/src/arch/dalvik/operand.c
@@ -24,6 +24,7 @@
#include "operand.h"
+#include <assert.h> // REMME (assert(0))
#include <malloc.h>
#include <stdarg.h>
@@ -298,23 +299,28 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const GDexFormat
break;
case DOI_IMMEDIATE_4:
- op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, end, low, endian);
+ assert(0);
+ //op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, end, low, endian);
break;
case DOI_IMMEDIATE_8:
- op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, end, endian);
+ assert(0);
+ //op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, end, endian);
break;
case DOI_IMMEDIATE_16:
- op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, end, endian);
+ assert(0);
+ //op = g_imm_operand_new_from_data(MDS_16_BITS, data, pos, end, endian);
break;
case DOI_IMMEDIATE_32:
- op = g_imm_operand_new_from_data(MDS_32_BITS, data, pos, end, endian);
+ assert(0);
+ //op = g_imm_operand_new_from_data(MDS_32_BITS, data, pos, end, endian);
break;
case DOI_IMMEDIATE_64:
- op = g_imm_operand_new_from_data(MDS_64_BITS, data, pos, end, endian);
+ assert(0);
+ //op = g_imm_operand_new_from_data(MDS_64_BITS, data, pos, end, endian);
break;
case DOI_IMMEDIATE_H16:
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index f8ef432..4d0c0b8 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -43,6 +43,7 @@ struct _GImmOperand
GArchOperand parent; /* Instance parente */
MemoryDataSize size; /* Taille de l'opérande */
+ uint64_t raw; /* Valeur transtypée */
/**
* Note : dans le cas d'une valeur signée,
@@ -197,7 +198,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)
* *
* Paramètres : size = taille de l'opérande souhaitée. *
* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
+* addr = position courante dans ce flux. [OUT] *
* end = limite des données à analyser. *
* low = position éventuelle des 4 bits visés. [OUT] *
* endian = ordre des bits dans la source. *
@@ -210,64 +211,87 @@ static void g_imm_operand_finalize(GImmOperand *operand)
* *
******************************************************************************/
-GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t end, bool *low, SourceEndian endian)
+GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
{
GImmOperand *result; /* Opérande à retourner */
+ off_t old; /* Ancienne tête de lecture */
+ off_t pos; /* Position physique */
+ uint8_t uval8; /* Valeur sur 8 bits */
+ uint16_t uval16; /* Valeur sur 16 bits */
+ uint32_t uval32; /* Valeur sur 32 bits */
+ uint64_t uval64; /* Valeur sur 64 bits */
+ int8_t sval8; /* Valeur sur 8 bits */
+ int16_t sval16; /* Valeur sur 16 bits */
+ int32_t sval32; /* Valeur sur 32 bits */
+ int64_t sval64; /* Valeur sur 64 bits */
result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
result->size = size;
+ pos = get_phy_addr(addr);
+ old = pos;
+
switch (size)
{
case MDS_4_BITS_UNSIGNED:
- if (!read_u4(&result->unsigned_imm.val8, data, pos, end, low, endian))
+ if (!read_u4(&uval8, data, &pos, end, low, endian))
goto gionfd_error;
+ result->raw = uval8;
break;
case MDS_8_BITS_UNSIGNED:
- if (!read_u8(&result->unsigned_imm.val8, data, pos, end, endian))
+ if (!read_u8(&uval8, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval8;
break;
case MDS_16_BITS_UNSIGNED:
- if (!read_u16(&result->unsigned_imm.val16, data, pos, end, endian))
+ if (!read_u16(&uval16, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval16;
break;
case MDS_32_BITS_UNSIGNED:
- if (!read_u32(&result->unsigned_imm.val32, data, pos, end, endian))
+ if (!read_u32(&uval32, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval32;
break;
case MDS_64_BITS_UNSIGNED:
- if (!read_u64(&result->unsigned_imm.val64, data, pos, end, endian))
+ if (!read_u64(&uval64, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval64;
break;
case MDS_4_BITS_SIGNED:
- if (!read_s4(&result->signed_imm.val8, data, pos, end, low, endian))
+ if (!read_s4(&sval8, data, &pos, end, low, endian))
goto gionfd_error;
+ result->raw = sval8;
break;
case MDS_8_BITS_SIGNED:
- if (!read_s8(&result->signed_imm.val8, data, pos, end, endian))
+ if (!read_s8(&sval8, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval8;
break;
case MDS_16_BITS_SIGNED:
- if (!read_s16(&result->signed_imm.val16, data, pos, end, endian))
+ if (!read_s16(&sval16, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval16;
break;
case MDS_32_BITS_SIGNED:
- if (!read_s32(&result->signed_imm.val32, data, pos, end, endian))
+ if (!read_s32(&sval32, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval32;
break;
case MDS_64_BITS_SIGNED:
- if (!read_s64(&result->signed_imm.val64, data, pos, end, endian))
+ if (!read_s64(&sval64, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval64;
break;
case MDS_UNDEFINED:
@@ -276,6 +300,8 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
}
+ advance_vmpa(addr, pos - old);
+
return G_ARCH_OPERAND(result);
gionfd_error:
@@ -287,17 +313,10 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
}
-
-
-
/******************************************************************************
* *
-* Paramètres : size = taille de l'opérande souhaitée. *
-* data = flux de données à analyser. *
-* addr = position courante dans ce flux. [OUT] *
-* end = limite des données à analyser. *
-* low = position éventuelle des 4 bits visés. [OUT] *
-* endian = ordre des bits dans la source. *
+* Paramètres : size = taille de l'opérande souhaitée. *
+* value = valeur sur x bits à venir récupérer. *
* *
* Description : Crée un opérande réprésentant une valeur numérique. *
* *
@@ -307,121 +326,70 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
* *
******************************************************************************/
-GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
+GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
{
GImmOperand *result; /* Opérande à retourner */
- off_t old; /* Ancienne tête de lecture */
- off_t pos; /* Position physique */
- result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
-
- result->size = size;
-
- pos = get_phy_addr(addr);
- old = pos;
-
- switch (size)
- {
- case MDS_4_BITS_UNSIGNED:
- if (!read_u4(&result->unsigned_imm.val8, data, &pos, end, low, endian))
- goto gionfd_error;
- break;
-
- case MDS_8_BITS_UNSIGNED:
- if (!read_u8(&result->unsigned_imm.val8, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_16_BITS_UNSIGNED:
- if (!read_u16(&result->unsigned_imm.val16, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_32_BITS_UNSIGNED:
- if (!read_u32(&result->unsigned_imm.val32, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_64_BITS_UNSIGNED:
- if (!read_u64(&result->unsigned_imm.val64, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_4_BITS_SIGNED:
- if (!read_s4(&result->signed_imm.val8, data, &pos, end, low, endian))
- goto gionfd_error;
- break;
-
- case MDS_8_BITS_SIGNED:
- if (!read_s8(&result->signed_imm.val8, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_16_BITS_SIGNED:
- if (!read_s16(&result->signed_imm.val16, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_32_BITS_SIGNED:
- if (!read_s32(&result->signed_imm.val32, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_64_BITS_SIGNED:
- if (!read_s64(&result->signed_imm.val64, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_UNDEFINED:
- goto gionfd_error;
- break;
+ if (size == MDS_UNDEFINED) return NULL;
- }
+ result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
- advance_vmpa(addr, pos - old);
+ g_imm_operand_set_value(result, size, value);
return G_ARCH_OPERAND(result);
- gionfd_error:
+}
- g_object_unref(G_OBJECT(result));
- return NULL;
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* *
+* Description : Renseigne la taille de la valeur indiquée à la construction. *
+* *
+* Retour : Taille de la valeur représentée en mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+{
+ return operand->size;
}
/******************************************************************************
* *
-* Paramètres : size = taille de l'opérande souhaitée. *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* size = taille de l'opérande souhaitée. *
* ... = valeur sur x bits à venir récupérer. *
* *
-* Description : Crée un opérande réprésentant une valeur numérique. *
+* Description : Fournit la valeur portée par une opérande numérique. *
* *
-* Retour : Instruction mise en place. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
+bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)
{
- GImmOperand *result; /* Opérande à retourner */
+ bool result; /* Bilan à retourner */
va_list ap; /* Liste des compléments */
- uint8_t uval8; /* Valeur sur 8 bits */
- uint16_t uval16; /* Valeur sur 16 bits */
- uint32_t uval32; /* Valeur sur 32 bits */
- uint64_t uval64; /* Valeur sur 64 bits */
- int8_t sval8; /* Valeur sur 8 bits */
- int16_t sval16; /* Valeur sur 16 bits */
- int32_t sval32; /* Valeur sur 32 bits */
- int64_t sval64; /* Valeur sur 64 bits */
+ uint8_t *uval8; /* Valeur sur 8 bits */
+ uint16_t *uval16; /* Valeur sur 16 bits */
+ uint32_t *uval32; /* Valeur sur 32 bits */
+ uint64_t *uval64; /* Valeur sur 64 bits */
+ int8_t *sval8; /* Valeur sur 8 bits */
+ int16_t *sval16; /* Valeur sur 16 bits */
+ int32_t *sval32; /* Valeur sur 32 bits */
+ int64_t *sval64; /* Valeur sur 64 bits */
- if (size == MDS_UNDEFINED) return NULL;
+ if (operand->size != size) return false;
- result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
-
- result->size = size;
+ result = true;
va_start(ap, size);
@@ -429,65 +397,73 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
{
/* Pour GCC... */
case MDS_UNDEFINED:
+ result = false;
break;
case MDS_4_BITS_UNSIGNED:
case MDS_8_BITS_UNSIGNED:
- uval8 = (uint8_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val8 = uval8;
+ uval8 = va_arg(ap, uint8_t *);
+ *uval8 = operand->raw;
break;
case MDS_16_BITS_UNSIGNED:
- uval16 = (uint16_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val16 = uval16;
+ uval16 = va_arg(ap, uint16_t *);
+ *uval16 = operand->raw;
break;
case MDS_32_BITS_UNSIGNED:
- uval32 = (uint32_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val32 = uval32;
+ uval32 = va_arg(ap, uint32_t *);
+ *uval32 = operand->raw;
break;
case MDS_64_BITS_UNSIGNED:
- uval64 = (uint64_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val64 = uval64;
+ uval64 = va_arg(ap, uint64_t *);
+ *uval64 = operand->raw;
break;
case MDS_4_BITS_SIGNED:
case MDS_8_BITS_SIGNED:
- sval8 = (int8_t)va_arg(ap, int);
- result->signed_imm.val8 = sval8;
+ sval8 = va_arg(ap, int8_t *);
+ *sval8 = operand->raw;
break;
case MDS_16_BITS_SIGNED:
- sval16 = (int16_t)va_arg(ap, int);
- result->signed_imm.val16 = sval16;
+ sval16 = va_arg(ap, int16_t *);
+ *sval16 = operand->raw;
break;
case MDS_32_BITS_SIGNED:
- sval32 = (int32_t)va_arg(ap, int);
- result->signed_imm.val32 = sval32;
+ sval32 = va_arg(ap, int32_t *);
+ *sval32 = operand->raw;
break;
case MDS_64_BITS_SIGNED:
- sval64 = (int64_t)va_arg(ap, int);
- result->signed_imm.val64 = sval64;
+ sval64 = va_arg(ap, int64_t *);
+ *sval64 = operand->raw;
break;
}
va_end(ap);
- return G_ARCH_OPERAND(result);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : operand = structure dont le contenu est à consulter. *
+* Paramètres : operand = structure dont le contenu est à mettre à jour. *
+* size = taille de l'opérande souhaitée. *
+* value = valeur sur x bits à venir récupérer. *
* *
-* Description : Renseigne la taille de la valeur indiquée à la construction. *
+* Description : Définit la nouvelle valeur de l'opérande à une valeur. *
* *
-* Retour : Taille de la valeur représentée en mémoire. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+bool g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
{
- return operand->size;
+ if (size == MDS_UNDEFINED) return false;
+
+ operand->size = size;
+ operand->raw = value;
+
+ return true;
}
@@ -589,19 +565,15 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
switch (operand->size)
{
case MDS_4_BITS_SIGNED:
- result = (operand->signed_imm.val8 & 0x08);
- break;
case MDS_8_BITS_SIGNED:
- result = (operand->signed_imm.val8 & 0x80);
- break;
case MDS_16_BITS_SIGNED:
- result = (operand->signed_imm.val16 & 0x8000);
- break;
case MDS_32_BITS_SIGNED:
- result = (operand->signed_imm.val32 & 0x80000000);
- break;
case MDS_64_BITS_SIGNED:
- result = (operand->signed_imm.val64 & 0x8000000000000000ll);
+ /**
+ * Pour les valeurs plus petites que 64 bits, le compilateur
+ * réalise une extension de signe lors du transtypage.
+ */
+ result = (operand->raw & 0x8000000000000000ll);
break;
default:
result = false;
@@ -627,46 +599,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
bool g_imm_operand_is_null(const GImmOperand *operand)
{
- bool result; /* Bilan à renvoyer */
-
- switch (operand->size)
- {
- case MDS_4_BITS_SIGNED:
- result = !(operand->signed_imm.val8 & 0x0f);
- break;
- case MDS_4_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val8 & 0x0f);
- break;
- case MDS_8_BITS_SIGNED:
- result = !(operand->signed_imm.val8 & 0xff);
- break;
- case MDS_8_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val8 & 0xff);
- break;
- case MDS_16_BITS_SIGNED:
- result = !(operand->signed_imm.val16 & 0xffff);
- break;
- case MDS_16_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val16 & 0xffff);
- break;
- case MDS_32_BITS_SIGNED:
- result = !(operand->signed_imm.val32 & 0xffffffff);
- break;
- case MDS_32_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val32 & 0xffffffff);
- break;
- case MDS_64_BITS_SIGNED:
- result = !(operand->signed_imm.val64 & 0xffffffffffffffffll);
- break;
- case MDS_64_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val64 & 0xffffffffffffffffll);
- break;
- default:
- result = false;
- break;
- }
-
- return result;
+ return (operand->raw == 0ll);
}
@@ -750,43 +683,43 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
break;
case MDS_4_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint8_t)operand->raw);
break;
case MDS_8_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint8_t)operand->raw);
break;
case MDS_16_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint16_t)operand->raw);
break;
case MDS_32_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint32_t)operand->raw);
break;
case MDS_64_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint64_t)operand->raw);
break;
case MDS_4_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int8_t)operand->raw);
break;
case MDS_8_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int8_t)operand->raw);
break;
case MDS_16_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int16_t)operand->raw);
break;
case MDS_32_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int32_t)operand->raw);
break;
case MDS_64_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int64_t)operand->raw);
break;
}
@@ -857,7 +790,6 @@ bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr)
*addr = operand->unsigned_imm.val64;
break;
default:
- *addr = operand->signed_imm.val32;//////
result = false;
break;
}
diff --git a/src/arch/immediate.h b/src/arch/immediate.h
index 99d1b7f..a218c16 100644
--- a/src/arch/immediate.h
+++ b/src/arch/immediate.h
@@ -27,6 +27,7 @@
#include <glib-object.h>
#include <stdbool.h>
+#include <stdint.h>
#include "archbase.h"
@@ -46,10 +47,12 @@ typedef enum _ImmOperandDisplay
} ImmOperandDisplay;
-#define G_TYPE_IMM_OPERAND g_imm_operand_get_type()
-#define G_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_imm_operand_get_type(), GImmOperand))
-#define G_IS_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_imm_operand_get_type()))
-#define G_IMM_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_imm_operand_get_type(), GImmOperandIface))
+#define G_TYPE_IMM_OPERAND g_imm_operand_get_type()
+#define G_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_imm_operand_get_type(), GImmOperand))
+#define G_IS_IMM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_imm_operand_get_type()))
+#define G_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_IMM_OPERAND, GImmOperandClass))
+#define G_IS_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_IMM_OPERAND))
+#define G_IMM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_IMM_OPERAND, GImmOperandClass))
/* Définition d'un opérande de valeur numérique (instance) */
@@ -63,21 +66,23 @@ typedef struct _GImmOperandClass GImmOperandClass;
GType g_imm_operand_get_type(void);
/* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, off_t *, off_t, bool *, SourceEndian);
+GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian);
-#define g_imm_operand_new_from_data(size, data, pos, len, endian) _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian)
+#define g_imm_operand_new_from_data(size, data, pos, len, endian) \
+ _g_imm_operand_new_from_data(size, data, pos, len, NULL, endian)
/* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize, const bin_t *, vmpa2t *, off_t, bool *, SourceEndian);
-
-#define g_imm_operand_new_from_data2(size, data, pos, len, endian) _g_imm_operand_new_from_data2(size, data, pos, len, NULL, endian)
-
-/* Crée un opérande réprésentant une valeur numérique. */
-GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, ...);
+GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, uint64_t);
/* Renseigne la taille de la valeur indiquée à la construction. */
MemoryDataSize g_imm_operand_get_size(const GImmOperand *);
+/* Fournit la valeur portée par une opérande numérique. */
+bool g_imm_operand_get_value(const GImmOperand *, MemoryDataSize, ...);
+
+/* Définit la nouvelle valeur de l'opérande à une valeur. */
+bool g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t);
+
/* Précise si des zéro doivent compléter l'affichage ou non. */
void g_imm_operand_pad(GImmOperand *, bool);
@@ -97,13 +102,13 @@ bool g_imm_operand_is_negative(const GImmOperand *);
bool g_imm_operand_is_null(const GImmOperand *);
/* Convertit une valeur immédiate en adresse de type vmpa_t. */
-bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *);
+bool g_imm_operand_to_vmpa_t(const GImmOperand *, vmpa_t *) __attribute__ ((deprecated));
/* Convertit une valeur immédiate en valeur de type size_t. */
-bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *);
+bool g_imm_operand_to_size_t(const GImmOperand *, size_t *, bool *) __attribute__ ((deprecated));
/* Convertit une valeur immédiate en valeur de type off_t. */
-bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *);
+bool g_imm_operand_to_off_t(const GImmOperand *, off_t *, bool *) __attribute__ ((deprecated));
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index aedd468..5bdcedb 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -58,7 +58,7 @@ struct _GArchInstruction
const char *suffix; /* Complément au nom affiché */
char *cached_keyword; /* Désignation complète */
- instr_post_prod_fc post_prod; /* A remplacer par un signal... */
+ instr_hook_fc hooks[IPH_COUNT]; /* Traitements complémentaires */
mrange_t range; /* Emplacement en mémoire */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index a96f0e4..598da6d 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -24,6 +24,7 @@
#include "instruction.h"
+#include <assert.h>
#include <stdarg.h>
#include <string.h>
@@ -168,9 +169,10 @@ void g_arch_instruction_append_suffix(GArchInstruction *instr, const char *suffi
/******************************************************************************
* *
* Paramètres : instr = instruction quelconque à modifier. *
-* post = fonction à appeler sur commande. *
+* type = type de procédure à mémoriser. *
+* hook = fonction à appeler sur commande. *
* *
-* Description : Définit une fonction de post-traitement après désassemblage. *
+* Description : Définit un traitement complémentare au désassemblage. *
* *
* Retour : - *
* *
@@ -178,17 +180,21 @@ void g_arch_instruction_append_suffix(GArchInstruction *instr, const char *suffi
* *
******************************************************************************/
-void g_arch_instruction_set_post_prod_function(GArchInstruction *instr, instr_post_prod_fc post)
+void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type, instr_hook_fc hook)
{
- instr->post_prod = post;
+ assert(type < IPH_COUNT);
+
+ instr->hooks[type] = hook;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à traiter. *
-* data = données éventuelles associées à l'opération. *
+* Paramètres : instr = instruction quelconque à traiter. *
+* type = type de procédure à utiliser. *
+* 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. *
* *
@@ -198,16 +204,14 @@ void g_arch_instruction_set_post_prod_function(GArchInstruction *instr, instr_po
* *
******************************************************************************/
-void g_arch_instruction_call_post_prod_function(GArchInstruction *instr, void *data)
+void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GProcContext *context, GBinFormat *format)
{
- if (instr->post_prod != NULL)
- instr->post_prod(instr, data);
-
-}
-
-
+ assert(type < IPH_COUNT);
+ if (instr->hooks[type] != NULL)
+ instr->hooks[type](instr, context, format);
+}
/******************************************************************************
@@ -338,6 +342,8 @@ GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size
if (index >= instr->operands_count) result = NULL;
else result = instr->operands[index];
+ /* TODO : incrémenter la référence ! */
+
return result;
}
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 7b9fe66..5657f73 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -28,6 +28,7 @@
#include <sys/types.h>
+#include "context.h"
#include "immediate.h"
#include "register.h"
#include "vmpa.h"
@@ -60,16 +61,24 @@ GType g_arch_instruction_get_type(void);
/* Etend la désignation d'un nom d'instruction. */
void g_arch_instruction_append_suffix(GArchInstruction *, const char *);
-/* Complète un désassemblage accompli pour une instruction. */
-typedef void (* instr_post_prod_fc)(GArchInstruction *, void *);
+/* Types de crochet de traitement */
+typedef enum _InstrProcessHook
+{
+ IPH_LINK, /* Edition des liens */
+ IPH_POST, /* Résolution des symboles */
-/* Définit une fonction de post-traitement après désassemblage. */
-void g_arch_instruction_set_post_prod_function(GArchInstruction *, instr_post_prod_fc);
+ IPH_COUNT
+
+} InstrProcessHook;
/* Complète un désassemblage accompli pour une instruction. */
-void g_arch_instruction_call_post_prod_function(GArchInstruction *, void *);
+typedef void (* instr_hook_fc) (GArchInstruction *, GProcContext *, GBinFormat *);
+/* Définit un traitement complémentare au désassemblage. */
+void g_arch_instruction_set_hook(GArchInstruction *, InstrProcessHook, instr_hook_fc);
+/* Complète un désassemblage accompli pour une instruction. */
+void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GProcContext *, GBinFormat *);
/* Définit la localisation d'une instruction. */
void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *);
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 9b13dac..e76d75d 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -201,7 +201,7 @@ GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize
for (i = 0; i < count; i++)
{
- operand = g_imm_operand_new_from_data2(size, data, addr, end, endian);
+ operand = g_imm_operand_new_from_data(size, data, addr, end, endian);
if (operand == NULL) goto grina_error;
g_imm_operand_pad(G_IMM_OPERAND(operand), true);
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index cf3af50..8eb79dc 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -117,16 +117,19 @@ bool _x86_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos,
switch (types[i])
{
case X86_OTP_IMM8:
- op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
break;
case X86_OTP_IMM16:
- op = g_imm_operand_new_from_data(MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //op = g_imm_operand_new_from_data(MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
break;
case X86_OTP_IMM1632:
if (oprsize == MDS_UNDEFINED) oprsize = va_arg(ap, MemoryDataSize);
- op = g_imm_operand_new_from_data(oprsize == MDS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //op = g_imm_operand_new_from_data(oprsize == MDS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
break;
case X86_OTP_MOFFS8:
diff --git a/src/arch/x86/operands/modrm.c b/src/arch/x86/operands/modrm.c
index 6c70762..1da734f 100644
--- a/src/arch/x86/operands/modrm.c
+++ b/src/arch/x86/operands/modrm.c
@@ -136,7 +136,9 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,
if (g_x86_register_is_base_pointer(reg) && mod == 0x00)
{
/* FIXME *///free_x86_register(reg);
- return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);
+ assert(0);
+ return NULL;
+ //return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);
}
result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL);
@@ -176,19 +178,22 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,
/* FIXME *///free_x86_register(result->base);
result->base = NULL;
- result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);
if (result->displacement == NULL) goto gxmron_error;
}
break;
case 0x40:
- result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);
if (result->displacement == NULL) goto gxmron_error;
break;
case 0x80:
- result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);
if (result->displacement == NULL) goto gxmron_error;
break;
diff --git a/src/arch/x86/operands/moffs.c b/src/arch/x86/operands/moffs.c
index 55e758d..689a400 100644
--- a/src/arch/x86/operands/moffs.c
+++ b/src/arch/x86/operands/moffs.c
@@ -116,7 +116,8 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,
result = NULL;
- offset = g_imm_operand_new_from_data(size, data, pos, len, SRE_LITTLE /* FIXME */);
+ assert(0);
+ //offset = g_imm_operand_new_from_data(size, data, pos, len, SRE_LITTLE /* FIXME */);
if (offset != NULL)
{
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 30bdcca..d69e41a 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -141,10 +141,15 @@ bool load_elf_symbols(GElfFormat *format)
result = load_elf_internal_symbols(format);
#endif
+
+
entry_point = ELF_HDR(format, format->header, e_entry);
+ G_BIN_FORMAT(format)->entry_point = entry_point;
+
+
- printf("E_ENTRY : 0x%08lx\n", (unsigned long)entry_point);
+ printf("E_ENTRY : 0x%08lx\n", (unsigned long)entry_point);
if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
entry_point &= ~0x1;
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 95e171d..21a97b3 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -44,6 +44,8 @@ struct _GBinFormat
const bin_t *content; /* Contenu binaire à étudier */
off_t length; /* Taille de ce contenu */
+ virt_t entry_point; /* Point d'entrée dans le code */
+
GBinSymbol **symbols; /* Liste des symboles trouvés */
size_t symbols_count; /* Quantité de ces symboles */
diff --git a/src/format/format.c b/src/format/format.c
index cb43a94..8e1b9f4 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -180,6 +180,25 @@ const bin_t *g_binary_format_get_content(const GBinFormat *format, off_t *length
/******************************************************************************
* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* *
+* Description : Fournit l'adresse mémoire du point d'entrée d'un binaire. *
+* *
+* Retour : Adresse de mémoire virtuelle, voire VMPA_NO_VIRTUAL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+virt_t g_binary_format_get_entry_point(const GBinFormat *format)
+{
+ return format->entry_point;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = informations chargées à compléter. *
* symbol = symbole à ajouter à la liste. *
* *
diff --git a/src/format/format.h b/src/format/format.h
index 3c74b50..364f71a 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -58,6 +58,9 @@ GType g_binary_format_get_type(void);
/* Fournit une référence vers le contenu binaire analysé. */
const bin_t *g_binary_format_get_content(const GBinFormat *, off_t *);
+/* Fournit l'adresse mémoire du point d'entrée d'un binaire. */
+virt_t g_binary_format_get_entry_point(const GBinFormat *);
+
/* Ajoute un symbole à la collection du format binaire. */
void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);