From 2d95ce74200c8cb7c328535235a8c8e74686794e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 2 Jan 2010 01:48:30 +0000 Subject: Provided ways to load, save and edit some binary parts selection. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@141 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 28 ++++ src/analysis/binary.c | 2 +- src/analysis/binary.h | 2 +- src/dialogs/Makefile.am | 16 +++ src/dialogs/binparts.c | 327 ++++++++++++++++++++++++++++++++++---------- src/dialogs/binparts.h | 2 +- src/editor.c | 2 +- src/format/elf/elf.c | 34 ++++- src/format/elf/section.c | 40 ++++++ src/format/elf/section.h | 3 + src/format/executable-int.h | 6 +- src/format/executable.c | 23 +++- src/format/executable.h | 3 + src/format/part.c | 29 ++++ src/format/part.h | 3 + 15 files changed, 437 insertions(+), 83 deletions(-) create mode 100644 src/dialogs/Makefile.am diff --git a/ChangeLog b/ChangeLog index f5f5ab2..1a1ff62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +10-01-02 Cyrille Bagard + + * src/analysis/binary.c: + * src/analysis/binary.h: + Fix the prototype of the function giving access to disassembled parts. + + * src/dialogs/binparts.c: + * src/dialogs/binparts.h: + Load, save and edit some binary parts selection. + + * src/dialogs/Makefile.am: + News entry: add this missing file. + + * src/editor.c: + Fix a call. + + * src/format/elf/elf.c: + * src/format/elf/section.c: + * src/format/elf/section.h: + * src/format/executable.c: + * src/format/executable.h: + * src/format/executable-int.h: + Provide a way to translate addresses into file positions. + + * src/format/part.c: + * src/format/part.h: + Create a function to dump parts. + 09-12-13 Cyrille Bagard * src/analysis/binary.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 56265f2..58979d0 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -1044,7 +1044,7 @@ void g_openida_binary_set_parts(GOpenidaBinary *binary, BinaryPartModel model, G * * ******************************************************************************/ -GBinPart **g_openida_binary_get_parts(const GOpenidaBinary *binary, BinaryPartModel *model, size_t *count) +GBinPart ***g_openida_binary_get_parts(const GOpenidaBinary *binary, BinaryPartModel *model, size_t **count) { *model = binary->model; *count = binary->parts_count; diff --git a/src/analysis/binary.h b/src/analysis/binary.h index d195fef..533264b 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -78,7 +78,7 @@ bool g_openida_binary_save(const GOpenidaBinary *, xmlDocPtr, xmlXPathContextPtr void g_openida_binary_set_parts(GOpenidaBinary *, BinaryPartModel, GBinPart **, size_t); /* Fournit les parties de binaire analysées. */ -GBinPart **g_openida_binary_get_parts(const GOpenidaBinary *, BinaryPartModel *, size_t *); +GBinPart ***g_openida_binary_get_parts(const GOpenidaBinary *, BinaryPartModel *, size_t **); /* Lance l'analyse d'un élément binaire chargé. */ void g_openida_binary_analyse(GOpenidaBinary *); diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am new file mode 100644 index 0000000..181f418 --- /dev/null +++ b/src/dialogs/Makefile.am @@ -0,0 +1,16 @@ + +lib_LIBRARIES = libdialogs.a + +libdialogs_a_SOURCES = \ + binparts.h binparts.c + +libdialogs_a_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/dialogs/binparts.c b/src/dialogs/binparts.c index 1135348..a88232e 100644 --- a/src/dialogs/binparts.c +++ b/src/dialogs/binparts.c @@ -24,6 +24,9 @@ #include "binparts.h" +#include + + #include "../format/format.h" #include "../gtkext/easygtk.h" @@ -46,7 +49,6 @@ typedef enum _PartsColumn } PartsColumn; - /* Mémoire d'un modèle */ typedef struct _parts_model { @@ -56,15 +58,17 @@ typedef struct _parts_model } parts_model; +/* Sélectionne ou non tous les éléments de la liste courante. */ +static void select_all_items_or_none(GtkButton *, GObject *); +/* Sauvegarde l'état courant des sélections et clôt la fenêtre. */ +static void save_current_selection(GtkButton *, GObject *); +/* Ferme la fenêtre de dialogue. */ +static void close_editor(GtkButton *, GtkWidget *); -/* Charge les sections sélectionnées pour le projet courant. */ -void load_project_sections(void *, GObject *); - - - - +/* Charge les parties courantes d'un binaire donné. */ +static void load_binary_current_parts(GOpenidaBinary *binary, GObject *ref); /* Affiche les parties désassemblées par défaut. */ static void load_default_parts(GObject *); @@ -85,6 +89,7 @@ static void on_part_selection_toggle(GtkCellRendererToggle *, gchar *, GObject * /****************************************************************************** * * * Paramètres : binary = informations sur le binaire actuellement ouvert. * +* parent = fenêtre parente à surpasser. * * * * Description : Construit la fenêtre de sélection des sections. * * * @@ -94,7 +99,7 @@ static void on_part_selection_toggle(GtkCellRendererToggle *, gchar *, GObject * * * ******************************************************************************/ -GtkWidget *create_sections_dialog(GOpenidaBinary *binary) +GtkWidget *create_sections_dialog(GOpenidaBinary *binary, GtkWindow *parent) { GtkWidget *result; /* Fenêtre à renvoyer */ GObject *ref; /* Espace de référencements */ @@ -104,19 +109,13 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) GtkWidget *vbox1; - //GtkWidget *hbox1; - - - GtkWidget *label; /* Etiquette à afficher */ - - GtkWidget *combobox; - GtkWidget *alignment; /* Adaptation de disposition */ - GtkWidget *frame; /* Support avec encadrement */ GtkWidget *vbox2; GtkWidget *hbox2; + GtkWidget *label; /* Etiquette à afficher */ + GtkWidget *comboboxentry; GtkWidget *hbox3; GtkWidget *scrolledwindow1; @@ -131,14 +130,15 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) GtkWidget *hbuttonbox1; GtkWidget *button; /* Bouton de commande */ + GtkWidget *sep; /* Barre de séparation */ - result = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_size_request(result, 600, 400); - gtk_container_set_border_width(GTK_CONTAINER(result), 8); - gtk_window_set_title(GTK_WINDOW(result), _("Sections selection")); - gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); - gtk_window_set_default_size(GTK_WINDOW(result), 600, 400); - gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); + result = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(result, 600, 400); + gtk_container_set_border_width(GTK_CONTAINER(result), 8); + gtk_window_set_title(GTK_WINDOW(result), _("Content to display")); + gtk_window_set_transient_for(GTK_WINDOW(result), parent); + gtk_window_set_default_size(GTK_WINDOW(result), 600, 400); + gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); ref= G_OBJECT(result); g_object_set_data(ref, "binary", binary); @@ -147,28 +147,11 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) gtk_widget_show(vbox1); gtk_container_add(GTK_CONTAINER(result), vbox1); - /* - hbox1 = gtk_hbox_new(FALSE, 8); - gtk_widget_show(hbox1); - gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); - - label = qck_create_label(NULL, NULL, _("Binary :")); - gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 0); - - combobox = gtk_combo_box_new_text(); - gtk_widget_show(combobox); - gtk_box_pack_start(GTK_BOX(hbox1), combobox, TRUE, TRUE, 0); - */ - - frame = qck_create_frame(_("Content to display"), &alignment, 4, 4, 12, 0); - gtk_box_pack_start(GTK_BOX(vbox1), frame, TRUE, TRUE, 0); - - - - vbox2 = gtk_vbox_new(FALSE, 8); gtk_widget_show(vbox2); - gtk_container_add(GTK_CONTAINER(alignment), vbox2); + gtk_container_add(GTK_CONTAINER(vbox1), vbox2); + + hbox2 = gtk_hbox_new(FALSE, 8); gtk_widget_show(hbox2); @@ -182,9 +165,11 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); @@ -244,19 +229,32 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) + /* Boutons d'édition de la liste */ + + vbuttonbox1 = gtk_vbutton_box_new(); + gtk_widget_show(vbuttonbox1); + gtk_box_pack_start(GTK_BOX(hbox3), vbuttonbox1, FALSE, FALSE, 0); + gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_SPREAD); - vbuttonbox1 = gtk_vbutton_box_new(); - gtk_widget_show(vbuttonbox1); - gtk_box_pack_start(GTK_BOX(hbox3), vbuttonbox1, FALSE, FALSE, 0); - gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_SPREAD); + button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(select_all_items_or_none), ref); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); + g_object_set_data(G_OBJECT(button), "all", button); + + button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(select_all_items_or_none), ref); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); + sep = gtk_hseparator_new(); + gtk_widget_show(sep); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), sep); button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); @@ -269,16 +267,15 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox1), GTK_BUTTONBOX_END); - button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", G_CALLBACK(NULL), NULL); - gtk_container_add(GTK_CONTAINER(hbuttonbox1), button); + /* Boutons de contrôle principaux */ - button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", G_CALLBACK(NULL), NULL); + button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", G_CALLBACK(save_current_selection), ref); gtk_container_add(GTK_CONTAINER(hbuttonbox1), button); + button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", G_CALLBACK(close_editor), result); + gtk_container_add(GTK_CONTAINER(hbuttonbox1), button); - - - + /* Actualisation de l'interface */ g_signal_connect(G_OBJECT(comboboxentry), "changed", G_CALLBACK(on_model_change), ref); @@ -286,22 +283,52 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxentry), _("Routines")); gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxentry), _("User")); + load_binary_current_parts(binary, ref); + return result; } +/****************************************************************************** +* * +* Paramètres : button = bouton d'édition de la sélection. * +* ref = espace de référencement principal. * +* * +* Description : Sélectionne ou non tous les éléments de la liste courante. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void select_all_items_or_none(GtkButton *button, GObject *ref) +{ + gboolean state; /* Etat de sélection à donner */ + GtkTreeModel *model; /* Modèle de représentation */ + GtkTreeIter iter; /* Point de modification */ + + state = (g_object_get_data(G_OBJECT(button), "all") != NULL); + + model = GTK_TREE_MODEL(g_object_get_data(ref, "store")); + if (gtk_tree_model_get_iter_first(model, &iter)) + do + gtk_tree_store_set(GTK_TREE_STORE(model), &iter, + PTC_ACTIVE, state, + -1); + while (gtk_tree_model_iter_next(model, &iter)); +} /****************************************************************************** * * -* Paramètres : project = informations sur le project actuellement ouvert. * -* ref = espace de référencement principal. * +* Paramètres : button = bouton 'OK'. * +* ref = espace de référencement principal. * * * -* Description : Charge les sections sélectionnées pour le projet courant. * +* Description : Sauvegarde l'état courant des sélections et clôt la fenêtre. * * * * Retour : - * * * @@ -309,27 +336,189 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) * * ******************************************************************************/ -void load_project_sections(void *project, GObject *ref) +static void save_current_selection(GtkButton *button, GObject *ref) { - /* - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("Never automatically")); - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("When the window gets the focus")); - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("On click on the window")); - */ + + + + GOpenidaBinary *binary; /* Binaire à traiter */ + + GExeFormat *format; /* Format associé au binaire */ + GArchProcessor *proc; /* Architecture utilisée */ + + + GBinPart **parts; /* Parcelles à désassembler */ + size_t parts_count; /* Quantité de ces parcelles */ + GBinPart *part; /* Nouvelle partie à lister */ + + + GBinRoutine **routines; /* Liste des routines trouvées */ + size_t routines_count; /* Nombre de ces routines */ + parts_model *model; /* Mémoire du modèle */ + size_t i; /* Boucle de parcours */ + off_t offset; /* Position dans le binaire */ + + + binary = G_OPENIDA_BINARY(g_object_get_data(ref, "binary")); + + format = g_openida_binary_get_format(binary); + proc = get_arch_processor_from_format(format); + + + + + /* Routines */ + + parts = NULL; + parts_count = 0; + + routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count); + qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_compare); + + model = (parts_model *)g_object_get_data(ref, "routines_model"); + + for (i = 0; i < routines_count; i++) + { + if (!model->selected[i]) continue; + + part = g_binary_part_new(); + + g_binary_part_set_name(part, g_binary_routine_get_name(routines[i])); + + g_exe_format_translate_address_into_offset(format, + g_binary_routine_get_address(routines[i]), + &offset); + + g_binary_part_set_values(part, offset, + g_binary_routine_get_size(routines[i]), + g_binary_routine_get_address(routines[i])); + + parts = (GBinPart **)realloc(parts, ++parts_count * sizeof(GBinPart *)); + parts[parts_count - 1] = part; + + } + + g_openida_binary_set_parts(binary, BPM_ROUTINES, parts, parts_count); + + + + + + + + + /* Fin */ + + gtk_widget_destroy(GTK_WIDGET(ref)); } +/****************************************************************************** +* * +* Paramètres : button = bouton 'Annuler'. * +* widget = adresse de la fenêtre de l'éditeur à fermer. * +* * +* Description : Ferme la fenêtre de dialogue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void close_editor(GtkButton *button, GtkWidget *widget) +{ + gtk_widget_destroy(widget); +} +/****************************************************************************** +* * +* Paramètres : binary = informations sur le binaire actuellement ouvert. * +* ref = espace de référencement principal. * +* * +* Description : Charge les parties courantes d'un binaire donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void load_binary_current_parts(GOpenidaBinary *binary, GObject *ref) +{ + GtkTreeModel *store; /* Modèle de représentation */ + GBinPart ***list; /* Tableau de parties choisies */ + BinaryPartModel model; /* Sélection courante */ + size_t *count; /* Taille de chaque liste */ + unsigned int i; /* Boucle de parcours #1 */ + parts_model *parts; /* Liste de sélection courante */ + size_t j; /* Boucle de parcours #2 */ + GtkTreeIter iter; /* Lieu de lecture d'adresse */ + char path[11 /* UINT_MAX */]; /* Chemin d'accès pour GTK */ + gchar *value; /* Valeur d'adresse présentée */ + vmpa_t addr_dlg; /* Adresse côté local */ + size_t k; /* Boucle de parcours #3 */ + vmpa_t addr_bin; /* Adresse côté binaire */ + GtkComboBox *combo; /* Liste de tous les modèles */ + + /* Lecture des sélections courantes */ + + store = GTK_TREE_MODEL(g_object_get_data(ref, "store")); + + list = g_openida_binary_get_parts(binary, &model, &count); + + for (i = 0; i < (BPM_COUNT - 1 /* TODO*/); i++) + { + gtk_tree_store_clear(GTK_TREE_STORE(store)); + + switch (i) + { + case BPM_DEFAULT: + load_default_parts(ref); + parts = (parts_model *)g_object_get_data(ref, "default_model"); + break; + case BPM_ROUTINES: + load_routines_parts(ref); + parts = (parts_model *)g_object_get_data(ref, "routines_model"); + break; + case BPM_USER: + //parts = + break; + } + + for (j = 0; j < parts->count; j++) + { + snprintf(path, 11, "%u", j); + + gtk_tree_model_get_iter_from_string(store, &iter, path); + gtk_tree_model_get(store, &iter, PTC_START, &value, -1); + addr_dlg = strtoll(value, NULL, 16); + g_free(value); + + for (k = 0; k < count[i]; k++) + { + g_binary_part_get_values(list[i][k], NULL, NULL, &addr_bin); + if (addr_bin == addr_dlg) break; + } + parts->selected[j] = (count[i] == 0 || k < count[i]); + + } + + } + + /* Sélection courante */ + combo = GTK_COMBO_BOX(g_object_get_data(ref, "models")); + gtk_combo_box_set_active(combo, model); + +} /****************************************************************************** @@ -483,20 +672,6 @@ static void load_routines_parts(GObject *ref) -static void user_function(GtkButton *button, GObject *ref) -{ - - - - - - - - -} - - - diff --git a/src/dialogs/binparts.h b/src/dialogs/binparts.h index dd7fa5e..8a86bf6 100644 --- a/src/dialogs/binparts.h +++ b/src/dialogs/binparts.h @@ -33,7 +33,7 @@ /* Construit la fenêtre de sélection des sections. */ -GtkWidget *create_sections_dialog(GOpenidaBinary *); +GtkWidget *create_sections_dialog(GOpenidaBinary *, GtkWindow *); diff --git a/src/editor.c b/src/editor.c index 5e39f27..8291a2e 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1099,7 +1099,7 @@ static void mcb_binary_select_parts(GtkMenuItem *menuitem, GObject *ref) binary = G_OPENIDA_BINARY(g_object_get_data(ref, "current_binary")); - dialog = create_sections_dialog(binary); + dialog = create_sections_dialog(binary, GTK_WINDOW(ref)); gtk_widget_show(dialog); } diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 878bf51..b703dcf 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -62,6 +62,9 @@ static vmpa_t g_elf_format_get_entry_point(const GElfFormat *); /* Fournit les références aux zones binaires à analyser. */ static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *); +/* Fournit la position correspondant à une adresse virtuelle. */ +static bool g_elf_format_translate_address_into_offset(const GElfFormat *, vmpa_t, off_t *); + /* Fournit l'adresse virtuelle correspondant à une position. */ static bool g_elf_format_translate_offset_into_address(const GElfFormat *, off_t, vmpa_t *); @@ -139,7 +142,8 @@ static void g_elf_format_init(GElfFormat *format) exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point; exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts; - exe_format->translate = (translate_off_fc)g_elf_format_translate_offset_into_address; + exe_format->translate_addr = (translate_addr_fc)g_elf_format_translate_address_into_offset; + exe_format->translate_off = (translate_off_fc)g_elf_format_translate_offset_into_address; } @@ -496,6 +500,34 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit la position correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_translate_address_into_offset(const GElfFormat *format, vmpa_t addr, off_t *pos) +{ + bool result; /* Bilan à retourner */ + + result = translate_address_into_offset_using_elf_sections(format, addr, pos); + + if (!result) + /* TODO : prgm... */; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * * pos = position dans le flux binaire à retrouver. * * addr = adresse virtuelle correspondante. [OUT] * * * diff --git a/src/format/elf/section.c b/src/format/elf/section.c index b8d6a50..cb6a04a 100644 --- a/src/format/elf/section.c +++ b/src/format/elf/section.c @@ -280,6 +280,46 @@ const char *extract_name_from_elf_string_section(const GElfFormat *format, const /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit la position correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_address_into_offset_using_elf_sections(const GElfFormat *format, vmpa_t addr, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + elf_shdr section; /* Section à analyser */ + + result = false; + + for (i = 0; i < format->header.e_shnum && !result; i++) + { + find_elf_section_by_index(format, i, §ion); + + if (ELF_SHDR(format, section, sh_addr) <= addr + && addr < (ELF_SHDR(format, section, sh_addr) + ELF_SHDR(format, section, sh_size))) + { + *pos = ELF_SHDR(format, section, sh_offset) + addr - ELF_SHDR(format, section, sh_addr); + result = true; + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * * pos = position dans le flux binaire à retrouver. * * addr = adresse virtuelle correspondante. [OUT] * * * diff --git a/src/format/elf/section.h b/src/format/elf/section.h index ca91097..811e32b 100644 --- a/src/format/elf/section.h +++ b/src/format/elf/section.h @@ -51,6 +51,9 @@ bool find_elf_section_content_by_name(const GElfFormat *, const char *, off_t *, /* Identifie une chaîne de caractères dans une section adéquate. */ const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, off_t); +/* Fournit la position correspondant à une adresse virtuelle. */ +bool translate_address_into_offset_using_elf_sections(const GElfFormat *, vmpa_t, off_t *); + /* Fournit l'adresse virtuelle correspondant à une position. */ bool translate_offset_into_address_using_elf_sections(const GElfFormat *, off_t, vmpa_t *); diff --git a/src/format/executable-int.h b/src/format/executable-int.h index e4b18a4..224e193 100644 --- a/src/format/executable-int.h +++ b/src/format/executable-int.h @@ -41,6 +41,9 @@ typedef vmpa_t (* get_entry_point_fc) (const GExeFormat *); /* Fournit les références aux zones de code à analyser. */ typedef GBinPart ** (* get_parts_fc) (const GExeFormat *, size_t *); +/* Fournit la position correspondant à une adresse virtuelle. */ +typedef bool (* translate_addr_fc) (const GExeFormat *, vmpa_t, off_t *); + /* Fournit l'adresse virtuelle correspondant à une position. */ typedef bool (* translate_off_fc) (const GExeFormat *, off_t, vmpa_t *); @@ -56,7 +59,8 @@ struct _GExeFormat get_entry_point_fc get_entry_point; /* Obtention du point d'entrée */ get_parts_fc get_parts; /* Liste des parties binaires */ - translate_off_fc translate; /* Correspondance pos -> addr */ + translate_addr_fc translate_addr; /* Correspondance addr -> pos */ + translate_off_fc translate_off; /* Correspondance pos -> addr */ }; diff --git a/src/format/executable.c b/src/format/executable.c index 4af587f..76efaa1 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -147,6 +147,27 @@ GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count) /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit la position correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_exe_format_translate_address_into_offset(const GExeFormat *format, vmpa_t addr, off_t *pos) +{ + return format->translate_addr(format, addr, pos); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * * pos = position dans le flux binaire à retrouver. * * addr = adresse virtuelle correspondante. [OUT] * * * @@ -160,6 +181,6 @@ GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count) bool g_exe_format_translate_offset_into_address(const GExeFormat *format, off_t pos, vmpa_t *addr) { - return format->translate(format, pos, addr); + return format->translate_off(format, pos, addr); } diff --git a/src/format/executable.h b/src/format/executable.h index 4d3f759..2042df4 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -75,6 +75,9 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *); /* Fournit les références aux zones binaires à analyser. */ GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *); +/* Fournit la position correspondant à une adresse virtuelle. */ +bool g_exe_format_translate_address_into_offset(const GExeFormat *, vmpa_t, off_t *); + /* Fournit l'adresse virtuelle correspondant à une position. */ bool g_exe_format_translate_offset_into_address(const GExeFormat *, off_t, vmpa_t *); diff --git a/src/format/part.c b/src/format/part.c index 63747d9..006cb75 100644 --- a/src/format/part.c +++ b/src/format/part.c @@ -124,6 +124,35 @@ GBinPart *g_binary_part_new(void) /****************************************************************************** * * +* Paramètres : src = partie de code à copier. * +* * +* Description : Crée une description de partie de code à partir d'une autre. * +* * +* Retour : Partie de code copiée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPart *g_binary_part_dump(const GBinPart *src) +{ + GBinPart *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BIN_PART, NULL); + + result->name = (src->name != NULL ? strdup(src->name) : NULL); + + result->offset = result->offset; + result->size = result->size; + result->addr = result->addr; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : node = noeud XML contenant les données à charger. * * * * Description : Crée une description de partie de code vierge à partir d'XML.* diff --git a/src/format/part.h b/src/format/part.h index 5c1c904..32d1903 100644 --- a/src/format/part.h +++ b/src/format/part.h @@ -55,6 +55,9 @@ GType g_binary_part_get_type(void); /* Crée une description de partie de code vierge. */ GBinPart *g_binary_part_new(void); +/* Crée une description de partie de code à partir d'une autre. */ +GBinPart *g_binary_part_dump(const GBinPart *); + /* Crée une description de partie de code vierge à partir d'XML. */ GBinPart *g_binary_part_load_from_xml(xmlNodePtr); -- cgit v0.11.2-87-g4458