diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/arm/v7/link.c | 86 | ||||
-rw-r--r-- | src/arch/context-int.h | 3 | ||||
-rw-r--r-- | src/arch/context.c | 55 | ||||
-rw-r--r-- | src/arch/context.h | 6 | ||||
-rw-r--r-- | src/arch/raw.c | 70 | ||||
-rw-r--r-- | src/arch/raw.h | 3 | ||||
-rw-r--r-- | src/arch/vmpa.c | 28 | ||||
-rw-r--r-- | src/arch/vmpa.h | 5 |
8 files changed, 243 insertions, 13 deletions
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c index da5e30e..308d4e5 100644 --- a/src/arch/arm/v7/link.c +++ b/src/arch/arm/v7/link.c @@ -25,10 +25,15 @@ #include <assert.h> -#include <operands/offset.h> +#include <malloc.h> +#include <i18n.h> + + +#include "operands/offset.h" #include "../register.h" +#include "../../raw.h" @@ -347,21 +352,20 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr phys_t phys_pc; /* Position dans l'exécution */ GArchOperand *op; /* Opérande de surcouche */ GArchOperand *sub_op; /* Opérande numérique en place */ - - uint32_t offset; /* Décallage encodé en dur */ bool ret; /* Bilan d'une récupération */ - - off_t val_offset; /* Position de valeur à lire */ - - - + vmpa2t sym_addr; /* Adresse de nouveau symbole */ off_t length; /* Taille des données à lire */ const bin_t *data; /* Données binaires à lire */ - - uint32_t target; /* Adresse virtuelle visée */ + mrange_t sym_range; /* Espace du nouveau symbole */ + VMPA_BUFFER(loc); /* Adresse au format texte */ + size_t name_len; /* Taille de nomination finale */ + char *name; /* Désignation humaine */ + GArchInstruction *sym_instr; /* Instruction de symbole */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + GDbComment *comment; /* Définition de commentaire */ GArchOperand *new; /* Instruction de ciblage */ /* Récupération de l'adresse visée par le chargement */ @@ -401,13 +405,24 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr return; } - /* Lecture de la valeur vers laquelle renvoyer */ + /* Transformations et conservation d'une position de symbole */ if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op))) val_offset = phys_pc + offset; else val_offset = phys_pc - offset; + init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL); + init_mrange(&sym_range, &sym_addr, 4); + + + + + + + + + /* Lecture de la valeur vers laquelle renvoyer */ data = g_binary_format_get_content(format, &length); @@ -422,6 +437,55 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target); + + + + /* Réalise l'intégration du symbole associé */ + + sym_instr = g_raw_instruction_new_from_value(&sym_addr, MDS_32_BITS_UNSIGNED, target); + + name_len = strlen(_("Value used @ %s")) + VMPA_MAX_LEN + 1; + + name = (char *)calloc(name_len, sizeof(char)); + + vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL); + snprintf(name, name_len, _("Value used @ %s"), loc); + + ADD_RAW_AS_SYM(format, symbol, &sym_addr, sym_instr, comment, name); + + free(name); + + + + g_proc_context_push_new_symbol_at(G_PROC_CONTEXT(context), &sym_addr); + printf("repush :: from 0x%x :: %x / %x\n", + (unsigned int)get_phy_addr(get_mrange_addr(range)), + (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual); + + + printf("add sym %p\n", symbol); + + + + //g_proc_context_push_new_symbol_at(context, &sym_addr); + + + + + + + + + + + + + + + + + + //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target); diff --git a/src/arch/context-int.h b/src/arch/context-int.h index b181202..64465a2 100644 --- a/src/arch/context-int.h +++ b/src/arch/context-int.h @@ -41,6 +41,9 @@ struct _GProcContext virt_t *drop_points; /* Liste de points de départ */ size_t dp_count; /* Taille de cette liste */ + vmpa2t *extra_symbols; /* Adresses de symboles */ + size_t esyms_count; /* Nombres de nouveautés */ + }; diff --git a/src/arch/context.c b/src/arch/context.c index 794030a..5427e4a 100644 --- a/src/arch/context.c +++ b/src/arch/context.c @@ -85,6 +85,9 @@ static void g_proc_context_init(GProcContext *ctx) ctx->drop_points = NULL; ctx->dp_count = 0; + ctx->extra_symbols = NULL; + ctx->esyms_count = 0; + } @@ -205,3 +208,55 @@ virt_t g_proc_context_pop_drop_point(GProcContext *ctx) return result; } + + +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage à compléter. * +* addr = adresse d'un nouveau symbole à traiter. * +* * +* Description : Empile une adresse de nouveau symbole à prendre en compte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proc_context_push_new_symbol_at(GProcContext *ctx, const vmpa2t *addr) +{ + ctx->extra_symbols = (vmpa2t *)realloc(ctx->extra_symbols, ++ctx->esyms_count * sizeof(vmpa2t)); + + copy_vmpa(&ctx->extra_symbols[ctx->esyms_count - 1], addr); + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage à compléter. * +* addr = adresse d'un nouveau symbole à traiter. * +* * +* Description : Dépile une adresse de nouveau symbole à prendre en compte. * +* * +* Retour : true si un symbole était bien encore en stock, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_proc_context_pop_new_symbol_at(GProcContext *ctx, vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + + result = (ctx->esyms_count > 0); + + if (result) + { + ctx->esyms_count--; + copy_vmpa(addr, &ctx->extra_symbols[ctx->esyms_count]); + } + + return result; + +} diff --git a/src/arch/context.h b/src/arch/context.h index 97b23b6..390d9f9 100644 --- a/src/arch/context.h +++ b/src/arch/context.h @@ -63,6 +63,12 @@ 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 *); +/* Empile une adresse de nouveau symbole à prendre en compte. */ +void g_proc_context_push_new_symbol_at(GProcContext *, const vmpa2t *); + +/* Dépile une adresse de nouveau symbole à prendre en compte. */ +bool g_proc_context_pop_new_symbol_at(GProcContext *, vmpa2t *); + #endif /* _ARCH_CONTEXT_H */ diff --git a/src/arch/raw.c b/src/arch/raw.c index e76d75d..62c88c1 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -169,6 +169,76 @@ static void g_raw_instruction_finalize(GRawInstruction *instr) /****************************************************************************** * * +* Paramètres : addr = position à associer à l'instruction. * +* size = taille de l'opérande souhaitée. * +* value = valeur sur x bits à venir récupérer. * +* * +* Description : Crée une instruction de type 'db/dw/etc' simple. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value) +{ + GArchInstruction *result; /* Instruction à retourner */ + GArchOperand *operand; /* Octet non décodé à afficher */ + mrange_t range; /* Couverture de l'instruction */ + + result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); + + operand = g_imm_operand_new_from_value(size, value); + if (operand == NULL) goto grinfv_error; + + g_imm_operand_pad(G_IMM_OPERAND(operand), true); + + g_arch_instruction_attach_extra_operand(result, operand); + + switch (size) + { + case MDS_8_BITS_UNSIGNED: + case MDS_8_BITS_SIGNED: + init_mrange(&range, addr, 1); + break; + + case MDS_16_BITS_UNSIGNED: + case MDS_16_BITS_SIGNED: + init_mrange(&range, addr, 2); + break; + + case MDS_32_BITS_UNSIGNED: + case MDS_32_BITS_SIGNED: + init_mrange(&range, addr, 4); + break; + + case MDS_64_BITS_UNSIGNED: + case MDS_64_BITS_SIGNED: + init_mrange(&range, addr, 8); + break; + + default: + goto grinfv_error; + break; + + } + + g_arch_instruction_set_range(result, &range); + + return result; + + grinfv_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + +/****************************************************************************** +* * * Paramètres : data = flux de données à analyser. * * size = taille de chacun des éléments à représenter. * * count = nombre de ces éléments. * diff --git a/src/arch/raw.h b/src/arch/raw.h index ce324f5..8ae9a74 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -52,6 +52,9 @@ typedef struct _GRawInstructionClass GRawInstructionClass; /* Indique le type défini pour une instruction inconnue d'architecture. */ GType g_raw_instruction_get_type(void); +/* Crée une instruction de type 'db/dw/etc' simple. */ +GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *, MemoryDataSize, uint64_t); + /* Crée une instruction de type 'db/dw/etc' étendue. */ GArchInstruction *g_raw_instruction_new_array(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index b306f00..46d1a04 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -685,7 +685,12 @@ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) if (ret <= -1) { diff = compute_vmpa_diff(&range->addr, addr); - result = (diff < range->length); + + if (diff != VMPA_NO_PHYSICAL) + result = (diff < range->length); + else + result = false; + } else if (ret == 0) @@ -701,6 +706,27 @@ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) /****************************************************************************** * * +* Paramètres : range = zone mémoire à consulter. * +* addr = localisation mémoire à déterminer. * +* * +* Description : Calcule la position extérieure final d'une couverture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void compute_mrange_end_addr(const mrange_t *range, vmpa2t *addr) +{ + copy_vmpa(addr, &range->addr); + advance_vmpa(addr, range->length); + +} + + +/****************************************************************************** +* * * Paramètres : rane = emplacement virtuel ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * start = indique si le début ou la fin est à imprimer. * diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 6f8e809..97b2610 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -148,7 +148,7 @@ typedef struct _mrange_t /* Initialise une plage dans l'espace mémoire/physique. */ -void init_mrange(mrange_t *, const vmpa2t *, phys_t ); +void init_mrange(mrange_t *, const vmpa2t *, phys_t); /* Copie la définition d'une plage mémoire dans une autre. */ void copy_mrange(mrange_t *, const mrange_t *); @@ -162,6 +162,9 @@ bool mrange_contains_mrange(const mrange_t *, const mrange_t *); /* Indique si une localisation est incluse dans une zone ou non. */ bool mrange_contains_addr(const mrange_t *, const vmpa2t *); +/* Calcule la position extérieure final d'une couverture. */ +void compute_mrange_end_addr(const mrange_t *, vmpa2t *); + /* Transforme un emplacement physique en chaîne de caractères. */ char *mrange_phys_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); |