summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-01-30 23:37:39 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-01-30 23:37:39 (GMT)
commitd246c98c515cb44c5bc4c742a674bae2e824872b (patch)
tree2ea1ec27ae5fba761ee778ba4ddb85c7752ebbf5 /src/arch
parent262c95e0b088a56e9fd919edc57ad19f85e2e40e (diff)
Bound a symbol for each loaded value for 'ldr' instructions.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@462 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm/v7/link.c86
-rw-r--r--src/arch/context-int.h3
-rw-r--r--src/arch/context.c55
-rw-r--r--src/arch/context.h6
-rw-r--r--src/arch/raw.c70
-rw-r--r--src/arch/raw.h3
-rw-r--r--src/arch/vmpa.c28
-rw-r--r--src/arch/vmpa.h5
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 *);