/* OpenIDA - Outil d'analyse de fichiers binaires * editor.c - fenêtre principale de l'interface graphique * * Copyright (C) 2006-2007 Cyrille Bagard * * This file is part of OpenIDA. * * 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "editor.h" #include /** exemple GTK **/ #include #include #include #include #include #include /** exemple GTK **/ #include "project.h" #include "analysis/binary.h" #include "gtkext/easygtk.h" #include "gtkext/gtkextstatusbar.h" #include "gtkext/gtkbinview.h" #include "gtkext/gtkblockview.h" #include "gtkext/gtkdockpanel.h" #include "gtkext/gtkviewpanel.h" #include "debug/debugger.h" #include "dialogs/add_shellcode.h" #include "dialogs/binparts.h" #include "dialogs/export.h" #include "dialogs/plugins.h" #include "gui/menus/menubar.h" #include "gui/tb/source.h" #include "panels/panel.h" #include "shell.h" /* TODO : à virer -> plugin */ /* Construit la fenêtre de l'éditeur. */ GtkWidget *create_editor(void); /* Quitte le programme en sortie de la boucle de GTK. */ static gboolean on_delete_editor(GtkWidget *, GdkEvent *, gpointer); /* Quitte le programme en sortie de la boucle de GTK. */ static void on_destroy_editor(GtkWidget *, gpointer); /* Réagit au menu "Fichier -> Nouveau projet". */ void mcb_file_new_project(GtkMenuItem *, gpointer); /* Réagit au menu "Fichier -> Ouvrir un projet". */ void mcb_file_open_project(GtkMenuItem *, gpointer); /* Réagit au menu "Fichier -> Enregistrer le projet". */ void mcb_file_save_project(GtkMenuItem *, gpointer); /* Réagit au menu "Fichier -> Enregistrer le projet sous...". */ void mcb_file_save_project_as(GtkMenuItem *, gpointer); /* Charge un projet récent et met à jour la liste. */ void mcb_open_recent_project(GtkMenuItem *, GObject *); /* Réagit avec le menu "Affichage -> Vue xxx". */ void mcb_view_change_support(GtkRadioMenuItem *, GObject *); /* Réagit avec le menu "Affichage -> Adresse virtuelle". */ void mcb_view_vaddress(GtkCheckMenuItem *, gpointer); /* Réagit avec le menu "Affichage -> code binaire". */ void mcb_view_code(GtkCheckMenuItem *, gpointer); /* Affiche la boîte d'ajout d'un binaire au projet courant. */ void mcb_project_add_binary(GtkMenuItem *, gpointer); /* Réagit au menu "Projet -> Ajouter un binaire -> Shellcode". */ static void mcb_project_add_binary_shellcode(GtkMenuItem *, GObject *); /* Retire un binaire du projet courant. */ void mcb_project_remove_binary(GtkMenuItem *, gpointer); /* Met à jour le contenu du menu 'Projet'. */ void reload_menu_project(GObject *); /* Réagit avec le menu "Binaire -> Sélectionner les parties...". */ static void mcb_binary_select_parts(GtkMenuItem *, GObject *); /* Réagit avec le menu "Binaire -> Sélectionner les greffons...". */ static void mcb_binary_select_plugins(GtkMenuItem *, GObject *); /* Réagit au menu "Binaire -> Exporter...". */ static void mcb_binary_export(GtkMenuItem *, GObject *); /* Réagit avec le menu "Débogage -> Démarrer". */ void mcb_debug_start(GtkCheckMenuItem *, gpointer); /* Réagit avec le menu "Débogage -> Mettre en pause". */ void mcb_debug_pause(GtkCheckMenuItem *, gpointer); /* Réagit avec le menu "Débogage -> Reprendre". */ void mcb_debug_resume(GtkCheckMenuItem *, gpointer); /* Réagit avec le menu "Débogage -> Tuer". */ void mcb_debug_kill(GtkCheckMenuItem *, gpointer); /* Met à jour l'accessibilité aux éléments du menu "Debogage". */ void update_debug_menu_items(GObject *, gboolean); /* Réagit au changement d'onglet d'un panneau quelconque. */ static void on_dock_item_switch(GtkDockPanel *, GDockItem *, GObject *); /* Met en concordance les menus avec l'édition courante. */ static void refresh_editor_menus(GObject *, GOpenidaBinary *, GtkBinView *); /* ------------------------- PARTIE DEDIEE AU MODE DEBOGAGE ------------------------- */ /* Prend note d'une pause dans le débogage. */ static void on_debugger_halted(GBinaryDebugger *, int, vmpa_t, pid_t, GObject *); /* ------------------------ INTEGRATION DE LA BARRE D'OUTILS ------------------------ */ /* Construit la barre d'outils de l'éditeur. */ static GtkWidget *build_editor_toolbar(GObject *); /****************************************************************************** * * * Paramètres : - * * * * Description : Construit la fenêtre de l'éditeur. * * * * Retour : Adresse de la fenêtre mise en place. * * * * Remarques : - * * * ******************************************************************************/ GtkWidget *create_editor(void) { GtkWidget *result; /* Fenêtre à renvoyer */ GObject *ref; /* Version de référence */ GEditorItem *editem; /* Menus réactifs principaux */ GtkWidget *menuboard; /* Barre de menus principale */ GtkWidget *menuitem; /* Elément de menu */ GtkWidget *menubar; /* Support pour éléments */ GtkWidget *submenuitem; /* Sous-élément de menu */ GtkWidget *submenubar; /* Support pour sous-éléments */ GSList *rgroup; /* Groupe des boutons radio */ GtkWidget *ssubmenuitem; /* Sous-élément de menu */ GtkWidget *toolbar; /* Barre d'outils */ GtkWidget *vbox1; GtkWidget *vpaned1; GtkWidget *hpaned1; GtkWidget *scrolledwindow2; GtkWidget *snippet; GtkWidget *statusbar; GtkWidget *view; GtkWidget *panel; GtkWidget *dpanel; /* Support de panneaux */ GDockItem *ditem; /* Panneau avec ses infos. */ #if 0 GtkWidget *vbox; /* Support à divisions vert. */ GtkWidget *notebook; /* Support à onglets */ GtkWidget *panel; /* Panneau de configuration */ GtkWidget *label; /* Etiquette pour onglet */ GtkWidget *hseparator; /* Barre de séparation */ GtkWidget *hbuttonbox; /* Support horizontal de btns. */ GtkWidget *button; /* Btn. de commande inférieur */ #endif GtkWidget *button; /* Btn. de commande inférieur */ GtkAccelGroup *accgroup; result = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(result, 800, 600); gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(result), 4); gtk_window_set_title(GTK_WINDOW(result), _("OpenIDA")); g_signal_connect(G_OBJECT(result), "delete-event", G_CALLBACK(on_delete_editor), NULL); g_signal_connect(G_OBJECT(result), "destroy", G_CALLBACK(on_destroy_editor), NULL); ref = G_OBJECT(result); accgroup = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(result), accgroup); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (result), vbox1); /* Intégration des menus */ editem = g_menu_bar_new(ref, accgroup); menuboard = g_editor_item_get_widget(editem); gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); menuboard = gtk_menu_bar_new(); gtk_widget_show(menuboard); gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); menuitem = gtk_menu_item_new_with_mnemonic(_("_File")); gtk_widget_show(menuitem); gtk_container_add(GTK_CONTAINER(menuboard), menuitem); menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); submenuitem = qck_create_menu_item(NULL, NULL, _("New project"), G_CALLBACK(mcb_file_new_project), result); add_accelerator_to_menu_item(submenuitem, "N", accgroup); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Open project"), G_CALLBACK(mcb_file_open_project), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Save project"), G_CALLBACK(mcb_file_save_project), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Save project as..."), G_CALLBACK(mcb_file_save_project_as), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(G_OBJECT(result), "menu_recent_prjs", _("Recent projects..."), NULL, NULL); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenubar); /* Affichage */ menuitem = gtk_menu_item_new_with_mnemonic(_("_View")); gtk_widget_show(menuitem); gtk_container_add(GTK_CONTAINER(menuboard), menuitem); menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); submenuitem = qck_create_radio_menu_item(ref, "textview", NULL, _("Text view"), G_CALLBACK(mcb_view_change_support), result); add_accelerator_to_menu_item(submenuitem, "F2", accgroup); g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_BLOCK)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem)); submenuitem = qck_create_radio_menu_item(ref, "graphview", rgroup, _("Graph view"), G_CALLBACK(mcb_view_change_support), result); add_accelerator_to_menu_item(submenuitem, "F3", accgroup); g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_GRAPH)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem)); submenuitem = qck_create_radio_menu_item(ref, "sourceview", rgroup, _("Source code"), G_CALLBACK(mcb_view_change_support), result); add_accelerator_to_menu_item(submenuitem, "F4", accgroup); g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_SOURCE)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_check_menu_item(NULL, NULL, _("Virtual address"), G_CALLBACK(mcb_view_vaddress), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_check_menu_item(NULL, NULL, _("Binary code"), G_CALLBACK(mcb_view_code), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Toolbar"), NULL, NULL); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenubar); ssubmenuitem = qck_create_check_menu_item(NULL, NULL, _("Source file"), G_CALLBACK(NULL), result); gtk_container_add(GTK_CONTAINER(submenubar), ssubmenuitem); /* Projet */ menuitem = gtk_menu_item_new_with_mnemonic(_("_Project")); gtk_widget_show(menuitem); gtk_container_add(GTK_CONTAINER(menuboard), menuitem); menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); submenuitem = qck_create_menu_item(NULL, NULL, _("Add a binary..."), G_CALLBACK(mcb_project_add_binary), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Add a binary"), NULL, NULL); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenubar); submenuitem = qck_create_menu_item(NULL, NULL, _("Shellcode"), G_CALLBACK(mcb_project_add_binary_shellcode), result); gtk_container_add(GTK_CONTAINER(submenubar), submenuitem); submenuitem = qck_create_menu_item(G_OBJECT(result), "menu_prj_remove_bin", _("Remove a binary"), NULL, NULL); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenubar); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); menuitem = gtk_menu_item_new_with_mnemonic(_("_Binary")); gtk_widget_show(menuitem); gtk_container_add(GTK_CONTAINER(menuboard), menuitem); menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); submenuitem = qck_create_menu_item(NULL, NULL, _("Select parts..."), G_CALLBACK(mcb_binary_select_parts), ref); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Select plugins..."), G_CALLBACK(mcb_binary_select_plugins), ref); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_binary_export", _("Export..."), G_CALLBACK(mcb_binary_export), ref); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); menuitem = gtk_menu_item_new_with_mnemonic(_("_Debug")); gtk_widget_show(menuitem); gtk_container_add(GTK_CONTAINER(menuboard), menuitem); menubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); submenuitem = qck_create_menu_item(ref, "mnu_debug_start", _("Start process"), G_CALLBACK(mcb_debug_start), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_debug_pause", _("Pause process"), G_CALLBACK(mcb_debug_pause), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_debug_resume", _("Resume process"), G_CALLBACK(mcb_debug_resume), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_debug_kill", _("Kill process"), G_CALLBACK(mcb_debug_kill), result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_debug_into", _("Step into"), NULL/*G_CALLBACK()*/, result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_debug_over", _("Step over"), NULL/*G_CALLBACK()*/, result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(ref, "mnu_debug_ret", _("Run until ret"), NULL/*G_CALLBACK()*/, result); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); update_debug_menu_items(ref, FALSE); menuitem = gtk_menu_item_new_with_mnemonic(_("_Plugins")); gtk_widget_show(menuitem); gtk_container_add(GTK_CONTAINER(menuboard), menuitem); /* Barre d'outils */ toolbar = build_editor_toolbar(G_OBJECT(result)); gtk_box_pack_start(GTK_BOX(vbox1), toolbar, FALSE, FALSE, 0); vpaned1 = gtk_vpaned_new (); gtk_widget_show (vpaned1); gtk_box_pack_start (GTK_BOX (vbox1), vpaned1, TRUE, TRUE, 0); gtk_paned_set_position (GTK_PANED (vpaned1), 400); hpaned1 = gtk_hpaned_new (); gtk_widget_show (hpaned1); gtk_paned_pack1 (GTK_PANED (vpaned1), hpaned1, FALSE, TRUE); gtk_paned_set_position (GTK_PANED (hpaned1), 600); init_panels(ref); dpanel = gtk_dock_panel_new(); g_object_set_data(G_OBJECT(result), "binpanel", dpanel); gtk_widget_show(dpanel); g_signal_connect(dpanel, "switch-item", G_CALLBACK(on_dock_item_switch), ref); gtk_paned_pack1(GTK_PANED(hpaned1), dpanel, TRUE, TRUE); dpanel = gtk_dock_panel_new(); gtk_widget_show(dpanel); g_signal_connect(dpanel, "switch-item", G_CALLBACK(on_dock_item_switch), ref); gtk_paned_pack2(GTK_PANED(hpaned1), dpanel, TRUE, TRUE); place_all_panels_in_editor(dpanel); ditem = g_dock_item_new(_("Registers"), get_panel(PNT_REGISTERS)); gtk_dock_panel_add_item(dpanel, ditem); /* Panneau inférieur */ dpanel = gtk_dock_panel_new(); gtk_widget_show(dpanel); printf("bottom :: %p\n", dpanel); gtk_paned_pack2(GTK_PANED(vpaned1), dpanel, FALSE, FALSE); ditem = g_dock_item_new(_("Messages"), get_panel(PNT_LOG)); gtk_dock_panel_add_item(dpanel, ditem); ditem = g_dock_item_new(_("Strings"), get_panel(PNT_STRINGS)); gtk_dock_panel_add_item(dpanel, ditem); panel = build_shell_panel(G_OBJECT(result)); ditem = g_dock_item_new(_("Shell"), panel); gtk_dock_panel_add_item(dpanel, ditem); /* notebook = qck_create_notebook(NULL, NULL); gtk_paned_pack2(GTK_PANED(vpaned1), notebook, FALSE, FALSE); panel = build_strings_panel(G_OBJECT(result)); gtk_container_add(GTK_CONTAINER(notebook), panel); label = qck_create_label(NULL, NULL, _("Strings")); gtk_notebook_set_tab_label(GTK_NOTEBOOK(notebook), gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), 0), label); */ /* scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow1); gtk_paned_pack2 (GTK_PANED (vpaned1), scrolledwindow1, TRUE, TRUE); textview1 = gtk_text_view_new (); gtk_widget_show (textview1); gtk_container_add (GTK_CONTAINER (scrolledwindow1), textview1); */ statusbar = gtk_extended_status_bar_new(); g_object_set_data(ref, "statusbar", statusbar); gtk_widget_show(statusbar); gtk_box_pack_start(GTK_BOX(vbox1), statusbar, FALSE, FALSE, 0); load_recent_openida_projects_list(G_OBJECT(result), G_CALLBACK(mcb_open_recent_project)); reload_menu_project(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : widget = fenêtre de l'éditeur de préférences. * * event = informations liées à l'événement. * * data = adresse non utilisée ici. * * * * Description : Quitte le programme en sortie de la boucle de GTK. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer data) { gboolean result; /* Continuation à retourner */ openida_project *project; /* Projet courant */ GtkWidget *dialog; /* Boîte à afficher */ result = FALSE; project = get_current_openida_project(); if (g_openida_project_get_filename(project) == NULL) { dialog = gtk_message_dialog_new(widget, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("The current project will be lost. Do you you want to save it ?")); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_YES, GTK_RESPONSE_YES); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_NO, GTK_RESPONSE_NO); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); switch (gtk_dialog_run(GTK_DIALOG(dialog))) { case GTK_RESPONSE_YES: mcb_file_save_project_as(NULL, widget); break; case GTK_RESPONSE_NO: break; case GTK_RESPONSE_CANCEL: result = TRUE; break; } gtk_widget_destroy(dialog); } return result; } /****************************************************************************** * * * Paramètres : widget = fenêtre de l'éditeur de préférences. * * event = informations liées à l'événement. * * data = adresse non utilisée ici. * * * * Description : Quitte le programme en sortie de la boucle de GTK. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void on_destroy_editor(GtkWidget *widget, gpointer data) { close_openida_project(get_current_openida_project()); /* Fermeture propre */ /* ... */ gtk_main_quit(); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Fichier -> Nouveau projet". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) { openida_project *project; /* Nouveau projet courant */ project = create_empty_openida_project(G_OBJECT(data)); set_current_openida_project(project); display_openida_project(project, G_OBJECT(data)); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Fichier -> Ouvrir un projet". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) { GtkWidget *dialog; /* Boîte à afficher */ openida_project *project; /* Projet chargé */ gchar *filename; /* Nom du fichier à intégrer */ dialog = gtk_file_chooser_dialog_new(_("Open a project"), GTK_WINDOW(data), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); project = get_current_openida_project(); if (g_openida_project_get_filename(project) != NULL) gtk_file_chooser_set_filename(dialog, g_openida_project_get_filename(project)); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); project = g_openida_project_new_from_xml(G_OBJECT(data), filename); if (project != NULL) { set_current_openida_project(project); display_openida_project(project, G_OBJECT(data)); } g_free(filename); } gtk_widget_destroy(dialog); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Fichier -> Enregistrer le projet". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_file_save_project(GtkMenuItem *menuitem, gpointer data) { openida_project *project; /* Projet courant */ project = get_current_openida_project(); if (g_openida_project_get_filename(project) != NULL) { if (g_openida_project_save(project, NULL)) push_openida_project_into_recent_list(project); } else mcb_file_save_project_as(menuitem, data); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Fichier -> Enregistrer le projet sous...". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data) { GtkWidget *dialog; /* Boîte à afficher */ openida_project *project; /* Projet courant */ gchar *filename; /* Nom du fichier à intégrer */ dialog = gtk_file_chooser_dialog_new(_("Save the project as..."), GTK_WINDOW(data), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); project = get_current_openida_project(); if (g_openida_project_get_filename(project) != NULL) gtk_file_chooser_set_filename(dialog, g_openida_project_get_filename(project)); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if (g_openida_project_save(project, filename)) push_openida_project_into_recent_list(project); g_free(filename); } gtk_widget_destroy(dialog); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * ref = adresse de l'espace de référencement global. * * * * Description : Charge un projet récent et met à jour la liste. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_open_recent_project(GtkMenuItem *menuitem, GObject *ref) { const gchar *caption; /* Etiquette du menu */ openida_project *project; /* Nouveau projet chargé */ caption = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem)))); project = g_openida_project_new_from_xml(ref, caption); if (project != NULL) { push_openida_project_into_recent_list(project); load_recent_openida_projects_list(ref, G_CALLBACK(mcb_open_recent_project)); set_current_openida_project(project); /* TODO ... */ } } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * ref = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Affichage -> Vue xxx". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_view_change_support(GtkRadioMenuItem *menuitem, GObject *ref) { GSList *group; /* Liste de menus radio */ GSList *iter; /* Boucle de parcours */ BinaryView view; /* Nouvelle vue à présenter */ GOpenidaBinary *binary; /* Edition courante */ GtkViewPanel *pview; /* Afficheur effectif de code */ GtkWidget *panel; /* Nouveau support à utiliser */ GDockItem *ditem; /* Panneau avec ses infos. */ /* On ne traite qu'une seule fois ! */ if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return; group = gtk_radio_menu_item_get_group(menuitem); for (iter = group; iter != NULL; iter = g_slist_next(iter)) { if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(iter->data))) continue; view = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); binary = (GOpenidaBinary *)g_object_get_data(ref, "current_binary"); panel = get_view_for_openida_project_binary(get_current_openida_project(), binary, view, &pview); ditem = gtk_dock_panel_get_item_from_binary(get_current_openida_project(), binary); g_dock_item_set_panel(ditem, panel); change_editor_items_current_view(ref, pview); notify_panels_of_view_change(pview, true); } } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Affichage -> Adresse virtuelle". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_view_vaddress(GtkCheckMenuItem *menuitem, gpointer data) { GtkBinView *binview; /* Zone de code principale */ gboolean active; /* Etat de sélection du menu */ /* FIXME : "binview" -> "current_view" */ return; binview = GTK_BIN_VIEW(g_object_get_data(G_OBJECT(data), "binview")); active = gtk_check_menu_item_get_active(menuitem); gtk_binview_show_vaddress(binview, active); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Affichage -> code binaire". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_view_code(GtkCheckMenuItem *menuitem, gpointer data) { GtkBinView *binview; /* Zone de code principale */ gboolean active; /* Etat de sélection du menu */ /* FIXME : "binview" -> "current_view" */ return; binview = GTK_BIN_VIEW(g_object_get_data(G_OBJECT(data), "binview")); active = gtk_check_menu_item_get_active(menuitem); gtk_binview_show_code(binview, active); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * data = adresse de l'espace de référencement global. * * * * Description : Affiche la boîte d'ajout d'un binaire au projet courant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_project_add_binary(GtkMenuItem *menuitem, gpointer data) { GtkWidget *dialog; /* Boîte à afficher */ gchar *filename; /* Nom du fichier à intégrer */ GOpenidaBinary *binary; /* Représentation chargée */ dialog = gtk_file_chooser_dialog_new(_("Open a binary file"), GTK_WINDOW(data), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); binary = g_openida_binary_new_from_file(filename); if (binary != NULL) { attach_binary_to_openida_project(get_current_openida_project(), binary); reload_menu_project(G_OBJECT(data)); } g_free(filename); } gtk_widget_destroy(dialog); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * ref = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Projet -> Ajouter un binaire -> Shellcode". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_project_add_binary_shellcode(GtkMenuItem *menuitem, GObject *ref) { run_add_shellcode_assistant(get_current_openida_project(), GTK_WINDOW(ref)); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * data = adresse de l'espace de référencement global. * * * * Description : Retire un binaire du projet courant. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_project_remove_binary(GtkMenuItem *menuitem, gpointer data) { GOpenidaBinary *binary; /* Représentation chargée */ binary = g_object_get_data(G_OBJECT(menuitem), "binary"); detach_binary_to_openida_project(get_current_openida_project(), binary); //unload_binary_file(binary); reload_menu_project(G_OBJECT(data)); } /****************************************************************************** * * * Paramètres : ref = espace de référencements global. * * * * Description : Met à jour le contenu du menu 'Projet'. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void reload_menu_project(GObject *ref) { #if 0 GtkWidget *menuitem; /* Menu principal à compléter */ GtkWidget *menubar; /* Support pour éléments */ GList *list; /* Liste des éléments en place */ GList *iter; /* Boucle de parcours #1 */ size_t count; /* Nombre de binaires attachés */ const GOpenidaBinary **binaries; /* Liste de ces binaires */ size_t i; /* Boucle de parcours #2 */ const char *desc; /* Description à afficher */ GtkWidget *submenuitem; /* Sous-menu à ajouter */ menuitem = GTK_WIDGET(g_object_get_data(ref, "menu_prj_remove_bin")); menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); /* Remise à zéro */ list = gtk_container_get_children(GTK_CONTAINER(menubar)); for (iter = list; iter != NULL; iter = g_list_next(iter)) gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(iter->data)); g_list_free(list); /* Ajout des entrées */ binaries = get_openida_project_binaries(get_current_openida_project(), &count); for (i = 0; i < count; i++) { desc = g_openida_binary_to_string(binaries[i]); submenuitem = qck_create_menu_item(NULL, NULL, desc, G_CALLBACK(mcb_project_remove_binary), ref); g_object_set_data(G_OBJECT(submenuitem), "binary", binaries[i]); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); } gtk_widget_set_sensitive(menuitem, count > 0); #endif } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * ref = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Binaire -> Sélectionner les parties...".* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_binary_select_parts(GtkMenuItem *menuitem, GObject *ref) { GOpenidaBinary *binary; /* Binaire courant à l'écran */ GtkWidget *dialog; /* Boîte de dialogue à montrer */ binary = G_OPENIDA_BINARY(g_object_get_data(ref, "current_binary")); dialog = create_sections_dialog(binary, GTK_WINDOW(ref)); gtk_widget_show(dialog); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * ref = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Binaire -> Sélectionner les greffons..."* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_binary_select_plugins(GtkMenuItem *menuitem, GObject *ref) { GOpenidaBinary *binary; /* Binaire courant à l'écran */ GtkWidget *dialog; /* Boîte de dialogue à montrer */ binary = G_OPENIDA_BINARY(g_object_get_data(ref, "current_binary")); dialog = create_plugins_selection_dialog(binary, GTK_WINDOW(ref)); gtk_widget_show(dialog); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * ref = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Binaire -> Exporter...". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_binary_export(GtkMenuItem *menuitem, GObject *ref) { GOpenidaBinary *binary; /* Edition courante */ binary = (GOpenidaBinary *)g_object_get_data(ref, "current_binary"); run_export_assistant(binary, GTK_WINDOW(ref)); } void debugger_stopped_cb(GBinaryDebugger *debugger, uint64_t last, uint64_t cur, gpointer data) { GObject *ref; GOpenidaBinary *binary; GRenderingLine *line; GtkWidget *submenuitem; /* Menu à rendre accessible */ register_value *values; size_t count; ref = G_OBJECT(data); binary = g_object_get_data(ref, "current_binary"); if (last != cur) { line = g_rendering_line_find_by_address(g_openida_binary_get_lines(binary), NULL/* FIXME */, last); if (line != NULL) g_rendering_line_remove_flag(line, RLF_RUNNING_BP); } printf("bp at 0x%016llx\n", cur); line = g_rendering_line_find_by_address(g_openida_binary_get_lines(binary), NULL/* FIXME */, cur); if (line != NULL) g_rendering_line_add_flag(line, RLF_RUNNING_BP); else printf("no line at address !\n"); values = g_binary_debugger_get_registers(debugger, &count); /* Mises à jour */ update_debug_menu_items(ref, TRUE); refresh_registers_panel_with_registers(get_panel(PNT_REGISTERS), values, count); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Débogage -> Démarrer". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_debug_start(GtkCheckMenuItem *menuitem, gpointer data) { GOpenidaBinary *binary; /* Binaire à analyser */ GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ binary = g_object_get_data(G_OBJECT(data), "current_binary"); debugger = g_new_binary_debugger(DGT_REMOTE_GDB, binary); g_object_set_data(G_OBJECT(data), "current_debugger", debugger); g_signal_connect(debugger, "debugger-stopped", G_CALLBACK(debugger_stopped_cb), data); g_signal_connect(debugger, "halted", G_CALLBACK(on_debugger_halted), data); g_binary_debugger_run(debugger); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Débogage -> Mettre en pause". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_debug_pause(GtkCheckMenuItem *menuitem, gpointer data) { GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ debugger = g_object_get_data(G_OBJECT(data), "current_debugger"); //g_binary_debugger_resume(debugger); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Débogage -> Reprendre". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_debug_resume(GtkCheckMenuItem *menuitem, gpointer data) { GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ debugger = g_object_get_data(G_OBJECT(data), "current_debugger"); g_binary_debugger_resume(debugger); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * data = adresse de l'espace de référencement global. * * * * Description : Réagit avec le menu "Débogage -> Tuer". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_debug_kill(GtkCheckMenuItem *menuitem, gpointer data) { GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ debugger = g_object_get_data(G_OBJECT(data), "current_debugger"); g_binary_debugger_kill(debugger); /* TODO : retirer l'association binary <-> debugger */ } /****************************************************************************** * * * Paramètres : ref = adresse de l'espace de référencement global. * * stopped = indique l'état d'accessibilité des menus. * * * * Description : Met à jour l'accessibilité aux éléments du menu "Debogage". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void update_debug_menu_items(GObject *ref, gboolean stopped) { GtkWidget *submenuitem; /* Menu à rendre accessible */ submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_pause")); gtk_widget_set_sensitive(submenuitem, stopped); submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_resume")); gtk_widget_set_sensitive(submenuitem, stopped); submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_into")); gtk_widget_set_sensitive(submenuitem, stopped); submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_over")); gtk_widget_set_sensitive(submenuitem, stopped); submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_ret")); gtk_widget_set_sensitive(submenuitem, stopped); } /****************************************************************************** * * * Paramètres : panel = panneau de support des éléments concerné. * * item = nouvel élément présenté à l'affichage. * * ref = adresse de l'espace de référencement global. * * * * Description : Réagit au changement d'onglet d'un panneau quelconque. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void on_dock_item_switch(GtkDockPanel *panel, GDockItem *item, GObject *ref) { GtkWidget *widget; /* Support réel à traiter */ GOpenidaBinary *old_binary; /* Ancien binaire édité */ GOpenidaBinary *binary; /* Binaire en cours d'édition */ widget = g_dock_item_get_panel(item); if (GTK_IS_SCROLLED_WINDOW(widget)) widget = gtk_bin_get_child(GTK_BIN(widget)); if (GTK_IS_VIEWPORT(widget)) widget = gtk_bin_get_child(GTK_BIN(widget)); if (GTK_IS_VIEW_PANEL(widget)) { /* Changement de binaire ? */ old_binary = G_OPENIDA_BINARY(g_object_get_data(ref, "current_binary")); binary = gtk_view_panel_get_binary(GTK_VIEW_PANEL(widget)); if (old_binary != binary) { notify_panels_of_binary_change(binary); change_editor_items_current_binary(ref, binary); } change_editor_items_current_view(ref, GTK_VIEW_PANEL(widget)); refresh_editor_menus(ref, binary, GTK_BIN_VIEW(widget)); notify_panels_of_view_change(GTK_VIEW_PANEL(widget), false); } } /****************************************************************************** * * * Paramètres : ref = adresse de l'espace de référencement global. * * binary = représentation de contenu binaire active. * * view = type de visualisation courante. * * * * Description : Met en concordance les menus avec l'édition courante. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void refresh_editor_menus(GObject *ref, GOpenidaBinary *binary, GtkBinView *view) { GtkCheckMenuItem *menuitem; /* Menu à coche à traiter */ /* Affichage : type de vue */ menuitem = GTK_CHECK_MENU_ITEM(g_object_get_data(ref, "textview")); g_signal_handlers_disconnect_by_func(menuitem, G_CALLBACK(mcb_view_change_support), ref); menuitem = GTK_CHECK_MENU_ITEM(g_object_get_data(ref, "graphview")); g_signal_handlers_disconnect_by_func(menuitem, G_CALLBACK(mcb_view_change_support), ref); if (GTK_IS_BLOCK_VIEW(view)) { menuitem = GTK_CHECK_MENU_ITEM(g_object_get_data(ref, "textview")); gtk_check_menu_item_set_active(menuitem, TRUE); } else { menuitem = GTK_CHECK_MENU_ITEM(g_object_get_data(ref, "graphview")); gtk_check_menu_item_set_active(menuitem, TRUE); } menuitem = GTK_CHECK_MENU_ITEM(g_object_get_data(ref, "textview")); g_signal_connect(menuitem, "toggled", G_CALLBACK(mcb_view_change_support), ref); menuitem = GTK_CHECK_MENU_ITEM(g_object_get_data(ref, "graphview")); g_signal_connect(menuitem, "toggled", G_CALLBACK(mcb_view_change_support), ref); } /* ---------------------------------------------------------------------------------- */ /* PARTIE DEDIEE AU MODE DEBOGAGE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : debugger = débogueur intervenant dans l'action. * * sig = identifiant du signal source (nul si indéterminé).* * addr = adresse de l'instruction courante. * * thread = identifiant du thread concerné. * * ref = espace de référencement global. * * * * Description : Prend note d'une pause dans le débogage. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void on_debugger_halted(GBinaryDebugger *debugger, int sig, vmpa_t addr, pid_t thread, GObject *ref) { printf("HALT (sig=%d) at 0x%016llx\n", sig, addr); } /* ---------------------------------------------------------------------------------- */ /* INTEGRATION DE LA BARRE D'OUTILS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : ref = espace de référencement global. * * * * Description : Construit la barre d'outils de l'éditeur. * * * * Retour : Adresse du composant mis en place. * * * * Remarques : - * * * ******************************************************************************/ static GtkWidget *build_editor_toolbar(GObject *ref) { GtkWidget *result; /* Support à retourner */ GEditorItem *item; /* Elément de barre d'outils */ result = gtk_toolbar_new(); gtk_widget_show(result); g_object_set_data(ref, "toolbar", result); item = create_source_tb_item(ref); register_editor_item(item); return result; }