From ed4bb73e5d68c1f81b8e0c3210aa221ec6f2675b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 31 Aug 2013 15:56:10 +0000 Subject: Loaded a binary strip into the editor. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@358 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 54 +++ src/arch/archbase.h | 5 + src/common/xml.h | 2 +- src/editor.c | 4 + src/format/elf/elf.c | 135 +++++- src/format/elf/elf_def.h | 25 +- src/format/elf/program.c | 51 ++- src/format/elf/program.h | 5 +- src/format/elf/symbols.c | 6 +- src/format/executable-int.h | 6 + src/format/executable.c | 29 ++ src/format/executable.h | 4 + src/glibext/Makefile.am | 1 + src/glibext/gbinportion.c | 938 +++++++++++++++++++++++++++++++++++++++ src/glibext/gbinportion.h | 148 ++++++ src/gtkext/Makefile.am | 1 + src/gtkext/graph/nodes/flow.c | 4 + src/gtkext/graph/nodes/virtual.c | 16 +- src/gtkext/gtkbinarystrip.c | 462 +++++++++++++++++++ src/gtkext/gtkbinarystrip.h | 62 +++ src/gui/editem-int.h | 4 + src/gui/editem.c | 24 + src/gui/editem.h | 3 + src/gui/tb/Makefile.am | 1 + src/gui/tb/portions.c | 162 +++++++ src/gui/tb/portions.h | 38 ++ src/main.c | 3 + 27 files changed, 2177 insertions(+), 16 deletions(-) create mode 100644 src/glibext/gbinportion.c create mode 100644 src/glibext/gbinportion.h create mode 100644 src/gtkext/gtkbinarystrip.c create mode 100644 src/gtkext/gtkbinarystrip.h create mode 100644 src/gui/tb/portions.c create mode 100644 src/gui/tb/portions.h diff --git a/ChangeLog b/ChangeLog index 4c9409e..ade8874 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +13-08-31 Cyrille Bagard + + * src/arch/archbase.h: + Define some stuff for file offsets. + + * src/common/xml.h: + Update the GLib headers. + + * src/editor.c: + Load a binary strip into the editor. + + * src/format/elf/elf.c: + * src/format/elf/elf_def.h: + * src/format/elf/program.c: + * src/format/elf/program.h: + * src/format/elf/symbols.c: + * src/format/executable.c: + * src/format/executable.h: + * src/format/executable-int.h: + Cut binary programs into portions. + + * src/glibext/gbinportion.c: + * src/glibext/gbinportion.h: + New entries: introduce data portions. + + * src/glibext/Makefile.am: + Add the 'gbinportion.[ch]' files to libglibext_la_SOURCES. + + * src/gtkext/graph/nodes/flow.c: + * src/gtkext/graph/nodes/virtual.c: + Work on the code. + + * src/gtkext/gtkbinarystrip.c: + * src/gtkext/gtkbinarystrip.h: + New entries: create binary strips for the GUI. + + * src/gtkext/Makefile.am: + Add the 'gtkbinarystrip.[ch]' files to libgtkext_la_SOURCES. + + * src/gui/editem.c: + * src/gui/editem.h: + * src/gui/editem-int.h: + Handle a global position in the current binary. + + * src/gui/tb/Makefile.am: + Add the 'portions.[ch]' files to libguitb_la_SOURCES. + + * src/gui/tb/portions.c: + * src/gui/tb/portions.h: + Create a place for a global binary strip. + + * src/main.c: + Load the binary strip colors. + 13-08-21 Cyrille Bagard * plugins/androhelpers/try_n_catch.c: diff --git a/src/arch/archbase.h b/src/arch/archbase.h index 1169c16..5ef412c 100644 --- a/src/arch/archbase.h +++ b/src/arch/archbase.h @@ -30,6 +30,10 @@ +#define OFF_FMT "%ld" +#define OFF_CAST(v) ((long)v) + + /* Octet de données binaires */ typedef uint8_t bin_t; @@ -42,6 +46,7 @@ typedef uint64_t vmpa_t; #define VMPA_FMT "0x%llx" #define VMPA_FMT_LONG "0x%08llx" +#define VMPA_CAST(v) ((unsigned long long)v) #define VMPA_MAX_SIZE 19 diff --git a/src/common/xml.h b/src/common/xml.h index f96f65a..c637235 100644 --- a/src/common/xml.h +++ b/src/common/xml.h @@ -26,8 +26,8 @@ #define _XML_H +#include #include -#include #include #include #include diff --git a/src/editor.c b/src/editor.c index 6386858..5df04ed 100644 --- a/src/editor.c +++ b/src/editor.c @@ -35,6 +35,7 @@ #include "gui/status.h" #include "gui/menus/menubar.h" #include "gui/panels/panel.h" +#include "gui/tb/portions.h" #include "gui/tb/source.h" @@ -421,6 +422,9 @@ static GtkWidget *build_editor_toolbar(GObject *ref) item = create_source_tb_item(ref); register_editor_item(item); + item = create_portions_tb_item(ref); + register_editor_item(item); + return result; diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 158a6b6..6807e36 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -26,9 +26,13 @@ #include #include +#include #include +#include + + #include "elf-int.h" #include "program.h" #include "section.h" @@ -39,11 +43,11 @@ -#ifndef _ -# define _(str) (str) -#endif +/* Taille maximale d'une description */ +#define MAX_PORTION_DESC 256 + /* Initialise la classe des formats d'exécutables ELF. */ @@ -58,6 +62,9 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *); /* Fournit l'adresse mémoire du point d'entrée du programme. */ static vmpa_t g_elf_format_get_entry_point(const GElfFormat *); +/* Etend la définition des portions au sein d'un binaire. */ +static void g_elf_format_refine_portions(const GElfFormat *, GBinPortion *); + /* Fournit les références aux zones binaires à analyser. */ static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *); @@ -139,6 +146,7 @@ static void g_elf_format_init(GElfFormat *format) exe_format->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point; + exe_format->refine_portions = (refine_portions_fc)g_elf_format_refine_portions; exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts; exe_format->translate_addr = (translate_addr_fc)g_elf_format_translate_address_into_offset; @@ -291,6 +299,127 @@ static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format) /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * +* raw = portion de binaire brut à raffiner. * +* * +* Description : Etend la définition des portions au sein d'un binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion *raw) +{ + uint16_t i; /* Boucle de parcours */ + off_t offset; /* Début de part de programme */ + elf_phdr phdr; /* En-tête de programme ELF */ + uint32_t p_flags; /* Droits associés à une partie*/ + const char *background; /* Fond signigicatif */ + GBinPortion *new; /* Nouvelle portion définie */ + char desc[MAX_PORTION_DESC]; /* Description d'une portion */ + PortionAccessRights rights; /* Droits d'une portion */ + elf_shdr strings; /* Section des descriptions */ + bool has_strings; /* Section trouvée ? */ + elf_shdr section; /* En-tête de section ELF */ + uint64_t sh_flags; /* Droits associés à une partie*/ + const char *name; /* Nom trouvé ou NULL */ + + /* Côté segments basiques */ + +#if 0 + for (i = 0; i < ELF_HDR(format, format->header, e_phnum); i++) + { + offset = ELF_HDR(format, format->header, e_phoff) + + ELF_HDR(format, format->header, e_phentsize) * i; + + if (!read_elf_program_header(format, &offset, &phdr)) + continue; + + p_flags = ELF_PHDR(format, phdr, p_flags); + + if (p_flags & PF_X) background = BPC_CODE; + else if (p_flags & PF_W) background = BPC_DATA; + else background = BPC_DATA_RO; + + new = g_binary_portion_new(background); + + sprintf(desc, "%s %s", + _("Segment"), + get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type))); + + g_binary_portion_set_desc(new, desc); + + g_binary_portion_set_values(new, + ELF_PHDR(format, phdr, p_offset), + ELF_PHDR(format, phdr, p_filesz), + ELF_PHDR(format, phdr, p_vaddr)); + + rights = PAC_NONE; + if (p_flags & PF_R) rights |= PAC_READ; + if (p_flags & PF_W) rights |= PAC_WRITE; + if (p_flags & PF_X) rights |= PAC_EXEC; + + g_binary_portion_set_rights(new, rights); + + g_binary_portion_include(raw, new); + + } +#endif + + /* Inclusion des sections, si possible... */ + + has_strings = find_elf_section_by_index(format, + ELF_HDR(format, format->header, e_shstrndx), + &strings); + + for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++) + { + if (!find_elf_section_by_index(format, i, §ion)) + continue; + + sh_flags = ELF_SHDR(format, section, sh_flags); + + if (sh_flags & SHF_EXECINSTR) background = BPC_CODE; + else if (sh_flags & SHF_WRITE) background = BPC_DATA; + else background = BPC_DATA_RO; + + new = g_binary_portion_new(background); + + if (has_strings) + name = extract_name_from_elf_string_section(format, &strings, + ELF_SHDR(format, section, sh_name)); + else name = NULL; + + if (name != NULL) + sprintf(desc, "%s %s", _("Section"), name); + else + sprintf(desc, "%s ???", _("Section")); + + g_binary_portion_set_desc(new, desc); + + rights = PAC_NONE; + if (sh_flags & SHF_ALLOC) rights |= PAC_READ; + if (sh_flags & SHF_WRITE) rights |= PAC_WRITE; + if (sh_flags & SHF_EXECINSTR) rights |= PAC_EXEC; + + g_binary_portion_set_rights(new, rights); + + g_binary_portion_set_values(new, + ELF_SHDR(format, section, sh_offset), + ELF_SHDR(format, section, sh_size), + ELF_SHDR(format, section, sh_addr)); + + g_binary_portion_include(raw, new); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * * count = quantité de zones listées. [OUT] * * * * Description : Fournit les références aux zones binaires à analyser. * diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h index dda1b1c..831e4ff 100644 --- a/src/format/elf/elf_def.h +++ b/src/format/elf/elf_def.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * elf_def.h - liste des structures et constantes utilisées par le format ELF * - * Copyright (C) 2009-2010 Cyrille Bagard + * Copyright (C) 2009-2013 Cyrille Bagard * * This file is part of OpenIDA. * @@ -178,6 +178,28 @@ typedef union _elf_phdr #define ELF_SIZEOF_PHDR(fmt) (fmt->is_32b ? sizeof(elf32_phdr) : sizeof(elf64_phdr)) +/* Valeurs possibles pour p_type */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ /* Valeurs possibles pour p_flags */ @@ -246,6 +268,7 @@ typedef union _elf_shdr /* Valeurs possibles pour sh_flags */ +#define SHF_WRITE (1 << 0) /* Accessible en écriture */ #define SHF_ALLOC (1 << 1) /* Copie en mémoire pdt l'exec.*/ #define SHF_EXECINSTR (1 << 2) /* Section exécutable */ #define SHF_STRINGS (1 << 5) /* Contient des chaînes ('\0') */ diff --git a/src/format/elf/program.c b/src/format/elf/program.c index f55b7c7..48d6d19 100644 --- a/src/format/elf/program.c +++ b/src/format/elf/program.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * program.c - gestion des en-têtes de programme d'un ELF * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard * * This file is part of OpenIDA. * @@ -30,6 +30,55 @@ /****************************************************************************** * * +* Paramètres : p_type = type associé à un en-tête de programme. * +* * +* Description : Fournit la description humaine d'un type de segment ELF. * +* * +* Retour : Désignation prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_elf_program_type_desc(uint32_t p_type) +{ + const char *result; /* Description à renvoyer */ + +#define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break; + + switch(p_type) + { + MAKE_STRING_FROM_PT(PT_NULL); + MAKE_STRING_FROM_PT(PT_LOAD); + MAKE_STRING_FROM_PT(PT_DYNAMIC); + MAKE_STRING_FROM_PT(PT_INTERP); + MAKE_STRING_FROM_PT(PT_NOTE); + MAKE_STRING_FROM_PT(PT_SHLIB); + MAKE_STRING_FROM_PT(PT_PHDR); + MAKE_STRING_FROM_PT(PT_TLS); + MAKE_STRING_FROM_PT(PT_NUM); + MAKE_STRING_FROM_PT(PT_LOOS); + MAKE_STRING_FROM_PT(PT_GNU_EH_FRAME); + MAKE_STRING_FROM_PT(PT_GNU_STACK); + MAKE_STRING_FROM_PT(PT_GNU_RELRO); + MAKE_STRING_FROM_PT(PT_LOSUNW); + MAKE_STRING_FROM_PT(PT_SUNWSTACK); + MAKE_STRING_FROM_PT(PT_HIOS); + MAKE_STRING_FROM_PT(PT_LOPROC); + MAKE_STRING_FROM_PT(PT_HIPROC); + + default: + result = "PT_???"; + break; + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = description de l'exécutable à consulter. * * index = indice de la section recherchée. * * program = ensemble d'informations à faire remonter. [OUT] * diff --git a/src/format/elf/program.h b/src/format/elf/program.h index 1718ca7..276e720 100644 --- a/src/format/elf/program.h +++ b/src/format/elf/program.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * program.h - prototypes pour la gestion des en-têtes de programme d'un ELF * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2013 Cyrille Bagard * * This file is part of OpenIDA. * @@ -30,6 +30,9 @@ +/* Fournit la description humaine d'un type de segment ELF. */ +const char *get_elf_program_type_desc(uint32_t); + /* Recherche un programme donné au sein de binaire par indice. */ bool find_elf_program_by_index(const GElfFormat *, uint16_t, elf_phdr *); diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index df1b613..50750ae 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -28,6 +28,9 @@ #include +#include + + #include "elf-int.h" #include "helper_x86.h" #include "section.h" @@ -38,9 +41,6 @@ -#define _(str) str - - /* Récupère la désignation d'un symbole donné. */ diff --git a/src/format/executable-int.h b/src/format/executable-int.h index 49b5275..6b843a5 100644 --- a/src/format/executable-int.h +++ b/src/format/executable-int.h @@ -38,6 +38,9 @@ typedef FormatTargetMachine (* get_target_machine_fc) (const GExeFormat *); /* Fournit l'adresse mémoire du point d'entrée du programme. */ typedef vmpa_t (* get_entry_point_fc) (const GExeFormat *); +/* Etend la définition des portions au sein d'un binaire. */ +typedef void (* refine_portions_fc) (const GExeFormat *, GBinPortion *); + /* Fournit les références aux zones de code à analyser. */ typedef GBinPart ** (* get_parts_fc) (const GExeFormat *, size_t *); @@ -57,11 +60,14 @@ struct _GExeFormat get_target_machine_fc get_machine; /* Architecture ciblée */ get_entry_point_fc get_entry_point; /* Obtention du point d'entrée */ + refine_portions_fc refine_portions; /* Décrit les portions binaires*/ get_parts_fc get_parts; /* Liste des parties binaires */ translate_addr_fc translate_addr; /* Correspondance addr -> pos */ translate_off_fc translate_off; /* Correspondance pos -> addr */ + GBinPortion *portions; /* Morceaux binaires distincts */ + }; /* Format d'exécutable générique (classe) */ diff --git a/src/format/executable.c b/src/format/executable.c index 2d7c185..13482c0 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -126,6 +126,35 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *format) /****************************************************************************** * * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Décrit les différentes portions qui composent le binaire. * +* * +* Retour : Défintions de zones. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPortion *g_exe_format_get_portions(GExeFormat *format) +{ + if (format->portions == NULL) + { + format->portions = g_binary_portion_new(BPC_RAW); + g_binary_portion_set_values(format->portions, 0, G_BIN_FORMAT(format)->length, 0); + + if (format->refine_portions != NULL) + format->refine_portions(format, format->portions); + + } + + return format->portions; + +} + + +/****************************************************************************** +* * * 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 d4f2645..2831696 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -29,6 +29,7 @@ #include "part.h" +#include "../glibext/gbinportion.h" @@ -74,6 +75,9 @@ FormatTargetMachine g_exe_format_get_target_machine(const GExeFormat *); /* Fournit l'adresse mémoire du point d'entrée du programme. */ 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 les références aux zones binaires à analyser. */ GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *); diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index b6f100b..e5c1a46 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -7,6 +7,7 @@ libglibext_la_SOURCES = \ chrysamarshal.h chrysamarshal.c \ delayed-int.h \ delayed.h delayed.c \ + gbinportion.h gbinportion.c \ gbufferline.h gbufferline.c \ gbuffersegment.h gbuffersegment.c \ gcodebuffer.h gcodebuffer.c \ diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c new file mode 100644 index 0000000..8272e55 --- /dev/null +++ b/src/glibext/gbinportion.c @@ -0,0 +1,938 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * binportion.c - représentation graphique de portions de binaire + * + * Copyright (C) 2013 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 Foobar. If not, see . + */ + + +#include "gbinportion.h" + + +#include +#include +#include + + +#include + + +#include "../common/extstr.h" + + + +/* --------------------------- COULEURS DE REPRESENTATION --------------------------- */ + + +/* Information sur une colorisation de portion */ +typedef struct _portion_color +{ + bp_color_t code; /* Identifiant pour les usages */ + char *name; /* Désignation humaine */ + + double red; /* Taux de rouge */ + double green; /* Taux de vert */ + double blue; /* Taux de bleu */ + double alpha; /* Transparence */ + +} portion_color; + + +/* Mémoire centrale... */ +static portion_color *_portion_colors = NULL; +static size_t _portion_colors_count = 0; + + +/* Compare deux enregistrements de couleur pour portions. */ +static int compare_portion_colors(const portion_color *, const portion_color *); + +/* Tente de retrouver une couleur de portion donnée. */ +static portion_color *find_binary_portion_color(bp_color_t); + + + +/* ------------------------------- PORTION DE BINAIRE ------------------------------- */ + + +/* Portion de données binaires quelconques (instance) */ +struct _GBinPortion +{ + GObject parent; /* A laisser en premier */ + + GBinPortion *container; /* Portion parente ou racine */ + + bp_color_t code; /* Code de la couleur de fond */ + + char *desc; /* Désignation humaine */ + + off_t offset; /* Position physique */ + off_t size; /* Taille de la partie */ + vmpa_t addr; /* Adresse associée */ + + PortionAccessRights rights; /* Droits d'accès */ + + GBinPortion **sub_portions; /* Portions incluses */ + size_t sub_count; /* Quantité d'inclusions */ + +#ifdef DEBUG + unsigned int valid; /* Instructions reconnues */ + unsigned int db; /* Instructions non traduites */ +#endif + +}; + +/* Portion de données binaires quelconques (classe) */ +struct _GBinPortionClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des blocs de données binaires. */ +static void g_binary_portion_class_init(GBinPortionClass *); + +/* Initialise une instance de bloc de données binaires. */ +static void g_binary_portion_init(GBinPortion *); + +/* Supprime toutes les références externes. */ +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étermine l'aire d'une sous-portion. */ +static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, const GdkRectangle *, GdkRectangle *); + + + +/* ---------------------------------------------------------------------------------- */ +/* COULEURS DE REPRESENTATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = échantillon n°1 à comparer. * +* b = échantillon n°2 à comparer. * +* * +* Description : Compare deux enregistrements de couleur pour portions. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int compare_portion_colors(const portion_color *a, const portion_color *b) +{ + int result; /* Bilan à renvoyer */ + + if (a->code < b->code) + result = -1; + + else if (a->code > b->code) + result = 1; + + else + result = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation humaine de la couleur. * +* red = taux de rouge dans la couleur. * +* gren = taux de vert dans la couleur. * +* blue = taux de bleu dans la couleur. * +* alpha = transparence de la couleur. * +* * +* Description : Enregistre une couleur pour le dessin de portions. * +* * +* Retour : true si l'enregistrement a pu être effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_binary_portion_color(const char *name, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) +{ + bp_color_t code; /* Accès rapide à la couleur */ + portion_color *new; /* Nouvel élément à constituer */ + + /* Vérification de l'unicité des noms */ + + code = fnv_64a_hash(name); + + new = find_binary_portion_color(code); + if (new != NULL) return false; + + /* Création du nouvel élément */ + + _portion_colors = (portion_color *)realloc(_portion_colors, + ++_portion_colors_count * sizeof(portion_color)); + + new = &_portion_colors[_portion_colors_count - 1]; + + /* Définition du nouvel élément */ + + new->name = strdup(name); + new->code = code; + + new->red = red / 255.0; + new->green = green / 255.0; + new->blue = blue / 255.0; + new->alpha = alpha / 255.0; + + /* Actualisation finale par tri */ + + qsort(_portion_colors, _portion_colors_count, sizeof(portion_color), + (__compar_fn_t)compare_portion_colors); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation humaine de la couleur. * +* * +* Description : Supprime une couleur pour le dessin de portions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unregister_binary_portion_color(const char *name) +{ + bp_color_t code; /* Accès rapide à la couleur */ + portion_color *item; /* Elément à retirer */ + size_t left; /* Quantité à déplacer */ + + code = fnv_64a_hash(name); + + item = find_binary_portion_color(code); + if (item == NULL) return; + + free(item->name); + + left = (size_t)(_portion_colors + _portion_colors_count) - (size_t)(item + 1); + + if (left > 0) + memmove(item, item + 1, left); + + _portion_colors = (portion_color *)realloc(_portion_colors, + --_portion_colors_count * sizeof(portion_color)); + +} + + +/****************************************************************************** +* * +* Paramètres : code = identifiant de la couleur à retrouver. * +* * +* Description : Tente de retrouver une couleur de portion donnée. * +* * +* Retour : Caractéristiques de la couleur visée, ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static portion_color *find_binary_portion_color(bp_color_t code) +{ + portion_color *result; /* Elément trouvé à retourner */ + + result = (portion_color *)bsearch(&code, _portion_colors, + _portion_colors_count, sizeof(portion_color), + (__compar_fn_t)compare_portion_colors); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Enregistre les couleurs de base pour le dessin des portions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_binary_portion_colors(void) +{ + register_binary_portion_color(BPC_RAW, 0, 0, 0, 255); + register_binary_portion_color(BPC_CODE, 0, 0, 255, 255); + register_binary_portion_color(BPC_DATA, 255, 255, 0, 255); + register_binary_portion_color(BPC_DATA_RO, 0, 255, 0, 255); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Supprime les couleurs de base pour le dessin des portions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_binary_portion_colors(void) +{ + while (_portion_colors_count > 0) + unregister_binary_portion_color(_portion_colors[0].name); + + if (_portion_colors != NULL) + { + free(_portion_colors); + _portion_colors = NULL; + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* PORTION DE BINAIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour les blocs de données. */ +G_DEFINE_TYPE(GBinPortion, g_binary_portion, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des blocs de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_class_init(GBinPortionClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_portion_dispose; + object->finalize = (GObjectFinalizeFunc)g_binary_portion_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance à initialiser. * +* * +* Description : Initialise une instance de bloc de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_init(GBinPortion *portion) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_dispose(GBinPortion *portion) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < portion->sub_count; i++) + g_object_unref(G_OBJECT(portion->sub_portions[i])); + + G_OBJECT_CLASS(g_binary_portion_parent_class)->dispose(G_OBJECT(portion)); + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_finalize(GBinPortion *portion) +{ + if (portion->desc != NULL) + free(portion->desc); + + if (portion->sub_portions != NULL) + free(portion->sub_portions); + + G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion)); + +} + + +/****************************************************************************** +* * +* Paramètres : code = désignation humaine de la couleur de fond. * +* * +* Description : Crée une description de partie de code vierge. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPortion *g_binary_portion_new(const char *code) +{ + GBinPortion *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BIN_PORTION, NULL); + + result->code = fnv_64a_hash(code); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* desc = nom à donner à la partie. * +* * +* Description : Attribue une description humaine à une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_set_desc(GBinPortion *portion, const char *desc) +{ + if (portion->desc != NULL) free(portion->desc); + + portion->desc = strdup(desc); + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à consulter. * +* * +* Description : Fournit la description attribuée à une partie de code. * +* * +* Retour : Nom donné à la partie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_portion_get_desc(const GBinPortion *portion) +{ + return portion->desc; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* offset = position de la section à conserver. * +* size = taille de la section à conserver. * +* addr = adresse de la section à conserver. * +* * +* Description : Définit les valeurs utiles d'une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_set_values(GBinPortion *portion, off_t offset, off_t size, vmpa_t addr) +{ + portion->offset = offset; + portion->size = size; + portion->addr = addr; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* rights = droits d'accès de la partie. * +* * +* Description : Définit les droits associés à une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_set_rights(GBinPortion *portion, PortionAccessRights rights) +{ + portion->rights = rights; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à consulter. * +* * +* Description : Fournit les droits associés à une partie de code. * +* * +* Retour : Droits d'accès de la partie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PortionAccessRights g_binary_portion_get_rights(const GBinPortion *portion) +{ + return portion->rights; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* sub = portion à inclure dans la définition courante. * +* * +* Description : Procède à l'inclusion d'une portion dans une autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) +{ + portion->sub_portions = (GBinPortion **)realloc(portion->sub_portions, + ++portion->sub_count * sizeof(GBinPortion *)); + + portion->sub_portions[portion->sub_count - 1] = sub; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = portion mère à consulter. * +* sub = portion fille à traiter. * +* area = étendue de représentation de la portion mère. * +* sub_area = étendue de représentation de la portion fille. * +* * +* Description : Détermine l'aire d'une sous-portion. * +* * +* Retour : true si la sous-surface a été calculée correctement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_portion_compute_sub_area(GBinPortion *portion, GBinPortion *sub, const GdkRectangle *area, GdkRectangle *sub_area) +{ + /* On saute les portions comme le segment GNU_STACK... */ + if (sub->size == 0) return false; + + sub_area->y = area->y; + sub_area->height = area->height; + + sub_area->x = area->x + (sub->offset * area->width) / portion->size; + sub_area->width = (sub->size * area->width) / portion->size; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* x = abscisse du point de recherche. * +* y = ordonnée du point de recherche. * +* area = étendue de portion mère, puis celle trouvée. [OUT] * +* * +* Description : Recherche la portion présente à un point donné. * +* * +* Retour : Portion trouvée à l'endroit indiqué. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPortion *g_binary_portion_find_at_pos(GBinPortion *portion, gint x, GdkRectangle *area) +{ + GBinPortion *result; /* Portion à retourner */ + size_t i; /* Boucle de parcours */ + GBinPortion *sub; /* Portion incluse à traiter */ + GdkRectangle sub_area; /* Etendue d'une sous-portion */ + + result = NULL; + + for (i = 0; i < portion->sub_count && !result; i++) + { + sub = portion->sub_portions[i]; + + if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area)) + continue; + + if (sub_area.x <= x && x < (sub_area.x + sub_area.width)) + { + result = sub; + *area = sub_area; + } + + } + + if (result == NULL) + result = portion; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* addr = adresse du point de recherche. * +* area = étendue de portion mère, puis celle trouvée. [OUT] * +* * +* Description : Recherche la portion présente à une adresse donnée. * +* * +* Retour : Portion trouvée à l'endroit indiqué. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, vmpa_t addr, GdkRectangle *area) +{ + GBinPortion *result; /* Portion à retourner */ + size_t i; /* Boucle de parcours #1 */ + GBinPortion *sub; /* Portion incluse à traiter */ + GdkRectangle sub_area; /* Etendue d'une sous-portion */ + size_t j; /* Boucle de parcours #2 */ + + result = NULL; + + for (i = 0; i < portion->sub_count && !result; i++) + { + sub = portion->sub_portions[i]; + + /* Portion non allouée en mémoire -> adresse nulle ; on écarte */ + if (sub->addr == 0) + continue; + + if (addr < sub->addr || addr >= (sub->addr + sub->size)) + continue; + + if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area)) + continue; + + for (j = 0; j < sub->sub_count && !result; j++) + result = g_binary_portion_find_at_addr(sub->sub_portions[j], addr, &sub_area); + + if (result == NULL) + { + result = sub; + *area = sub_area; + } + + } + + if (result == NULL) + result = portion; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* x = abscisse du point de recherche. * +* area = étendue de représentation de la portion mère. * +* addr = adresse correspondante. [OUT] * +* * +* Description : Fournit la position correspondant à une adresse donnée. * +* * +* Retour : Succès de la traduction. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_get_addr_from_pos(GBinPortion *portion, gint x, const GdkRectangle *area, vmpa_t *addr) +{ + GdkRectangle owner_area; /* Aire de contenance */ + GBinPortion *owner; /* Conteneur propriétaire */ + + owner_area = *area; + + owner = g_binary_portion_find_at_pos(portion, x, &owner_area); + if (owner == NULL) return false; + + *addr = owner->addr + (owner->size * (x - owner_area.x)) / owner_area.width; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* addr = adresse du point de recherche. * +* area = étendue de représentation de la portion mère. * +* x = position correspondante. [OUT] * +* * +* Description : Fournit l'adresse correspondant à une position donnée. * +* * +* Retour : Succès de la traduction. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, vmpa_t addr, const GdkRectangle *area, gint *x) +{ + GdkRectangle owner_area; /* Aire de contenance */ + GBinPortion *owner; /* Conteneur propriétaire */ + vmpa_t diff; /* Décallage à appliquer */ + + owner_area = *area; + + owner = g_binary_portion_find_at_addr(portion, addr, &owner_area); + if (owner == NULL) return false; + + diff = addr - owner->addr; + + *x = owner_area.x + (diff * owner_area.width) / owner->size; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* x = abscisse du point de recherche. * +* y = ordonnée du point de recherche. * +* area = étendue de représentation de la portion mère. * +* tooltip = astuce à compléter. [OUT] * +* * +* Description : Prépare une astuce concernant une portion pour son affichage.* +* * +* Retour : TRUE pour valider l'affichage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gboolean g_binary_portion_query_tooltip(GBinPortion *portion, gint x, gint y, const GdkRectangle *area, GtkTooltip *tooltip) +{ + GBinPortion *selected; /* Portion à décrire ici */ + char *markup; /* Description à construire */ + GBinPortion *iter; /* Remontée hiérarchique */ + char value[2 * VMPA_MAX_SIZE]; /* Traduction en texte */ + + selected = g_binary_portion_find_at_pos(portion, x, (GdkRectangle []) { *area }); + + /* Nom */ + + if (selected->desc != NULL) + { + markup = strdup(""); + markup = stradd(markup, selected->desc); + markup = stradd(markup, "\n"); + + for (iter = selected->container; iter != NULL; iter = iter->container) + if (iter->desc != NULL) + { + markup = stradd(markup, selected->desc); + markup = stradd(markup, "\n"); + } + + markup = stradd(markup, "\n"); + + } + else markup = strdup(""); + + markup = stradd(markup, "taille : "); + snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->size)); + markup = stradd(markup, value); + markup = stradd(markup, "\n"); + + /* Localisation */ + + markup = stradd(markup, ""); + markup = stradd(markup, _("Localisation")); + markup = stradd(markup, "\n"); + + markup = stradd(markup, _("physical: from ")); + snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->offset)); + markup = stradd(markup, value); + markup = stradd(markup, _(" to ")); + snprintf(value, 2 * VMPA_MAX_SIZE, OFF_FMT, OFF_CAST(selected->offset + selected->size)); + markup = stradd(markup, value); + markup = stradd(markup, "\n"); + + markup = stradd(markup, _("memory: from ")); + snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr)); + markup = stradd(markup, value); + markup = stradd(markup, _(" to ")); + snprintf(value, 2 * VMPA_MAX_SIZE, VMPA_FMT_LONG, VMPA_CAST(selected->addr + selected->size)); + markup = stradd(markup, value); + markup = stradd(markup, "\n\n"); + + /* Droits d'accès */ + + markup = stradd(markup, ""); + markup = stradd(markup, _("Rights")); + markup = stradd(markup, "\n"); + + snprintf(value, 2 * VMPA_MAX_SIZE, "%s%s%s", + selected->rights & PAC_READ ? "r" : "-", + selected->rights & PAC_WRITE ? "w" : "-", + selected->rights & PAC_EXEC ? "x" : "-"); + + markup = stradd(markup, value); + + /* Impression finale */ + + gtk_tooltip_set_markup(tooltip, markup); + free(markup); + + return TRUE; + +} + + + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à consulter. * +* cr = contexte graphique pour le dessin. * +* area = étendue mise à disposition. * +* * +* Description : Représente la portion sur une bande dédiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_draw(GBinPortion *portion, cairo_t *cr, const GdkRectangle *area) +{ + portion_color *color; /* Couleur du fond */ + size_t i; /* Boucle de parcours */ + GBinPortion *sub; /* Portion incluse à montrer */ + GdkRectangle sub_area; /* Etendue d'une sous-portion */ + + /* Dessin de la portion courante */ + + cairo_set_line_width(cr, 1.0); + + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); + + color = find_binary_portion_color(portion->code); + + if (color != NULL) + cairo_set_source_rgba(cr, + color->red, color->green, color->blue, + color->alpha); + + cairo_rectangle(cr, area->x, area->y, area->width, area->height); + cairo_fill(cr); + + if (color != NULL) + cairo_set_source_rgba(cr, + color->red * 0.7, color->green * 0.7, color->blue * 0.7, + color->alpha); + + cairo_rectangle(cr, area->x, area->y, area->width, area->height); + cairo_stroke(cr); + + /* Dessin des portions incluses */ + + sub_area.y = area->y; + sub_area.height = area->height; + + for (i = 0; i < portion->sub_count; i++) + { + sub = portion->sub_portions[i]; + + if (!g_binary_portion_compute_sub_area(portion, sub, area, &sub_area)) + continue; + + g_binary_portion_draw(sub, cr, &sub_area); + + } + +} diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h new file mode 100644 index 0000000..826d65f --- /dev/null +++ b/src/glibext/gbinportion.h @@ -0,0 +1,148 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * binportion.h - prototypes pour la représentation graphique de portions de binaire + * + * Copyright (C) 2013 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 Foobar. If not, see . + */ + + +#ifndef _GLIBEXT_BINPORTION_H +#define _GLIBEXT_BINPORTION_H + + +#include +#include +#include + + +#include "../arch/archbase.h" +#include "../common/fnv1a.h" + + + +/* --------------------------- COULEURS DE REPRESENTATION --------------------------- */ + + +/* Converion code -> identifiant unique */ +typedef fnv64_t bp_color_t; + +/* Identifiant non valide */ +#define BP_NO_COLOR 0 + +/* Identifiant pour la transparence */ +#define BP_INHERIT_COLOR 1 + + + +#define BPC_RAW "raw" +#define BPC_CODE "code" +#define BPC_DATA "data" +#define BPC_DATA_RO "data-ro" +#define BPC_DISASS_ERROR "disassembly-error" + + + + + +/* Enregistre une couleur pour le dessin de portions. */ +bool register_binary_portion_color(const char *, uint8_t, uint8_t, uint8_t, uint8_t); + +/* Supprime une couleur pour le dessin de portions. */ +void unregister_binary_portion_color(const char *); + +/* Enregistre les couleurs de base pour le dessin des portions. */ +void init_binary_portion_colors(void); + +/* Supprime les couleurs de base pour le dessin des portions. */ +void exit_binary_portion_colors(void); + + + + + +#define G_TYPE_BIN_PORTION (g_binary_portion_get_type()) +#define G_BIN_PORTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_PORTION, GBinPortion)) +#define G_IS_BIN_PORTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BIN_PORTION)) +#define G_BIN_PORTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_PORTION, GBinPortionClass)) +#define G_IS_BIN_PORTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_PORTION)) +#define G_BIN_PORTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_PORTION, GBinPortionClass)) + + +/* Portion de données binaires quelconques (instance) */ +typedef struct _GBinPortion GBinPortion; + +/* Portion de données binaires quelconques (classe) */ +typedef struct _GBinPortionClass GBinPortionClass; + + +/* Droits d'accès à une portion */ +typedef enum _PortionAccessRights +{ + PAC_NONE = (0 << 0), /* Aucun */ + PAC_READ = (1 << 0), /* Lecture */ + PAC_WRITE = (1 << 1), /* Ecriture */ + PAC_EXEC = (1 << 2) /* Exécution */ + +} PortionAccessRights; + + +/* Indique le type défini par la GLib pour les blocs de données. */ +GType g_binary_portion_get_type(void); + +/* Crée une description de partie de code vierge. */ +GBinPortion *g_binary_portion_new(const char *); + +/* Attribue une description humaine à une partie de code. */ +void g_binary_portion_set_desc(GBinPortion *, const char *); + +/* Fournit la description attribuée à une partie de code. */ +const char *g_binary_portion_get_desc(const GBinPortion *); + +/* Définit les valeurs utiles d'une partie de code. */ +void g_binary_portion_set_values(GBinPortion *, off_t, off_t, vmpa_t); + +/* Définit les droits associés à une partie de code. */ +void g_binary_portion_set_rights(GBinPortion *, PortionAccessRights); + +/* Fournit les droits associés à une partie de code. */ +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 *); + +/* Recherche la portion présente à un point donné. */ +GBinPortion *g_binary_portion_find_at_pos(GBinPortion *, gint, GdkRectangle *); + +/* Recherche la portion présente à une adresse donnée. */ +GBinPortion *g_binary_portion_find_at_addr(GBinPortion *, vmpa_t, GdkRectangle *); + +/* Fournit la position correspondant à une adresse donnée. */ +bool g_binary_portion_get_addr_from_pos(GBinPortion *, gint, const GdkRectangle *, vmpa_t *); + +/* Fournit l'adresse correspondant à une position donnée. */ +bool g_binary_portion_get_pos_from_addr(GBinPortion *, vmpa_t, const GdkRectangle *, gint *); + +/* Prépare une astuce concernant une portion pour son affichage. */ +gboolean g_binary_portion_query_tooltip(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *); + +/* Représente la portion sur une bande dédiée. */ +void g_binary_portion_draw(GBinPortion *, cairo_t *, const GdkRectangle *); + + + +#endif /* _GLIBEXT_BINPORTION_H */ diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 6478b87..18678b8 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libgtkext.la libgtkext_la_SOURCES = \ easygtk.h easygtk.c \ + gtkbinarystrip.h gtkbinarystrip.c \ gtkextstatusbar.h gtkextstatusbar.c \ gtkblockview.h gtkblockview.c \ gtkbufferview-int.h \ diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c index fad520d..6bb2617 100644 --- a/src/gtkext/graph/nodes/flow.c +++ b/src/gtkext/graph/nodes/flow.c @@ -581,6 +581,10 @@ void g_flow_node_link(GFlowNode *node, GGraphLayout *layout, GGraphNode *nodes) void g_flow_node_place(const GFlowNode *node, GtkGraphView *view) { + printf("[put] %p (%d ; %d) - (%d ; %d)\n", node, + G_GRAPH_NODE(node)->alloc.x, G_GRAPH_NODE(node)->alloc.y, + G_GRAPH_NODE(node)->alloc.width, G_GRAPH_NODE(node)->alloc.height); + gtk_graph_view_put(view, GTK_WIDGET(node->view), &G_GRAPH_NODE(node)->alloc); } diff --git a/src/gtkext/graph/nodes/virtual.c b/src/gtkext/graph/nodes/virtual.c index 48cc1fb..de0e75e 100644 --- a/src/gtkext/graph/nodes/virtual.c +++ b/src/gtkext/graph/nodes/virtual.c @@ -473,7 +473,7 @@ static void g_virtual_node_apply_position(GVirtualNode *node) { gint min; /* Valeur minimale rencontrée */ size_t i; /* Boucle de parcours */ - gint pos_x; /* Nouvelle position #1 */ + gint x_pos; /* Nouvelle position #1 */ gint offset; /* Décallage à faire suivre */ g_virtual_node_apply_x_line(node); @@ -484,8 +484,8 @@ static void g_virtual_node_apply_position(GVirtualNode *node) for (i = 0; i < node->count; i++) { - g_graph_node_get_position(node->children[i], &pos_x, NULL); - min = MIN(min, pos_x); + g_graph_node_get_position(node->children[i], &x_pos, NULL); + min = MIN(min, x_pos); } /* Espace pour les liens remontants */ @@ -503,10 +503,14 @@ static void g_virtual_node_apply_position(GVirtualNode *node) { /* BUG_ON(node->children[i]->alloc.x != UNINITIALIZED_NODE_POS); */ - g_graph_node_get_position(node->children[i], &pos_x, NULL); - pos_x += offset; + g_graph_node_get_position(node->children[i], &x_pos, NULL); + + printf(" == vapply == %p : %d + %d -> %d\n", + node->children[i], x_pos, offset, (int)(x_pos + offset)); - g_graph_node_set_x_position(node->children[i], pos_x); + x_pos += offset; + + g_graph_node_set_x_position(node->children[i], x_pos); } diff --git a/src/gtkext/gtkbinarystrip.c b/src/gtkext/gtkbinarystrip.c new file mode 100644 index 0000000..3f4a6a6 --- /dev/null +++ b/src/gtkext/gtkbinarystrip.c @@ -0,0 +1,462 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinarystrip.c - affichage d'un binaire sous forme de bande + * + * Copyright (C) 2013 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 Foobar. If not, see . + */ + + +#include "gtkbinarystrip.h" + + +#include "../glibext/chrysamarshal.h" + + + +/* Affichage d'un binaire en bande (instance) */ +struct _GtkBinaryStrip +{ + GtkDrawingArea parent; /* A laisser en premier */ + + GLoadedBinary *binary; /* Binaire à représenter */ + gint display_pos; /* Position à l'écran */ + + gint cursor_addr; /* Adresse de la position */ + gint cursor_pos; /* Position à l'écran */ + +}; + +/* Affichage d'un binaire en bande (classe) */ +struct _GtkBinaryStripClass +{ + GtkDrawingAreaClass parent; /* A laisser en premier */ + + void (* select_address) (GtkBinaryStrip *, vmpa_t); + +}; + + +/* Taille de l'encoche pour la position */ +#define STRIP_MARKER_SIZE 7 + + +/* Procède à l'initialisation de l'afficheur générique. */ +static void gtk_binary_strip_class_init(GtkBinaryStripClass *); + +/* Procède à l'initialisation de l'afficheur générique. */ +static void gtk_binary_strip_init(GtkBinaryStrip *); + +/* Encadre la préparation à l'affichage du composant. */ +static void gtk_binary_strip_realize(GtkWidget *); + +/* Réagit à un changement de taille du composant. */ +static void gtk_binary_strip_size_allocate(GtkWidget *, GtkAllocation *); + +/* Suit la progression de la souris sur le composant. */ +static gboolean gtk_binary_strip_button_release(GtkWidget *, GdkEventButton *); + +/* Met à jour l'affichage du composant d'affichage. */ +static gboolean gtk_binary_strip_expose(GtkWidget *, GdkEventExpose *); + +/* Prépare l'affichage d'une astuce. */ +static gboolean gtk_binary_strip_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *); + + + +/* Détermine le type du composant d'affichage générique. */ +G_DEFINE_TYPE(GtkBinaryStrip, gtk_binary_strip, GTK_TYPE_DRAWING_AREA) + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur générique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binary_strip_class_init(GtkBinaryStripClass *class) +{ + GtkWidgetClass *widget_class; /* Classe de haut niveau */ + + widget_class = GTK_WIDGET_CLASS(class); + + widget_class->realize = gtk_binary_strip_realize; + widget_class->size_allocate = gtk_binary_strip_size_allocate; + widget_class->button_release_event = gtk_binary_strip_button_release; + widget_class->expose_event = gtk_binary_strip_expose; + widget_class->query_tooltip = gtk_binary_strip_query_tooltip; + + g_signal_new("select-address", + GTK_TYPE_BINARY_STRIP, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkBinaryStripClass, select_address), + NULL, NULL, + g_cclosure_user_marshal_VOID__UINT64, + G_TYPE_NONE, 1, G_TYPE_UINT64); + +} + + +/****************************************************************************** +* * +* Paramètres : strip = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur générique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binary_strip_init(GtkBinaryStrip *strip) +{ + GObject *object; /* Autre version de l'instance */ + GtkWidget *widget; /* Autre version de l'instance */ + + object = G_OBJECT(strip); + widget = GTK_WIDGET(strip); + + g_object_set(object, "has-tooltip", TRUE, NULL); + + gtk_widget_set_size_request(widget, 400, 30); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant pour l'affichage d'une bande. * +* * +* Retour : Composant GTK créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_binary_strip_new(void) +{ + GtkBinaryStrip *result; /* Composant à retourner */ + + result = g_object_new(GTK_TYPE_BINARY_STRIP, NULL); + + return GTK_WIDGET(result); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à préparer. * +* * +* Description : Encadre la préparation à l'affichage du composant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binary_strip_realize(GtkWidget *widget) +{ + GdkCursor *cursor; /* Pointeur pour la surface */ + + GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->realize(widget); + + cursor = gdk_cursor_new(GDK_HAND1); + gdk_window_set_cursor(widget->window, cursor); + gdk_cursor_unref(cursor); + + gtk_widget_add_events(widget, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à préparer. * +* allocation = nouvelle taille à considérer. * +* * +* Description : Réagit à un changement de taille du composant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binary_strip_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkBinaryStrip *strip; /* Autre version du composant */ + GExeFormat *format; /* Format du binaire */ + GBinPortion *portions; /* Portions binaires à dessiner*/ + GdkRectangle area; /* Surface du composant */ + + GTK_WIDGET_CLASS(gtk_binary_strip_parent_class)->size_allocate(widget, allocation); + + strip = GTK_BINARY_STRIP(widget); + + if (strip->binary == NULL) + return; + + format = g_loaded_binary_get_format(strip->binary); + portions = g_exe_format_get_portions(format); + + area.x = 0; + area.y = 0; + area.width = allocation->width; + area.height = allocation->height; + + if (!g_binary_portion_get_pos_from_addr(portions, strip->cursor_addr, &area, &strip->cursor_pos)) + strip->cursor_pos = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* * +* Description : Suit la progression de la souris sur le composant. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_binary_strip_button_release(GtkWidget *widget, GdkEventButton *event) +{ + GtkBinaryStrip *strip; /* Autre version du composant */ + GExeFormat *format; /* Format du binaire */ + GBinPortion *portions; /* Portions binaires à dessiner*/ + GdkRectangle area; /* Surface du composant */ + vmpa_t addr; /* Adresse à sélectionner */ + + if (event->x < 0 || event->y < 0) + return FALSE; + if (event->x >= widget->allocation.width || event->y >= widget->allocation.height) + return FALSE; + + strip = GTK_BINARY_STRIP(widget); + format = g_loaded_binary_get_format(strip->binary); + portions = g_exe_format_get_portions(format); + + area.x = 0; + area.y = 0; + area.width = widget->allocation.width; + area.height = widget->allocation.height; + + if (g_binary_portion_get_addr_from_pos(portions, event->x, &area, &addr)) + { + strip->cursor_addr = addr; + strip->cursor_pos = event->x; + + gtk_widget_queue_draw(GTK_WIDGET(strip)); + + g_signal_emit_by_name(strip, "select-address", addr); + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à redessiner. * +* event = informations liées à l'événement. * +* * +* Description : Met à jour l'affichage du composant d'affichage. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_binary_strip_expose(GtkWidget *widget, GdkEventExpose *event) +{ + GtkBinaryStrip *strip; /* Autre vision du composant */ + cairo_t *cr; /* Contexte graphique */ + GExeFormat *format; /* Format du binaire */ + GBinPortion *portions; /* Portions binaires à dessiner*/ + GdkRectangle full; /* Taille totale de la surface */ + + strip = GTK_BINARY_STRIP(widget); + + if (strip->binary == NULL) + return FALSE; + + format = g_loaded_binary_get_format(strip->binary); + portions = g_exe_format_get_portions(format); + + cr = gdk_cairo_create(widget->window); + + cairo_rectangle(cr, + event->area.x, event->area.y, + event->area.width, event->area.height); + cairo_clip(cr); + + /* Dessin des portions de binaire */ + + full.x = 0; + full.y = 1; + full.width = widget->allocation.width; + full.height = widget->allocation.height - 1; + + g_binary_portion_draw(portions, cr, &full); + + /* Dessin de la position */ + + if (strip->cursor_pos != -1) + { + cairo_set_line_width(cr, 1); + + cairo_set_source_rgb(cr, + (1.0 * widget->style->bg[GTK_STATE_NORMAL].red) / USHRT_MAX, + (1.0 * widget->style->bg[GTK_STATE_NORMAL].green) / USHRT_MAX, + (1.0 * widget->style->bg[GTK_STATE_NORMAL].blue )/ USHRT_MAX); + + cairo_move_to(cr, strip->cursor_pos, STRIP_MARKER_SIZE); + cairo_line_to(cr, strip->cursor_pos + STRIP_MARKER_SIZE, 0); + cairo_line_to(cr, strip->cursor_pos - STRIP_MARKER_SIZE, 0); + cairo_line_to(cr, strip->cursor_pos, STRIP_MARKER_SIZE); + cairo_fill(cr); + + cairo_move_to(cr, strip->cursor_pos, full.height - STRIP_MARKER_SIZE + 1); + cairo_line_to(cr, strip->cursor_pos + STRIP_MARKER_SIZE, full.height + 1); + cairo_line_to(cr, strip->cursor_pos - STRIP_MARKER_SIZE, full.height + 1); + cairo_line_to(cr, strip->cursor_pos, full.height - STRIP_MARKER_SIZE + 1); + cairo_fill(cr); + + } + + /* Clôture */ + + cairo_destroy (cr); + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* x = abscisse de la position du message. * +* y = ordonnée de la position du message. * +* keyboard = indique une demande suite à obtiention du focus. * +* tooltip = astuce à compléter. [OUT] * +* * +* Description : Prépare l'affichage d'une astuce. * +* * +* Retour : TRUE pour un affichage validé, FALSE sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_binary_strip_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip) +{ + gboolean result; /* Bilan à retourner */ + GtkBinaryStrip *strip; /* Autre version du composant */ + GExeFormat *format; /* Format du binaire */ + GBinPortion *portions; /* Portions binaires à dessiner*/ + GdkRectangle area; /* Surface du composant */ + + if (keyboard) return FALSE; + + strip = GTK_BINARY_STRIP(widget); + + if (strip->binary != NULL) + { + format = g_loaded_binary_get_format(strip->binary); + portions = g_exe_format_get_portions(format); + + area.x = 0; + area.y = 0; + area.width = widget->allocation.width; + area.height = widget->allocation.height; + + result = g_binary_portion_query_tooltip(portions, x, y, &area, tooltip); + + } + else result = FALSE; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : strip = composant GTK à mettre à jour. * +* binary = nouveau contenu binaire à représenter. * +* * +* Description : Attache un nouveau binaire à la barre de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_binary_strip_attach(GtkBinaryStrip *strip, GLoadedBinary *binary) +{ + if (strip->binary != NULL) + g_object_unref(G_OBJECT(strip->binary)); + + strip->binary = binary; + g_object_ref(G_OBJECT(strip->binary)); + + gtk_widget_queue_draw(GTK_WIDGET(strip)); + +} + + +/****************************************************************************** +* * +* Paramètres : strip = composant GTK à mettre à jour. * +* binary = nouveau contenu binaire à représenter. * +* * +* Description : Place le curseur dans la barre de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#if 0 +void gtk_binary_strip_locate_cursor(GtkBinaryStrip *strip, vmpa_t addr, bool emit) +{ + //srip->cursor_pos = pos; + + gtk_widget_queue_draw(GTK_WIDGET(strip)); + +} +#endif diff --git a/src/gtkext/gtkbinarystrip.h b/src/gtkext/gtkbinarystrip.h new file mode 100644 index 0000000..58c31f0 --- /dev/null +++ b/src/gtkext/gtkbinarystrip.h @@ -0,0 +1,62 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinarystrip.h - prototypes pour l'affichage d'un binaire sous forme de bande + * + * Copyright (C) 2013 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 Foobar. If not, see . + */ + + +#ifndef _GTKEXT_BINARYSTRIP_H +#define _GTKEXT_BINARYSTRIP_H + + +#include +#include + + +#include "../analysis/binary.h" + + + +#define GTK_TYPE_BINARY_STRIP (gtk_binary_strip_get_type()) +#define GTK_BINARY_STRIP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BINARY_STRIP, GtkBinaryStrip)) +#define GTK_BINARY_STRIP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BINARY_STRIP, GtkBinaryStripClass)) +#define GTK_IS_BINARY_STRIP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BINARY_STRIP)) +#define GTK_IS_BINARY_STRIP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BINARY_STRIP)) +#define GTK_BINARY_STRIP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BINARY_STRIP, GtkBinaryStripClass)) + + +/* Affichage d'un binaire en bande (instance) */ +typedef struct _GtkBinaryStrip GtkBinaryStrip; + +/* Affichage d'un binaire en bande (classe) */ +typedef struct _GtkBinaryStripClass GtkBinaryStripClass; + + +/* Détermine le type du composant d'affichage générique. */ +GType gtk_binary_strip_get_type(void); + +/* Crée un nouveau composant pour l'affichage d'une bande. */ +GtkWidget *gtk_binary_strip_new(void); + +/* Attache un nouveau binaire à la barre de représentation. */ +void gtk_binary_strip_attach(GtkBinaryStrip *, GLoadedBinary *); + + + +#endif /* _GTKEXT_BINARYSTRIP_H */ diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h index 594b6fd..80fe699 100644 --- a/src/gui/editem-int.h +++ b/src/gui/editem-int.h @@ -42,6 +42,9 @@ typedef void (* update_item_binary_fc) (GEditorItem *, GLoadedBinary *); /* Réagit à un changement d'affichage principal de contenu. */ typedef void (* update_item_view_fc) (GEditorItem *, GtkViewPanel *); +/* Concentre l'attention de l'ensemble sur une adresse donnée. */ +typedef void (* focus_addr_fc) (GEditorItem *, vmpa_t, GtkWidget *); + /* Lance une actualisation relative à l'étendue du projet. */ typedef void (* update_project_fc) (GEditorItem *, GStudyProject *); @@ -61,6 +64,7 @@ struct _GEditorItem update_item_binary_fc update_binary; /* Changement de binaire */ update_item_view_fc update_view; /* Rechargement dû à une vue */ update_item_view_fc update_content; /* Rechargement dû à un contenu*/ + focus_addr_fc focus_addr; /* Prête attention à une addr. */ update_project_fc update_project; /* Actualisation des binaires */ }; diff --git a/src/gui/editem.c b/src/gui/editem.c index d658428..882bd3e 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -273,6 +273,30 @@ void change_editor_items_current_view_content(GtkViewPanel *view) /****************************************************************************** * * +* Paramètres : addr = adresse mémoire à mettre en avant. * +* source = composant à l'origine du changement. * +* * +* Description : Concentre l'attention de l'ensemble sur une adresse donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void focus_address_in_editor_items(vmpa_t addr, GtkWidget *source) +{ + GEditorItem *iter; /* Boucle de parcours */ + + editem_list_for_each(iter, _editem_list) + if (iter->focus_addr != NULL && iter->widget != source) + iter->focus_addr(iter, addr, source); + +} + + +/****************************************************************************** +* * * Paramètres : project = projet concerné par l'évolution. * * * * Description : Lance une actualisation relative à l'étendue du projet. * diff --git a/src/gui/editem.h b/src/gui/editem.h index 5321600..85f9022 100644 --- a/src/gui/editem.h +++ b/src/gui/editem.h @@ -85,6 +85,9 @@ void change_editor_items_current_view(GObject *, GtkViewPanel *); /* Lance une actualisation du fait d'un changement de contenu. */ void change_editor_items_current_view_content(GtkViewPanel *); +/* Concentre l'attention de l'ensemble sur une adresse donnée. */ +void focus_address_in_editor_items(vmpa_t, GtkWidget *); + /* Lance une actualisation relative à l'étendue du projet. */ void update_project_area(GStudyProject *); diff --git a/src/gui/tb/Makefile.am b/src/gui/tb/Makefile.am index 65679cb..5cd46a8 100644 --- a/src/gui/tb/Makefile.am +++ b/src/gui/tb/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libguitb.la libguitb_la_SOURCES = \ + portions.h portions.c \ source.h source.c \ toolbar.h toolbar.c diff --git a/src/gui/tb/portions.c b/src/gui/tb/portions.c new file mode 100644 index 0000000..c53a3ea --- /dev/null +++ b/src/gui/tb/portions.c @@ -0,0 +1,162 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * portions.c - navigation dans les portions de binaire + * + * Copyright (C) 2013 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 "portions.h" + + +#include + + +#include "toolbar.h" +#include "../editem-int.h" +#include "../../format/format.h" +#include "../../gtkext/gtkbinarystrip.h" + + + +/* Construit l'élément GTK pour une barre d'outils. */ +static GtkWidget *build_portions_tb_widget(GObject *); + +/* Fait suivre un changement d'adresse dans la barre. */ +static void track_address_on_binary_strip(GtkBinaryStrip *, vmpa_t, GObject *); + +/* Réagit à un changement du binaire courant. */ +static void update_portions_item_binary(GEditorItem *, GLoadedBinary *); + + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Construit l'élément GTK pour une barre d'outils. * +* * +* Retour : Adresse du composant mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *build_portions_tb_widget(GObject *ref) +{ + GtkWidget *result; /* Composant à retourner */ + GtkWidget *handlebox; /* Support relocalisable */ + GtkWidget *strip; /* Bande pour binaire */ + + result = GTK_WIDGET(gtk_tool_item_new()); + gtk_tool_item_set_expand(GTK_TOOL_ITEM(result), TRUE); + gtk_widget_show(result); + + handlebox = gtk_handle_box_new(); + gtk_widget_show(handlebox); + gtk_container_add(GTK_CONTAINER(result), handlebox); + + strip = gtk_binary_strip_new(); + gtk_widget_show(strip); + gtk_container_add(GTK_CONTAINER(handlebox), strip); + + g_object_set_data(G_OBJECT(result), "strip", strip); + + g_signal_connect(strip, "select-address", + G_CALLBACK(track_address_on_binary_strip), + ref); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : strip = composant d'affichage parcouru. * +* addr = nouvelle adresse du curseur courant. * +* ref = espace de référencement global. * +* * +* Description : Fait suivre un changement d'adresse dans la barre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void track_address_on_binary_strip(GtkBinaryStrip *strip, vmpa_t addr, GObject *ref) +{ + + printf("===> CHANGE TO 0x%08llx\n", addr); + + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Crée une sélection de fichier réactive pour barre d'outils. * +* * +* Retour : Adresse de la structure d'encadrement mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *create_portions_tb_item(GObject *ref) +{ + GEditorItem *result; /* Structure à retourner */ + GtkWidget *widget; /* Composant affiché à l'écran */ + + widget = build_portions_tb_widget(ref); + + result = g_toolbar_item_new(ref, "portions", widget, _("Portions")); + + result->update_binary = update_portions_item_binary; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = élément réactif sollicité. * +* binary = binaire chargé nouvellement affiché. * +* * +* Description : Réagit à un changement du binaire courant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void update_portions_item_binary(GEditorItem *item, GLoadedBinary *binary) +{ + GtkBinaryStrip *strip; /* Bande pour binaire */ + + strip = GTK_BINARY_STRIP(g_object_get_data(G_OBJECT(item->widget), "strip")); + + gtk_binary_strip_attach(strip, binary); + +} diff --git a/src/gui/tb/portions.h b/src/gui/tb/portions.h new file mode 100644 index 0000000..a2a2041 --- /dev/null +++ b/src/gui/tb/portions.h @@ -0,0 +1,38 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * portions.h - prototypes pour la navigation dans les portions de binaire + * + * Copyright (C) 2013 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 + */ + + +#ifndef _GUI_TB_PORTIONS_H +#define _GUI_TB_PORTIONS_H + + +#include "../editem.h" + + + +/* Crée une sélection de fichier réactive pour barre d'outils. */ +GEditorItem *create_portions_tb_item(GObject *ref); + + + +#endif /* _GUI_TB_PORTIONS_H */ diff --git a/src/main.c b/src/main.c index 9efc94d..7dbb055 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ #include "arch/processor.h" #include "format/format.h" #include "glibext/delayed.h" +#include "glibext/gbinportion.h" #include "glibext/gfontcache.h" #include "gtkext/support.h" #include "plugins/pglist.h" @@ -136,6 +137,7 @@ int main(int argc, char **argv) /* Initialisation du programme */ init_all_processors(); init_all_formats(); + init_binary_portion_colors(); init_global_pango_context(); /* Création de l'interface */ @@ -167,6 +169,7 @@ int main(int argc, char **argv) exit_all_plugins(); exit_global_pango_context(); + exit_binary_portion_colors(); unload_configuration(config); -- cgit v0.11.2-87-g4458