diff options
-rw-r--r-- | ChangeLog | 48 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 114 | ||||
-rw-r--r-- | src/arch/arm/v7/Makefile.am | 1 | ||||
-rw-r--r-- | src/arch/arm/v7/link.c | 113 | ||||
-rw-r--r-- | src/arch/arm/v7/link.h | 41 | ||||
-rw-r--r-- | src/arch/arm/v7/post.c | 175 | ||||
-rw-r--r-- | src/arch/arm/v7/post.h | 5 | ||||
-rw-r--r-- | src/arch/arm/v7/processor.c | 7 | ||||
-rw-r--r-- | src/arch/context-int.h | 5 | ||||
-rw-r--r-- | src/arch/context.c | 108 | ||||
-rw-r--r-- | src/arch/context.h | 18 | ||||
-rw-r--r-- | src/arch/dalvik/operand.c | 16 | ||||
-rw-r--r-- | src/arch/immediate.c | 312 | ||||
-rw-r--r-- | src/arch/immediate.h | 35 | ||||
-rw-r--r-- | src/arch/instruction-int.h | 2 | ||||
-rw-r--r-- | src/arch/instruction.c | 32 | ||||
-rw-r--r-- | src/arch/instruction.h | 19 | ||||
-rw-r--r-- | src/arch/raw.c | 2 | ||||
-rw-r--r-- | src/arch/x86/operand.c | 9 | ||||
-rw-r--r-- | src/arch/x86/operands/modrm.c | 13 | ||||
-rw-r--r-- | src/arch/x86/operands/moffs.c | 3 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 7 | ||||
-rw-r--r-- | src/format/format-int.h | 2 | ||||
-rw-r--r-- | src/format/format.c | 19 | ||||
-rw-r--r-- | src/format/format.h | 3 |
25 files changed, 710 insertions, 399 deletions
@@ -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 *); |