summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-11-29 09:33:00 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-11-29 09:33:00 (GMT)
commit97d1cc10210cf4ec237e1d9a8b23b120ddef47c5 (patch)
treebe02d0c99cd02917ca31541f4ff0aafa9b9903fc
parentb4d1a25a22371fa67c5d73bc8fcca08e045556f3 (diff)
Displayed segments in the disassembly view.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@429 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog23
-rw-r--r--src/analysis/disass/output.c31
-rw-r--r--src/arch/instruction.c2
-rw-r--r--src/format/elf/elf.c4
-rw-r--r--src/format/executable.c56
-rw-r--r--src/format/executable.h3
-rw-r--r--src/glibext/gbinportion.c161
-rw-r--r--src/glibext/gbinportion.h10
-rw-r--r--src/glibext/gbufferline.c38
-rw-r--r--src/glibext/gbufferline.h3
10 files changed, 317 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index d4d129a..41501e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+14-11-29 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/output.c:
+ Display segments in the disassembly view.
+
+ * src/arch/instruction.c:
+ Typo.
+
+ * src/format/elf/elf.c:
+ Quote segments names.
+
+ * src/format/executable.c:
+ * src/format/executable.h:
+ Find all binary portions and sort them.
+
+ * src/glibext/gbinportion.c:
+ * src/glibext/gbinportion.h:
+ Add a depth level to portions and allow to sort them.
+
+ * src/glibext/gbufferline.c:
+ * src/glibext/gbufferline.h:
+ Provide a way to fill the addresses columns quickly.
+
14-11-25 Cyrille Bagard <nocbos@gmail.com>
* src/dialogs/binparts.c:
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index a6d7845..2007f48 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -70,13 +70,15 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
GBufferLine *line;
+ GBinPortion **portions; /* Morceaux d'encadrement */
+ size_t portions_count; /* Taille de cette liste */
+ size_t portion_index; /* Prochaine portion à traiter */
GBinSymbol **symbols; /* Symboles à représenter */
size_t sym_count; /* Qté de symboles présents */
-
-
size_t sym_index; /* Prochain symbole non traité */
+ const vmpa2t *paddr; /* Adresse de portion */
GDbComment *comment; /* Commentaire à ajouter */
@@ -91,11 +93,15 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
output = g_asm_output_new();
- symbols = g_binary_format_get_symbols(format, &sym_count);
+
+ portions = g_exe_format_get_portions_at_level(format, -1, &portions_count);
+ portion_index = 0;
+ symbols = g_binary_format_get_symbols(format, &sym_count);
sym_index = 0;
+
//GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures);
@@ -133,6 +139,22 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
#endif
+ iaddr = get_mrange_addr(g_arch_instruction_get_range(iter));
+
+ while (portion_index < portions_count)
+ {
+ paddr = get_mrange_addr(g_binary_portion_get_range(portions[portion_index]));
+
+ if (cmp_vmpa_by_phy(iaddr, paddr) != 0)
+ break;
+
+ g_binary_portion_print(portions[portion_index], buffer, msize);
+
+ portion_index++;
+
+ }
+
+
line = g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL);
@@ -178,6 +200,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
}
+
+ /* free portions... */
+
g_object_unref(G_OBJECT(output));
}
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index f649150..d91e110 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -671,6 +671,7 @@ const char *g_arch_instruction_get_keyword(const GArchInstruction *instr, AsmSyn
* *
* Paramètres : instr = instruction d'assemblage à représenter. *
* buffer = espace où placer ledit contenu. *
+* msize = taille idéale des positions et adresses; *
* syntax = type de représentation demandée. *
* *
* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
@@ -724,6 +725,7 @@ static GBufferLine *_g_arch_instruction_print(const GArchInstruction *instr, GCo
* *
* Paramètres : instr = instruction d'assemblage à représenter. *
* buffer = espace où placer ledit contenu. *
+* msize = taille idéale des positions et adresses; *
* syntax = type de représentation demandée. *
* *
* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 64708ee..6d2138a 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -345,7 +345,7 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
new = g_binary_portion_new(background);
- sprintf(desc, "%s %s",
+ sprintf(desc, "%s \"%s\"",
_("Segment"),
get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type)));
@@ -391,7 +391,7 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *
else name = NULL;
if (name != NULL)
- sprintf(desc, "%s %s", _("Section"), name);
+ sprintf(desc, "%s \"%s\"", _("Section"), name);
else
sprintf(desc, "%s ???", _("Section"));
diff --git a/src/format/executable.c b/src/format/executable.c
index ea1b398..0ae6934 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -162,6 +162,62 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *format)
/******************************************************************************
* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* level = étage des portions à considérer ou -1 pour tous. *
+* count = nombre de portions trouvées et renvoyées. [OUT] *
+* *
+* Description : Fournit une liste choisie de portions d'un binaire. *
+* *
+* Retour : Liste de définitins de zones à libérer après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *format, unsigned int level, size_t *count)
+{
+ GBinPortion **result; /* Liste à retourner */
+
+ typedef struct _portions_list
+ {
+ unsigned int required;
+ GBinPortion **portions;
+ size_t length;
+
+ } portions_list;
+
+ portions_list list; /* Sauvegarde de la liste */
+
+ bool visit_for_level(GBinPortion *portion, portions_list *list)
+ {
+ if (list->required == -1 || g_binary_portion_get_level(portion) == list->required)
+ {
+ list->portions = (GBinPortion **)realloc(list->portions, ++list->length * sizeof(GBinPortion *));
+ list->portions[list->length - 1] = portion;
+ }
+
+ return true;
+
+ }
+
+ list.required = level;
+ list.portions = NULL;
+ list.length = 0;
+
+ g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_level, &list);
+
+ result = list.portions;
+ *count = list.length;
+
+ qsort(result, *count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = informations chargées à consulter. *
* count = quantité de zones listées. [OUT] *
* *
diff --git a/src/format/executable.h b/src/format/executable.h
index 10bff42..28ac201 100644
--- a/src/format/executable.h
+++ b/src/format/executable.h
@@ -78,6 +78,9 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *);
/* Décrit les différentes portions qui composent le binaire. */
GBinPortion *g_exe_format_get_portions(GExeFormat *);
+/* Fournit une liste choisie de portions d'un binaire. */
+GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *, unsigned int, size_t *);
+
/* Fournit les espaces mémoires des portions exécutables. */
mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count);
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index 94a04cc..1fbb460 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -44,6 +44,7 @@ struct _GBinPortion
{
GObject parent; /* A laisser en premier */
+ unsigned int level; /* Profondeur de la portion */
GBinPortion *container; /* Portion parente ou racine */
char *code; /* Code de la couleur de fond */
@@ -51,8 +52,8 @@ struct _GBinPortion
char *desc; /* Désignation humaine */
mrange_t range; /* Emplacement dans le code */
- vmpa2t addr; /* Emplacement dans le code */
- off_t size; /* Taille de la partie */
+ vmpa2t addr; /* Emplacement dans le code */ /* TODO : clean */
+ off_t size; /* Taille de la partie */ /* TODO : clean */
PortionAccessRights rights; /* Droits d'accès */
@@ -86,6 +87,9 @@ static void g_binary_portion_dispose(GBinPortion *);
/* Procède à la libération totale de la mémoire. */
static void g_binary_portion_finalize(GBinPortion *);
+/* Définit le niveau de profondeur pour une branche de portions. */
+static void g_binary_portion_set_level(GBinPortion *, unsigned int);
+
/* Détermine l'aire d'une sous-portion. */
static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, const GdkRectangle *, GdkRectangle *);
@@ -139,6 +143,7 @@ static void g_binary_portion_class_init(GBinPortionClass *klass)
static void g_binary_portion_init(GBinPortion *portion)
{
+ portion->level = 0;
}
@@ -221,6 +226,37 @@ GBinPortion *g_binary_portion_new(const char *code)
/******************************************************************************
* *
+* Paramètres : a = premières informations à consulter. *
+* b = secondes informations à consulter. *
+* *
+* Description : Etablit la comparaison ascendante entre deux portions. *
+* *
+* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int g_binary_portion_compare(const GBinPortion **a, const GBinPortion **b)
+{
+ int result; /* Bilan à retourner */
+
+ if ((*a)->level < (*b)->level)
+ result = -1;
+
+ else if ((*a)->level > (*b)->level)
+ result = 1;
+
+ else
+ result = cmp_mrange(&(*a)->range, &(*b)->range);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : portion = description de partie à mettre à jour. *
* desc = nom à donner à la partie. *
* *
@@ -362,6 +398,52 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub)
portion->sub_portions[portion->sub_count - 1] = sub;
+ g_binary_portion_set_level(sub, portion->level + 1);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* level = niveau de profondeur à associer. *
+* *
+* Description : Définit le niveau de profondeur pour une branche de portions.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_binary_portion_set_level(GBinPortion *portion, unsigned int level)
+{
+ size_t i; /* Boucle de parcours */
+
+ portion->level = level;
+
+ for (i = 0; i < portion->sub_count; i++)
+ g_binary_portion_set_level(portion->sub_portions[i], level + 1);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : portion = description de partie à mettre à jour. *
+* *
+* Description : Indique le niveau de profondeur d'une portion donnée. *
+* *
+* Retour : Niveau de profondeur positif ou nul. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+unsigned int g_binary_portion_get_level(GBinPortion *portion)
+{
+ return portion->level;
+
}
@@ -603,6 +685,81 @@ bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, const vmpa2t *addr
/******************************************************************************
* *
+* Paramètres : portion = description de partie à consulter. *
+* buffer = espace où placer ledit contenu. *
+* msize = taille idéale des positions et adresses; *
+* *
+* Description : Insère dans un tampon une description de portion. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, MemoryDataSize msize)
+{
+ GBufferLine *line; /* Nouvelle ligne à éditer */
+ char rights[64]; /* Traduction en texte */
+
+ /* On ne traite pas les portions anonymes ! */
+ if (portion->desc == NULL) return;
+
+ line = g_code_buffer_append_new_line(buffer, &portion->range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ /* Séparation */
+
+ line = g_code_buffer_append_new_line(buffer, &portion->range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD,
+ "; ======================================================", 56, RTT_COMMENT);
+
+ /* Retour à la ligne */
+
+ line = g_code_buffer_append_new_line(buffer, &portion->range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+
+ /* Description */
+
+ line = g_code_buffer_append_new_line(buffer, &portion->range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT);
+
+ snprintf(rights, sizeof(rights), " (%s%s%s%s)",
+ _("rights: "),
+ portion->rights & PAC_READ ? "r" : "-",
+ portion->rights & PAC_WRITE ? "w" : "-",
+ portion->rights & PAC_EXEC ? "x" : "-");
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT);
+
+ /* Retour à la ligne */
+
+ line = g_code_buffer_append_new_line(buffer, &portion->range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+ g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT);
+
+ line = g_code_buffer_append_new_line(buffer, &portion->range);
+ g_buffer_line_fill_mrange(line, msize, msize);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : portion = description de partie à mettre à jour. *
* x = abscisse du point de recherche. *
* y = ordonnée du point de recherche. *
diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h
index ac6b4fd..f92b87e 100644
--- a/src/glibext/gbinportion.h
+++ b/src/glibext/gbinportion.h
@@ -30,6 +30,7 @@
#include <gtk/gtk.h>
+#include "gcodebuffer.h"
#include "../arch/vmpa.h"
#include "../common/fnv1a.h"
@@ -82,6 +83,9 @@ GType g_binary_portion_get_type(void);
/* Crée une description de partie de code vierge. */
GBinPortion *g_binary_portion_new(const char *);
+/* Etablit la comparaison ascendante entre deux portions. */
+int g_binary_portion_compare(const GBinPortion **, const GBinPortion **);
+
/* Attribue une description humaine à une partie de code. */
void g_binary_portion_set_desc(GBinPortion *, const char *);
@@ -103,6 +107,9 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *);
/* Procède à l'inclusion d'une portion dans une autre. */
void g_binary_portion_include(GBinPortion *, GBinPortion *);
+/* Indique le niveau de profondeur d'une portion donnée. */
+unsigned int g_binary_portion_get_level(GBinPortion *);
+
/* Parcours un ensemble de portions binaires. */
bool g_binary_portion_visit(GBinPortion *, visit_portion_fc, void *);
@@ -118,6 +125,9 @@ bool g_binary_portion_get_addr_from_pos(GBinPortion *, gint, const GdkRectangle
/* Fournit l'adresse correspondant à une position donnée. */
bool g_binary_portion_get_pos_from_addr(GBinPortion *, const vmpa2t *, const GdkRectangle *, gint *);
+/* Insère dans un tampon une description de portion. */
+void g_binary_portion_print(const GBinPortion *, GCodeBuffer *, MemoryDataSize);
+
/* Prépare une astuce concernant une portion pour son affichage. */
gboolean g_binary_portion_query_tooltip(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *);
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 6970dac..a71ef9d 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -468,6 +468,36 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
/******************************************************************************
* *
+* Paramètres : line = ligne à venir compléter. *
+* psize = taille souhaitée de l'impression des positions. *
+* vsize = taille souhaitée de l'impression des adresses. *
+* *
+* Description : Construit le tronc commun d'une ligne autour de sa position. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize)
+{
+ size_t len; /* Taille de l'élément inséré */
+ VMPA_BUFFER(address); /* Adresse au format texte */
+
+ /* Adresse physique puis virtuelle */
+
+ mrange_phys_to_string(&line->range, psize, true, address, &len);
+ g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW);
+
+ mrange_virt_to_string(&line->range, vsize, true, address, &len);
+ g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne à venir compléter. *
* psize = taille souhaitée de l'impression des positions. *
* vsize = taille souhaitée de l'impression des adresses. *
@@ -485,8 +515,6 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize, const bin_t *content, off_t length, bool full)
{
- size_t len; /* Taille de l'élément inséré */
- VMPA_BUFFER(address); /* Adresse au format texte */
size_t required; /* Taille de traitement requise*/
char static_buffer[64]; /* Petit tampon local rapide */
char *bin_code; /* Tampon utilisé pour le code */
@@ -501,11 +529,7 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor
/* Adresse physique puis virtuelle */
- mrange_phys_to_string(&line->range, psize, true, address, &len);
- g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW);
-
- mrange_virt_to_string(&line->range, vsize, true, address, &len);
- g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW);
+ g_buffer_line_fill_mrange(line, psize, vsize);
/* Détermination du réceptacle */
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 5a45fe2..f6ee171 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -93,6 +93,9 @@ GBufferLine *g_buffer_line_new(const mrange_t *, BufferLineColumn);
/* Indique la zone mémoire où se situe la ligne. */
const mrange_t *g_buffer_line_get_range(const GBufferLine *);
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_mrange(GBufferLine *, MemoryDataSize, MemoryDataSize);
+
/* Construit le tronc commun d'une ligne d'instruction. */
void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, const bin_t *, off_t, bool);