From fab9d7cd46922abea7d94f36dcd4630cdf3f4719 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 14 Mar 2016 23:18:27 +0100 Subject: Improved the basic support of Dwarf information. --- ChangeLog | 73 +++++ plugins/readelf/header.c | 2 +- plugins/readelf/program.c | 2 +- plugins/readelf/section.c | 2 +- src/analysis/binary.c | 1 - src/format/debuggable-int.h | 7 + src/format/debuggable.c | 42 +++ src/format/dwarf/Makefile.am | 7 +- src/format/dwarf/abbrev.c | 607 ++++++++++++++++++++++++++++++++++++++++ src/format/dwarf/abbrev.h | 70 +++++ src/format/dwarf/die.c | 303 ++++++++++++++++++++ src/format/dwarf/die.h | 76 +++++ src/format/dwarf/dwarf-int.c | 134 ++++++++- src/format/dwarf/dwarf-int.h | 56 ++-- src/format/dwarf/dwarf.c | 58 ++++ src/format/dwarf/dwarf_def.h | 427 ++++++++++++++++++++++++++++ src/format/dwarf/form.c | 113 ++++++++ src/format/dwarf/form.h | 40 +++ src/format/dwarf/info.c | 165 +++++++++++ src/format/dwarf/info.h | 20 ++ src/format/dwarf/symbols.c | 318 +++++++++++++++++++++ src/format/dwarf/symbols.h | 40 +++ src/format/dwarf/v2/Makefile.am | 3 +- src/format/dwarf/v2/dwarf.c | 8 + src/format/dwarf/v2/form.c | 272 ++++++++++++++++++ src/format/dwarf/v2/form.h | 39 +++ src/format/dwarf/v4/Makefile.am | 3 +- src/format/dwarf/v4/dwarf.c | 16 +- src/format/dwarf/v4/form.c | 106 +++++++ src/format/dwarf/v4/form.h | 39 +++ src/format/elf/elf.c | 46 +-- src/format/elf/elf.h | 3 - src/format/format-int.h | 5 + src/format/format.c | 23 ++ src/format/format.h | 6 +- 35 files changed, 3074 insertions(+), 58 deletions(-) create mode 100644 src/format/dwarf/die.c create mode 100644 src/format/dwarf/die.h create mode 100644 src/format/dwarf/form.c create mode 100644 src/format/dwarf/form.h create mode 100644 src/format/dwarf/symbols.c create mode 100644 src/format/dwarf/symbols.h create mode 100644 src/format/dwarf/v2/form.c create mode 100644 src/format/dwarf/v2/form.h create mode 100644 src/format/dwarf/v4/form.c create mode 100644 src/format/dwarf/v4/form.h diff --git a/ChangeLog b/ChangeLog index d098f3b..01893ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,78 @@ 16-03-14 Cyrille Bagard + * plugins/readelf/header.c: + * plugins/readelf/program.c: + * plugins/readelf/section.c: + Update code. + + * src/analysis/binary.c: + Increase the reference counter when setting the content in formats. + + * src/format/debuggable-int.h: + * src/format/debuggable.c: + Update code. + + * src/format/dwarf/Makefile.am: + Add the 'abbrev.[ch]', 'die.[ch]', 'form.[ch]', 'info.[ch]' and + 'symbols.[ch]' files to libformatdwarf_la_SOURCES. + + * src/format/dwarf/abbrev.c: + * src/format/dwarf/abbrev.h: + Improve the basic support of Dwarf information. + + * src/format/dwarf/die.c: + * src/format/dwarf/die.h: + New entries: improve the basic support of Dwarf information. + + * src/format/dwarf/dwarf-int.c: + * src/format/dwarf/dwarf-int.h: + * src/format/dwarf/dwarf.c: + * src/format/dwarf/dwarf_def.h: + Improve the basic support of Dwarf information. + + * src/format/dwarf/form.c: + * src/format/dwarf/form.h: + New entries: improve the basic support of Dwarf information. + + * src/format/dwarf/info.c: + * src/format/dwarf/info.h: + Improve the basic support of Dwarf information. + + * src/format/dwarf/symbols.c: + * src/format/dwarf/symbols.h: + New entries: improve the basic support of Dwarf information. + + * src/format/dwarf/v2/Makefile.am: + Add the 'form.[ch]' files to libformatdwarfv2_la_SOURCES. + + * src/format/dwarf/v2/dwarf.c: + Improve the basic support of Dwarf information. + + * src/format/dwarf/v2/form.c: + * src/format/dwarf/v2/form.h: + New entries: improve the basic support of Dwarf information. + + * src/format/dwarf/v4/Makefile.am: + Add the 'form.[ch]' files to libformatdwarfv2_la_SOURCES. + + * src/format/dwarf/v4/dwarf.c: + Improve the basic support of Dwarf information. + + * src/format/dwarf/v4/form.c: + * src/format/dwarf/v4/form.h: + New entries: improve the basic support of Dwarf information. + + * src/format/elf/elf.c: + * src/format/elf/elf.h: + Update code. + + * src/format/format-int.h: + * src/format/format.c: + * src/format/format.h: + Increase the reference counter when setting the content in formats. + +16-03-14 Cyrille Bagard + * src/analysis/db/collection.c: Update code and fix some memory leaks. diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c index 6c7e171..1c46bbc 100644 --- a/plugins/readelf/header.c +++ b/plugins/readelf/header.c @@ -58,7 +58,7 @@ bool annotate_elf_header(GElfFormat *format) content = g_binary_format_get_content(G_BIN_FORMAT(format)); header = g_elf_format_get_header(format); - endian = g_elf_format_get_endianness(format); + endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos)) return false; diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c index 0a5ce7f..f380ce4 100644 --- a/plugins/readelf/program.c +++ b/plugins/readelf/program.c @@ -347,7 +347,7 @@ bool annotate_elf_program_header_table(GElfFormat *format) result = true; header = g_elf_format_get_header(format); - endian = g_elf_format_get_endianness(format); + endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); offset = ELF_HDR(format, *header, e_phoff); diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c index 8445fc6..bae4b4c 100644 --- a/plugins/readelf/section.c +++ b/plugins/readelf/section.c @@ -422,7 +422,7 @@ bool annotate_elf_section_header_table(GElfFormat *format) result = true; header = g_elf_format_get_header(format); - endian = g_elf_format_get_endianness(format); + endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); if (!find_elf_section_by_index(format, ELF_HDR(format, *header, e_shstrndx), &strings)) return false; diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 5884350..e617767 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -298,7 +298,6 @@ GLoadedBinary *g_loaded_binary_new(GBinContent *content) log_variadic_message(LMT_PROCESS, _("Opening binary data from '%s'..."), g_binary_content_describe(content, true)); - g_object_ref(G_OBJECT(content)); result->content = content; /* Format d'exécutable */ diff --git a/src/format/debuggable-int.h b/src/format/debuggable-int.h index 855a7bf..1fbe4c3 100644 --- a/src/format/debuggable-int.h +++ b/src/format/debuggable-int.h @@ -29,6 +29,7 @@ #include "format-int.h" +#include "executable.h" @@ -37,6 +38,8 @@ struct _GDbgFormat { GBinFormat parent; /* A laisser en premier */ + GExeFormat *executable; /* Binaire principal attaché */ + }; /* Format de débogage générique (classe) */ @@ -47,5 +50,9 @@ struct _GDbgFormatClass }; +/* Associe officiellement des formats exécutable et de débogage. */ +void g_debuggable_format_attach_executable(GDbgFormat *, GExeFormat *); + + #endif /* _FORMAT_DEBUGGABLE_INT_H */ diff --git a/src/format/debuggable.c b/src/format/debuggable.c index f66ab96..03ee4ed 100644 --- a/src/format/debuggable.c +++ b/src/format/debuggable.c @@ -39,6 +39,9 @@ static void g_debuggable_format_class_init(GDbgFormatClass *); /* Initialise une instance de format d'exécutable générique. */ static void g_debuggable_format_init(GDbgFormat *); +/* Indique le boutisme employé par le format binaire analysé. */ +static SourceEndian g_debuggable_format_get_endianness(const GDbgFormat *); + /* Indique le type défini pour un format de débogage générique. */ @@ -59,6 +62,11 @@ G_DEFINE_TYPE(GDbgFormat, g_debuggable_format, G_TYPE_BIN_FORMAT); static void g_debuggable_format_class_init(GDbgFormatClass *klass) { + GBinFormatClass *fmt; /* Version en format basique */ + + fmt = G_BIN_FORMAT_CLASS(klass); + + fmt->get_endian = (format_get_endian_fc)g_debuggable_format_get_endianness; } @@ -81,8 +89,42 @@ static void g_debuggable_format_init(GDbgFormat *format) } +/****************************************************************************** +* * +* Paramètres : format = description du binaire de débogage à consulter. * +* * +* Description : Indique le boutisme employé par le format binaire analysé. * +* * +* Retour : Boutisme associé au format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static SourceEndian g_debuggable_format_get_endianness(const GDbgFormat *format) +{ + return g_binary_format_get_endianness(G_BIN_FORMAT(format->executable)); + +} +/****************************************************************************** +* * +* Paramètres : format = description du binaire de débogage à compléter. * +* executable = référence vers le binaire exécutable à lier. * +* * +* Description : Associe officiellement des formats exécutable et de débogage.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +void g_debuggable_format_attach_executable(GDbgFormat *format, GExeFormat *executable) +{ + format->executable = executable; + g_object_ref(G_OBJECT(executable)); +} diff --git a/src/format/dwarf/Makefile.am b/src/format/dwarf/Makefile.am index e3889c4..6ebea4e 100644 --- a/src/format/dwarf/Makefile.am +++ b/src/format/dwarf/Makefile.am @@ -2,8 +2,13 @@ noinst_LTLIBRARIES = libformatdwarf.la libformatdwarf_la_SOURCES = \ + abbrev.h abbrev.c \ + die.h die.c \ dwarf.h dwarf.c \ - dwarf-int.h dwarf-int.c + dwarf-int.h dwarf-int.c \ + form.h form.c \ + info.h info.c \ + symbols.h symbols.c # libformatdwarf_la_SOURCES = \ # abbrev.h abbrev.c \ diff --git a/src/format/dwarf/abbrev.c b/src/format/dwarf/abbrev.c index 0428806..039c3a0 100644 --- a/src/format/dwarf/abbrev.c +++ b/src/format/dwarf/abbrev.c @@ -25,6 +25,611 @@ #include + + +#include "dwarf-int.h" + + + + + +/* Description d'un attribut d'une abréviation */ +typedef struct _dw_abbrev_attr +{ + DwarfAttrib name; /* Sujet de l'élément */ + DwarfForm form; /* Représentation */ + +} dw_abbrev_attr; + + +/* Description d'une abréviation */ +struct _dw_abbrev +{ + uleb128_t code; /* Identifiant attribué */ + DwarfTag tag; /* Sujet de l'élément */ + + dw_abbrev_attr *attribs; /* Liste des attributs */ + size_t attribs_count; /* Nombre de ces attributs */ + + struct _dw_abbrev **children; /* Liste des sous-éléments */ + size_t children_count; /* Nombre de ces enfants */ + +}; + + + + + +/* Procède à la conversion de base d'une abréviation DWARF. */ +static bool check_abbreviation_decl(const GDwarfFormat *, const dw_abbrev_decl *, dw_abbrev *); + +/* Procède à la conversion d'un attribut d'abréviation DWARF. */ +static bool check_abbreviation_attrib(const GDwarfFormat *, const dw_abbrev_raw_attr *, dw_abbrev_attr *); + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à constituer. * +* * +* Description : Charge toutes les abbréviations présentes dans un DWARF. * +* * +* Retour : Bilan de l'opération, potentiellement un succès sans sortie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_all_dwarf_abbreviations(GDwarfFormat *format) +{ + bool result; /* Bilan à faire remonter */ + mrange_t range; /* Couverture d'une section */ + vmpa2t *pos; /* Position de tête de lecture */ + + result = g_exe_format_get_section_range_by_name(G_DBG_FORMAT(format)->executable, ".debug_abbrev", &range); + + pos = get_mrange_addr(&range); + + printf("start :: 0x%08x\n", (unsigned int)pos->physical); + + result &= load_dwarf_abbreviation(format, pos, &format->abbreviations); + + printf("abbrevs :: %p\n", format->abbreviations); + + if (format->abbreviations != NULL) + printf(" -> children : %zu\n", format->abbreviations->children_count); + else + printf(" -> (nothing)\n"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* pos = tête de lecture à faire évoluer. * +* abbrev = abréviation lue et complète, NULL si aucune. [OUT] * +* * +* Description : Charge une abréviation valide pour un DWARF en mémoire. * +* * +* Retour : Bilan de l'opération, potentiellement un succès sans sortie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_dwarf_abbreviation(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev **abbrev) +{ + dw_abbrev_decl decl; /* En-tête d'abréviation */ + bool status; /* Bilan d'une lecture */ + dw_abbrev_raw_attr attr; /* Attribut de l'abréviation */ + dw_abbrev *child; /* Rejeton à intégrer */ + + *abbrev = NULL; + + /** + * Cette routine est la transcription du paragraphe 7.5.3 ("Abbreviations Tables"), + * de la quatrième version de la définition du format DWARF. + * + * La spécification précise : + * + * As mentioned in Section 2.3, each chain of sibling entries is terminated by a null entry. + * + * Cependant, ce formalisme n'est pas constaté dans la pratique. D'ailleurs, readelf + * comporte le commentaire suivant dans le fichier 'dwarf_reader.cc' : + * + * Read the abbrev code. A zero here indicates the end of the abbrev table. + * + */ + + if (!read_dwarf_abbrev_decl(format, pos, &decl)) + goto lda_bad_exit; + + if (decl.code == 0) + goto lda_exit; + + *abbrev = (dw_abbrev *)calloc(1, sizeof(dw_abbrev)); + + if (!check_abbreviation_decl(format, &decl, *abbrev)) + goto lda_bad_exit; + + /* Chargement des attributs */ + + for (;;) + { + status = read_dwarf_abbrev_attr(format, pos, &attr); + if (!status) goto lda_bad_exit; + + printf(" -- [0x%llx] [0x%llx] name = %u\tform = %u\n", + (unsigned long long)pos->physical, + (unsigned long long)decl.code, + (unsigned int)attr.name, (unsigned int)attr.form); + + if (attr.name == DW_ATTR_invalid && attr.form == DW_FORM_invalid) + break; + + (*abbrev)->attribs_count++; + (*abbrev)->attribs = (dw_abbrev_attr *)realloc((*abbrev)->attribs, + (*abbrev)->attribs_count * sizeof(dw_abbrev_attr)); + + status = check_abbreviation_attrib(format, &attr, + &(*abbrev)->attribs[(*abbrev)->attribs_count - 1]); + if (!status) goto lda_bad_exit; + + } + + /* Chargement des enfants */ + + printf(" || children ? %d vs %d\n", (int)decl.has_children, (int)DW_CHILDREN_yes); + + if (decl.has_children == DW_CHILDREN_yes) + for (;;) + { + status = load_dwarf_abbreviation(format, pos, &child); + if (!status) goto lda_bad_exit; + + if (child == NULL) + break; + + (*abbrev)->children_count++; + (*abbrev)->children = (dw_abbrev **)realloc((*abbrev)->children, + (*abbrev)->children_count * sizeof(dw_abbrev)); + + (*abbrev)->children[(*abbrev)->children_count - 1] = child; + + } + + lda_exit: + + return true; + + lda_bad_exit: + + free_dwarf_abbreviation(*abbrev); + + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation chargée en mémoire à traiter. * +* * +* Description : Supprime de la mémoire toute trace d'une abréviation DWARF. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void free_dwarf_abbreviation(dw_abbrev *abbrev) +{ + size_t i; /* Boucle de parcours */ + + if (abbrev->attribs != NULL) + free(abbrev->attribs); + + if (abbrev->children != NULL) + { + for (i = 0; i < abbrev->children_count; i++) + free_dwarf_abbreviation(abbrev->children[i]); + + free(abbrev->attribs); + + } + + free(abbrev); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* decl = structure brute dont le contenu est à valider. * +* abbrev = abréviation à constituer à partir du brut. [OUT] * +* * +* Description : Procède à la conversion de base d'une abréviation DWARF. * +* * +* Retour : Validité confirmée ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool check_abbreviation_decl(const GDwarfFormat *format, const dw_abbrev_decl *decl, dw_abbrev *abbrev) +{ + bool result; /* Validité à retourner */ + + result = (decl->has_children == DW_CHILDREN_no + || decl->has_children == DW_CHILDREN_yes); + + + /* TODO : vérifier les bornes de 'tag' */ + + + if (result) + { + abbrev->code = decl->code; + abbrev->tag = decl->tag; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* decl = structure brute dont le contenu est à valider. * +* abbrev = abréviation à constituer à partir du brut. [OUT] * +* * +* Description : Procède à la conversion d'un attribut d'abréviation DWARF. * +* * +* Retour : Validité confirmée ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool check_abbreviation_attrib(const GDwarfFormat *format, const dw_abbrev_raw_attr *attr, dw_abbrev_attr *attrib) +{ + bool result; /* Validité à retourner */ + + result = true; + + + /* TODO : vérifier les bornes de 'name' et 'form' */ + + + if (result) + { + attrib->name = attr->name; + attrib->form = attr->form; + + + + } + + return result; + +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * +* * +* Description : Fournit l'étiquette associée à l'ensemble des attributs. * +* * +* Retour : Etiquette officielle de l'ensemble représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DwarfTag dwarf_abbreviation_get_tag(const dw_abbrev *abbrev) +{ + return abbrev->tag; + +} + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * +* * +* Description : Compte le nombre d'attributs présents dans une abréviation. * +* * +* Retour : Quantité d'attributs pris en compte dans l'abréviation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t dwarf_abbreviation_count_attribs(const dw_abbrev *abbrev) +{ + return abbrev->attribs_count; + +} + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * +* attrib = désignation de l'attribut à retrouver. * +* index = indice de cet attribut dans l'ensemble. [OUT] * +* * +* Description : Recherche un attribut dans une abréviation. * +* * +* Retour : Indication sur le bilan des recherches. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dwarf_abbreviation_get_attrib_index(const dw_abbrev *abbrev, DwarfAttrib attrib, size_t *index) +{ + bool result; /* Etat de validité à renvoyer */ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < abbrev->attribs_count; i++) + if (abbrev->attribs[i].name == attrib) + break; + + if (i < abbrev->attribs_count) + { + result = true; + *index = i; + } + else + result = false; + + return result; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * +* attrib = désignation de l'attribut à retrouver. * +* index = indice de cet attribut dans l'ensemble. * +* form = type de valeur attendu pour un attribut donné. [OUT]* +* * +* Description : Détermine le type d'un attribut dans une abréviation. * +* * +* Retour : Indication sur le bilan des accès. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dwarf_abbreviation_get_form_for_index(const dw_abbrev *abbrev, size_t index, DwarfForm *form) +{ + if (index >= abbrev->attribs_count) + return false; + + *form = abbrev->attribs[index].form; + + return true; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : abbrev = abréviation chargée en mémoire à consulter. * +* * +* Description : Indique si une abbréviation comporte des sous-définitions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dwarf_abbreviation_has_children(const dw_abbrev *abbrev) +{ + return (abbrev->children_count > 0); + +} + + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage à consulter. * +* code = identifiant de l'abbréviation recherchée. * +* * +* Description : Recherche une abréviation DWARF donnée. * +* * +* Retour : Adresse d'une abréviation ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_abbrev *find_dwarf_abbreviations(const GDwarfFormat *format, uleb128_t code) +{ + const dw_abbrev *result; /* Trouvaille à retourner */ + + if (format->abbreviations->code == code) + result = format->abbreviations; + + else + { + const dw_abbrev *_find_dwarf_abbreviations(const dw_abbrev *abbrev, uleb128_t c) + { + const dw_abbrev *found; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + + if (abbrev->code == c) + found = abbrev; + else + { + found = NULL; + + for (i = 0; i < abbrev->children_count && found == NULL; i++) + found = _find_dwarf_abbreviations(abbrev->children[i], c); + + } + + return found; + + } + + result = _find_dwarf_abbreviations(format->abbreviations, code); + + } + + return result; + +} + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = contenu binaire de débogage à parcourir. * +* cu = unité de compilation parente. * +* form = nature de la valeur à lire. * +* pos = tête de lecture au sein des données. [OUT] * +* value = valeur au format donné lue. [OUT] * +* * +* Description : Lit la valeur correspondant à un type donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +dw_value *translate_abbreviation_attributes(const GDwarfFormat *format, const dw_abbrev *abbrev, const dw_compil_unit_header *cu, vmpa2t *pos) +{ + dw_value *result; /* Valeurs lues retournées */ + size_t i; /* Boucle de parcours */ + bool status; /* Bilan d'une lecture */ + + result = (dw_value *)calloc(abbrev->attribs_count, sizeof(dw_value)); + + for (i = 0; i < abbrev->attribs_count; i++) + { + result[i].attrib = abbrev->attribs[i].name; + + printf("-- loading attrib %x (%u) -- form = %x (%u) -- pos = %llx --\n", + (unsigned int)abbrev->attribs[i].name, + (unsigned int)abbrev->attribs[i].name, + (unsigned int)abbrev->attribs[i].form, + (unsigned int)abbrev->attribs[i].form, + (unsigned long long)(pos->physical - 0x1039)); + + status = G_DWARF_FORMAT_GET_CLASS(format)->read_form(format, cu, + abbrev->attribs[i].form, pos, &result[i].value); + if (!status) printf("[%zu] failed for %x\n", i, abbrev->attribs[i].form); + if (status) printf("[%zu] success for %x\n", i, abbrev->attribs[i].form); + printf(" current pos :: %llx\n", (unsigned long long)(pos->physical - 0x1039)); + if (!status) break; + + } + + if (i != abbrev->attribs_count) + { + free(result); + result = NULL; + } + + return result; + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#if 0 + +#include #include #include @@ -781,3 +1386,5 @@ bool skip_dwarf_abbrev(dwarf_format *format, off_t *pos, const dw_abbrev *abbrev return result; } + +#endif diff --git a/src/format/dwarf/abbrev.h b/src/format/dwarf/abbrev.h index 469d572..bc7efe6 100644 --- a/src/format/dwarf/abbrev.h +++ b/src/format/dwarf/abbrev.h @@ -28,6 +28,73 @@ #include +#include "dwarf.h" +#include "dwarf_def.h" + + + + +/* Description d'une abréviation */ +typedef struct _dw_abbrev dw_abbrev; + + + + + + + +/* Charge toutes les abbréviations présentes dans un DWARF. */ +bool load_all_dwarf_abbreviations(GDwarfFormat *); + +/* Charge une abréviation valide pour un DWARF en mémoire. */ +bool load_dwarf_abbreviation(const GDwarfFormat *, vmpa2t *, dw_abbrev **); + +/* Supprime de la mémoire toute trace d'une abréviation DWARF. */ +void free_dwarf_abbreviation(dw_abbrev *); + +/* Fournit l'étiquette associée à l'ensemble des attributs. */ +DwarfTag dwarf_abbreviation_get_tag(const dw_abbrev *); + +/* Compte le nombre d'attributs présents dans une abréviation. */ +size_t dwarf_abbreviation_count_attribs(const dw_abbrev *); + +/* Recherche un attribut dans une abréviation. */ +bool dwarf_abbreviation_get_attrib_index(const dw_abbrev *, DwarfAttrib, size_t *); + + +/* Détermine le type d'un attribut dans une abréviation. */ +bool dwarf_abbreviation_get_form_for_index(const dw_abbrev *, size_t, DwarfForm *); + + +/* Indique si une abbréviation comporte des sous-définitions. */ +bool dwarf_abbreviation_has_children(const dw_abbrev *); + + + +/* Recherche une abréviation DWARF donnée. */ +const dw_abbrev *find_dwarf_abbreviations(const GDwarfFormat *, uleb128_t); + +/* Lit la valeur correspondant à un type donné. */ +dw_value *translate_abbreviation_attributes(const GDwarfFormat *, const dw_abbrev *, const dw_compil_unit_header *, vmpa2t *); + + + + + + + + + + + + + +#if 0 + + +#include + + #include "d_dwarf.h" #include "dwarf-int.h" @@ -52,5 +119,8 @@ bool read_dwarf_abbrev_attribute(dwarf_format *, off_t *, bool, const dw_abbrev bool skip_dwarf_abbrev(dwarf_format *, off_t *, const dw_abbrev *); +#endif + + #endif /* _FORMAT_DWARF_ABBREV_H */ diff --git a/src/format/dwarf/die.c b/src/format/dwarf/die.c new file mode 100644 index 0000000..8c25a1d --- /dev/null +++ b/src/format/dwarf/die.c @@ -0,0 +1,303 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * die.c - gestion des entrées renvoyant à des informations de débogage + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "die.h" + + +#include +#include + + +#include "dwarf-int.h" + + + +/** + * § 2.1 The Debugging Information Entry (DIE). + */ + +typedef struct _dw_die +{ + unsigned int level; /* Niveau hiérarchique */ + phys_t offset; /* Position dans le flux */ + + const dw_abbrev *abbrev; /* Lien vers la représentation */ + + dw_value *values; /* Liste des valeurs associées */ + + bool has_children; /* Feuille ou noeud de l'arbre */ + struct _dw_die **children; /* Liste d'éventuels enfants */ + size_t children_count; /* Taille de cette liste */ + +} dw_die; + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* endian = boutisme reconnu dans le format. * +* header = en-tête de description de l'unité à traiter. * +* die = emplacement de stockage de l'entrée ou NULL. [OUT] * +* * +* Description : Procède à la lecture de l'en-tête d'une unité de compilation.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : Le format autorise à ne rien produire ici légitimement. * +* * +******************************************************************************/ + +bool build_dwarf_die(GDwarfFormat *format, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die **die) +{ + uleb128_t code; /* Code de la description liée */ + bool status; /* Bilan de la lecture */ + const dw_abbrev *abbrev; /* Lien vers la représentation */ + dw_value *values; /* Liste des valeurs associées */ + + *die = NULL; + + /** + * § 7.5.2 Debugging Information Entry. + */ + + status = g_binary_content_read_uleb128(G_BIN_FORMAT(format)->content, pos, &code); + if (!status) return false; + + printf("[ok] code = 0x%llx\n", (unsigned long long)code); + + if (code == 0) return true; + + abbrev = find_dwarf_abbreviations(format, code); + + printf("[ok] abbrev = %p\n", abbrev); + + printf("----------------------\n"); + + + values = translate_abbreviation_attributes(format, abbrev, header, pos); + if (values == NULL) return false; + + printf("[ok] values = %p\n", values); + + + + *die = (dw_die *)calloc(1, sizeof(dw_die)); + + (*die)->abbrev = abbrev; + + (*die)->values = values; + + (*die)->has_children = dwarf_abbreviation_has_children(abbrev); + + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à libérer de la mémoire. * +* * +* Description : Supprime les éléments mis en place pour une entrée d'info. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_dwarf_die(dw_die *die) +{ + size_t i; /* Boucle de parcours */ + + if (die->values != NULL) + free(die->values); + + for (i = 0; i < die->children_count; i++) + delete_dwarf_die(die->children[i]); + + if (die->children != NULL) + free(die->children); + + free(die); + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* * +* Description : Fournit un lien vers l'abréviation de représentation. * +* * +* Retour : Structure de représentation en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_abbrev *dw_die_get_abbrev(const dw_die *die) +{ + return die->abbrev; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* index = indice de cet attribut dans l'ensemble. * +* * +* Description : Fournit un lien vers l'abréviation de représentation. * +* * +* Retour : Valeur recherchée ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_form_value *dw_die_peek_value(const dw_die *die, size_t index) +{ + dw_form_value *result; /* Valeur ciblée à retourner */ + + if (index >= dwarf_abbreviation_count_attribs(die->abbrev)) + return NULL; + + result = &die->values[index].value; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée d'information à consulter. * +* attrib = désignation de l'attribut à retrouver. * +* form = type de valeur attendu pour un attribut donné. [OUT]* +* * +* Description : Fournit un lien vers l'abréviation de représentation. * +* * +* Retour : Valeur recherchée ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const dw_form_value *dw_die_peek_extended_value(const dw_die *die, DwarfAttrib attrib, DwarfForm *form) +{ + const dw_form_value *result; /* Valeur ciblée à retourner */ + size_t index; /* Indice d'élément à relire */ + bool status; /* Bilan d'une récupération */ + + status = dwarf_abbreviation_get_attrib_index(die->abbrev, attrib, &index); + if (!status) return NULL; + + status = dwarf_abbreviation_get_form_for_index(die->abbrev, index, form); + if (!status) return NULL; + + result = dw_die_peek_value(die, index); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* * +* Description : Indique si une entrée de débogage possède des enfants. * +* * +* Retour : true ou false selon la situation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dw_die_has_children(const dw_die *die) +{ + return die->has_children; + +} + + +/****************************************************************************** +* * +* Paramètres : die = entrée à consulter. * +* * +* Description : Indique si une entrée de débogage possède des enfants. * +* * +* Retour : true ou false selon la situation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void dw_die_append_child(dw_die *die, dw_die *child) +{ + assert(die->has_children); + + die->children = (dw_die **)realloc(die->children, ++die->children_count * sizeof(dw_die *)); + + die->children[die->children_count - 1] = child; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT PAR ENSEMBLES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : root = entrée première à consulter. * +* visitor = intervention régulière à respecter. * +* data = données quelconques à associer aux visites. * +* * +* Description : Entame une grande tournée de toutes les entrées présentes. * +* * +* Retour : true si l'opération s'est déroulée complètement, false sinon.* +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dw_die_visit(dw_die *root, visit_dies_fc visitor, void *data) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + result = visitor(root, data); + + for (i = 0; i < root->children_count && result; i++) + result = dw_die_visit(root->children[i], visitor, data); + + return result; + +} diff --git a/src/format/dwarf/die.h b/src/format/dwarf/die.h new file mode 100644 index 0000000..79634cb --- /dev/null +++ b/src/format/dwarf/die.h @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * die.h - prototypes pour la gestion des entrées renvoyant à des informations de débogage + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _FORMAT_DWARF_DIE_H +#define _FORMAT_DWARF_DIE_H + + +#include + + +#include "abbrev.h" +#include "dwarf.h" +#include "dwarf_def.h" + + + +/* § 2.1 The Debugging Information Entry (DIE). */ +typedef struct _dw_die dw_die; + + +/* Procède à la lecture de l'en-tête d'une unité de compilation. */ +bool build_dwarf_die(GDwarfFormat *, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die **); + +/* Supprime les éléments mis en place pour une entrée d'info. */ +void delete_dwarf_die(dw_die *); + +/* Fournit un lien vers l'abréviation de représentation. */ +const dw_abbrev *dw_die_get_abbrev(const dw_die *); + +/* Fournit un lien vers l'abréviation de représentation. */ +const dw_form_value *dw_die_peek_value(const dw_die *, size_t); + +/* Fournit un lien vers l'abréviation de représentation. */ +const dw_form_value *dw_die_peek_extended_value(const dw_die *, DwarfAttrib, DwarfForm *); + +/* Indique si une entrée de débogage possède des enfants. */ +bool dw_die_has_children(const dw_die *); + +/* Indique si une entrée de débogage possède des enfants. */ +void dw_die_append_child(dw_die *, dw_die *); + + + +/* ---------------------------- TRAITEMENT PAR ENSEMBLES ---------------------------- */ + + +/* Procédure appelée pour chaque élément recontré pendant une visite. */ +typedef bool (* visit_dies_fc) (const dw_die *, void *); + + +/* Entame une grande tournée de toutes les entrées présentes. */ +bool dw_die_visit(dw_die *, visit_dies_fc, void *); + + + +#endif /* _FORMAT_DWARF_DIE_H */ diff --git a/src/format/dwarf/dwarf-int.c b/src/format/dwarf/dwarf-int.c index 310f926..5c18aaf 100644 --- a/src/format/dwarf/dwarf-int.c +++ b/src/format/dwarf/dwarf-int.c @@ -29,10 +29,73 @@ * * * Paramètres : format = informations chargées à consulter. * * pos = position de début de lecture. [OUT] * +* attr = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'un attribut d'abréviation DWARF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_abbrev_attr(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev_raw_attr *attr) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + + content = G_BIN_FORMAT(format)->content; + + result = g_binary_content_read_uleb128(content, pos, &attr->name); + result &= g_binary_content_read_uleb128(content, pos, &attr->form); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* decl = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une déclaration d'abréviation DWARF. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_abbrev_decl(const GDwarfFormat *format, vmpa2t *pos, dw_abbrev_decl *decl) +{ + bool result; /* Bilan à retourner */ + const GBinContent *content; /* Contenu binaire à lire */ + + content = G_BIN_FORMAT(format)->content; + + result = g_binary_content_read_uleb128(content, pos, &decl->code); + result &= g_binary_content_read_uleb128(content, pos, &decl->tag); + result &= g_binary_content_read_u8(content, pos, &decl->has_children); + + return result; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * * endian = boutisme reconnu dans le format. * * header = en-tête à déterminer. [OUT] * * * -* Description : Procède à la lecture de l'en-tête d'un contenu binaire ELF. * +* Description : Procède à la lecture de l'en-tête d'un contenu binaire DWARF.* * * * Retour : Bilan de l'opération. * * * @@ -73,3 +136,72 @@ bool read_dwarf_section_header(GBinContent *content, vmpa2t *pos, SourceEndian e return result; } + + + + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* endian = boutisme reconnu dans le format. * +* header = en-tête à déterminer. [OUT] * +* * +* Description : Procède à la lecture de l'en-tête d'une unité de compilation.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_compil_unit_header(GBinContent *content, vmpa2t *pos, SourceEndian endian, dw_compil_unit_header *header) +{ + bool result; /* Bilan à retourner */ + uint32_t val32; /* Premier paquet d'octets */ + bool status; /* Bilan d'opération */ + + result = read_dwarf_section_header(content, pos, endian, (dw_section_header *)header); + if (!result) goto rdcuh_exit; + + if (header->is_32b) + { + status = g_binary_content_read_u32(content, pos, endian, &val32); + if (!status) goto rdcuh_exit; + + header->debug_abbrev_offset = val32; + + } + else + { + status = g_binary_content_read_u64(content, pos, endian, &header->debug_abbrev_offset); + if (!status) goto rdcuh_exit; + + } + + result &= g_binary_content_read_u8(content, pos, &header->address_size); + + rdcuh_exit: + + return result; + +} + + + + + + + diff --git a/src/format/dwarf/dwarf-int.h b/src/format/dwarf/dwarf-int.h index d3bf14a..c91609e 100644 --- a/src/format/dwarf/dwarf-int.h +++ b/src/format/dwarf/dwarf-int.h @@ -35,12 +35,21 @@ #include "../debuggable-int.h" +#include "abbrev.h" +#include "die.h" #include "dwarf_def.h" +/* Procède à la lecture d'un attribut d'abréviation DWARF. */ +bool read_dwarf_abbrev_attr(const GDwarfFormat *, vmpa2t *, dw_abbrev_raw_attr *); + +/* Procède à la lecture d'une déclaration d'abréviation DWARF. */ +bool read_dwarf_abbrev_decl(const GDwarfFormat *, vmpa2t *, dw_abbrev_decl *); + + /* En-tête présente dans certaines sections */ @@ -65,19 +74,38 @@ bool read_dwarf_section_header(GBinContent *, vmpa2t *, SourceEndian, dw_section +/* Procède à la lecture de l'en-tête d'une unité de compilation. */ +bool read_dwarf_compil_unit_header(GBinContent *, vmpa2t *, SourceEndian, dw_compil_unit_header *); + + + +///--------------------- + +//------------------------------- +/* Lit la valeur correspondant à un type donné. */ +typedef bool (* read_form_value_fc) (const GDwarfFormat *, const dw_compil_unit_header *, DwarfForm, vmpa2t *, dw_form_value *); + + /* Format de débogage DWARF (instance) */ struct _GDwarfFormat { GDbgFormat parent; /* A laisser en premier */ + dw_abbrev *abbreviations; /* Racine des abbréviations */ + + + dw_die *info_die; + + + }; /* Format de débogage DWARF (classe) */ @@ -85,13 +113,16 @@ struct _GDwarfFormatClass { GDbgFormatClass parent; /* A laisser en premier */ -}; + read_form_value_fc read_form; /* lecture de valeurs formatées*/ +}; +/* Charge de façon générique toutes les informations DWARF. */ +bool g_dwarf_format_load(GDwarfFormat *, GExeFormat *); @@ -119,29 +150,6 @@ typedef enum _DwarfFormat -/* Description d'un attribut d'une abréviation */ -typedef struct _dw_abbrev_attr -{ - DwarfAttrib attrib; /* Sujet de l'élément */ - DwarfForm form; /* Représentation */ - -} dw_abbrev_attr; - - -/* Description d'une abréviation */ -typedef struct _dw_abbrev -{ - off_t offset; /* Position dans le corps */ - DwarfTag tag; /* Sujet de l'élément */ - - dw_abbrev_attr *attribs; /* Liste des attributs */ - size_t attribs_count; /* Nombre de ces attributs */ - - struct _dw_abbrev **children; /* Liste des sous-éléments */ - size_t children_count; /* Nombre de ces enfants */ - -} dw_abbrev; - /* Eléments récupérés sur une fonction */ typedef struct _dw_dbg_function diff --git a/src/format/dwarf/dwarf.c b/src/format/dwarf/dwarf.c index 519aa49..3fe5e88 100644 --- a/src/format/dwarf/dwarf.c +++ b/src/format/dwarf/dwarf.c @@ -24,7 +24,10 @@ #include "dwarf.h" +#include "abbrev.h" #include "dwarf-int.h" +#include "info.h" +#include "symbols.h" #include "../../common/cpp.h" @@ -120,6 +123,9 @@ FormatMatchStatus dwarf_is_matching(GBinContent *content, GExeFormat *parent, vo if (parent == NULL) return FMS_UNKNOWN; + return FMS_UNKNOWN; + *key = strdup("dwarf_v4"); + return FMS_MATCHED; /* Lecture des indices présents */ @@ -145,6 +151,9 @@ FormatMatchStatus dwarf_is_matching(GBinContent *content, GExeFormat *parent, vo equal = true; for (k = 0; k < count && equal; k++) + printf(" -> %hhu vs %hhu\n", ref[k], cur[k]); + + for (k = 0; k < count && equal; k++) equal = (cur[k] == 0) || (ref[k] == cur[k]); return equal; @@ -158,6 +167,8 @@ FormatMatchStatus dwarf_is_matching(GBinContent *content, GExeFormat *parent, vo * du fait de l'absence de section, donc il n'y aura pas d'incompatibilité. */ + printf("---dwarf v4\n"); + found = check_dwarf_version(dwarf_v4_versions, current_versions, ARRAY_SIZE(section_names)); if (found) @@ -168,6 +179,8 @@ FormatMatchStatus dwarf_is_matching(GBinContent *content, GExeFormat *parent, vo if (result == FMS_UNKNOWN) { + printf("---dwarf v3\n"); + found = check_dwarf_version(dwarf_v3_versions, current_versions, ARRAY_SIZE(section_names)); if (found) @@ -180,6 +193,8 @@ FormatMatchStatus dwarf_is_matching(GBinContent *content, GExeFormat *parent, vo if (result == FMS_UNKNOWN) { + printf("---dwarf v2\n"); + found = check_dwarf_version(dwarf_v2_versions, current_versions, ARRAY_SIZE(section_names)); if (found) @@ -277,3 +292,46 @@ static void g_dwarf_format_finalize(GDwarfFormat *format) G_OBJECT_CLASS(g_dwarf_format_parent_class)->finalize(G_OBJECT(format)); } + + +/****************************************************************************** +* * +* Paramètres : format = description du binaire de débogage à compléter. * +* executable = référence vers le binaire exécutable à lier. * +* * +* Description : Charge de façon générique toutes les informations DWARF. * +* * +* Retour : Bilan du chargement : réussi ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dwarf_format_load(GDwarfFormat *format, GExeFormat *executable) +{ + bool result; /* Bilan à faire remonter */ + + result = true; + + g_debuggable_format_attach_executable(G_DBG_FORMAT(format), executable); + + printf("Loading abbrev...\n"); + + result &= load_all_dwarf_abbreviations(format); + + printf("Loading debug info...\n"); + + result &= load_dwarf_debug_information(format); + + printf("Done!\n"); + + result &= load_dwarf_symbols(format); + + printf("Got symbols...\n"); + + exit(0); + + return result; + +} + diff --git a/src/format/dwarf/dwarf_def.h b/src/format/dwarf/dwarf_def.h index 35fcdc0..7067472 100644 --- a/src/format/dwarf/dwarf_def.h +++ b/src/format/dwarf/dwarf_def.h @@ -26,6 +26,430 @@ +#include + + +#include "../../arch/vmpa.h" +#include "../../common/leb128.h" + + + + +/** + * § 7.5.1.1 Compilation Unit Header. + */ + +/* En-tête présente dans certaines sections */ +typedef struct _dw_compil_unit_header +{ + uint64_t unit_length; /* Taille totale sans le champ */ + bool is_32b; /* Le format est-il sur 32b ? */ + + uint16_t version; /* Version de la section */ + + uint64_t debug_abbrev_offset; /* Emplacement dans la section */ + uint8_t address_size; /* Taille des adresses */ + +} dw_compil_unit_header; + + +/** + * § 7.5.4 Attribute Encodings + */ + +/* Figure 18, Tag encodings, begins here. */ + +typedef enum _DwarfTag +{ + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + DW_TAG_imported_declaration = 0x08, + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + DW_TAG_member = 0x0d, + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_parameter = 0x2f, + DW_TAG_template_value_parameter = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + + DW_TAG_dwarf_procedure = 0x36, + DW_TAG_restrict_type = 0x37, + DW_TAG_interface_type = 0x38, + DW_TAG_namespace = 0x39, + DW_TAG_imported_module = 0x3a, + DW_TAG_unspecified_type = 0x3b, + DW_TAG_partial_unit = 0x3c, + DW_TAG_imported_unit = 0x3d, + DW_TAG_condition = 0x3f, + DW_TAG_shared_type = 0x40, + + /* Nouveautés v.4 */ + + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, + + DW_TAG_lo_user = 0x4080, + DW_TAG_hi_user = 0xffff + +} DwarfTag; + +/* Figure 19. Child determination encodings. */ + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +/* Figure 21. Attribute form encodings. */ + +typedef enum _DwarfForm +{ + DW_FORM_invalid = 0x00, + + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16, + + /* Nouveautés v4 */ + + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_ref_sig8 = 0x20 + +} DwarfForm; + + + + + + +/* Résumé des différentes valeurs dans DWARF v2 */ +typedef union _dw_v2_form_value +{ + /* DW_FORM_addr */ + virt_t address; + + /* DW_FORM_data[1248] */ + uint8_t data1; + uint16_t data2; + uint32_t data4; + uint64_t data8; + + /* DW_FORM_sdata */ + leb128_t sdata; + + /* DW_FORM_udata */ + uleb128_t udata; + + /* DW_FORM_block[124]? */ + struct + { + const bin_t *start; + phys_t size; + + } block; + + /* DW_FORM_string */ + /* DW_FORM_strp */ + const char *string; + + /* DW_FORM_flag */ + uint8_t flag; + + /* DW_FORM_ref[1248] */ + uint8_t ref1; + uint16_t ref2; + uint32_t ref4; + uint64_t ref8; + + /* DW_FORM_ref_udata */ + uleb128_t ref_udata; + +} dw_v2_form_value; + + +/* Résumé des différentes valeurs dans DWARF v4 */ +typedef union _dw_v4_form_value +{ + dw_v2_form_value v2; + + /* DW_FORM_sec_offset */ + uint64_t sec_offset; + + /* DW_FORM_exprloc */ + struct + { + const bin_t *start; + phys_t size; + + } expr; + + /* DW_FORM_flag_present */ + bool has_flag; + + /* DW_FORM_ref_sig8 */ + uint64_t signature; + +} dw_v4_form_value; + + +/* Résumé des différentes valeurs dans DWARF */ +typedef union _dw_form_value +{ + dw_v2_form_value v2; + dw_v2_form_value v4; + +} dw_form_value; + + + + + + + + + + + + + + + + + + + +/** + * § 7.5.3 Abbreviations Tables. + */ + +/* Description d'un attribut d'une abréviation */ +typedef struct _dw_abbrev_raw_attr +{ + uleb128_t name; /* Désignation de l'attribut */ + uleb128_t form; /* Nature de sa valeur */ + +} dw_abbrev_raw_attr; + +/* En-tête de déclaration d'une abréviation */ +typedef struct _dw_abbrev_decl +{ + uleb128_t code; /* Identifiant attribué */ + uleb128_t tag; /* Identifiant attribué */ + + uint8_t has_children; /* Présence de sous-entrées ? */ + +} dw_abbrev_decl; + + + + + + + + + + +/* Liste des attributs rencontrés */ +typedef enum _DwarfAttrib +{ + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, + DW_AT_bit_size = 0x0d, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_bit_stride = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, + DW_AT_namelist_item = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + DW_AT_allocated = 0x4e, + DW_AT_associated = 0x4f, + DW_AT_data_location = 0x50, + DW_AT_byte_stride = 0x51, + DW_AT_entry_pc = 0x52, + DW_AT_use_UTF8 = 0x53, + DW_AT_extension = 0x54, + DW_AT_ranges = 0x55, + DW_AT_trampoline = 0x56, + DW_AT_call_column = 0x57, + DW_AT_call_file = 0x58, + DW_AT_call_line = 0x59, + DW_AT_description = 0x5a, + DW_AT_binary_scale = 0x5b, + DW_AT_decimal_scale = 0x5c, + DW_AT_small = 0x5d, + DW_AT_decimal_sign = 0x5e, + DW_AT_digit_count = 0x5f, + DW_AT_picture_string = 0x60, + DW_AT_mutable = 0x61, + DW_AT_threads_scaled = 0x62, + DW_AT_explicit = 0x63, + DW_AT_object_pointer = 0x64, + DW_AT_endianity = 0x65, + DW_AT_elemental = 0x66, + DW_AT_pure = 0x67, + DW_AT_recursive = 0x68, + + /* Nouveautés v4 */ + + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + + DW_AT_lo_user = 0x2000, + DW_AT_hi_user = 0x3fff, + +} DwarfAttrib; + + +#define DW_ATTR_invalid 0 /* FIXME */ + + +typedef struct _dw_value +{ + DwarfAttrib attrib; /* Sujet de l'élément */ + dw_form_value value; /* Valeur instanciée associée */ + +} dw_value; + + + + + + + + + + + + + + + +#if 0 + + + + + + + + + + + + + + + /* Liste des balises rencontrées */ typedef enum _DwarfTag { @@ -399,5 +823,8 @@ typedef enum _DwarfForm } DwarfForm; +#endif + + #endif /* _FORMAT_DWARF_DWARF_DEF_H */ diff --git a/src/format/dwarf/form.c b/src/format/dwarf/form.c new file mode 100644 index 0000000..9d05c8e --- /dev/null +++ b/src/format/dwarf/form.c @@ -0,0 +1,113 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * form.h - prototypes pour la transmission des valeurs d'attributs + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "form.h" + + + +/****************************************************************************** +* * +* Paramètres : value = valeur au format Dwarf à consulter. * +* form = nature de la valeur à lire. * +* addr = valeur utilisable en interne récupérée. [OUT] * +* * +* Description : Transcrit une valeur Dwarf brute en adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_form_into_address(const dw_form_value *value, DwarfForm form, virt_t *addr) +{ + bool result; /* Bilan à retourner */ + + result = true; + + switch (form) + { + case DW_FORM_addr: + *addr = value->v2.address; + break; + + case DW_FORM_data1: + *addr = value->v2.data1; + break; + + case DW_FORM_data2: + *addr = value->v2.data2; + break; + + case DW_FORM_data4: + *addr = value->v2.data4; + break; + + case DW_FORM_data8: + *addr = value->v2.data8; + break; + + default: + result = false; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : value = valeur au format Dwarf à consulter. * +* form = nature de la valeur à lire. * +* * +* Description : Transcrit une valeur Dwarf brute en chaîne de caractères. * +* * +* Retour : Bilan de l'opération : chaîne de caractères ou NULL si échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *translate_form_into_string(const dw_form_value *value, DwarfForm form) +{ + const char *result; /* Valeur et bilan à retourner */ + + switch (form) + { + case DW_FORM_string: + case DW_FORM_strp: + result = value->v2.string; + break; + + default: + result = NULL; + break; + + } + + return result; + +} diff --git a/src/format/dwarf/form.h b/src/format/dwarf/form.h new file mode 100644 index 0000000..b6c3f47 --- /dev/null +++ b/src/format/dwarf/form.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * form.h - prototypes pour la transmission des valeurs d'attributs + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _FORMAT_DWARF_FORM_H +#define _FORMAT_DWARF_FORM_H + + +#include "dwarf_def.h" + + + +/* Transcrit une valeur Dwarf brute en adresse virtuelle. */ +bool translate_form_into_address(const dw_form_value *, DwarfForm, virt_t *); + +/* Transcrit une valeur Dwarf brute en chaîne de caractères. */ +const char *translate_form_into_string(const dw_form_value *, DwarfForm); + + + +#endif /* _FORMAT_DWARF_FORM_H */ diff --git a/src/format/dwarf/info.c b/src/format/dwarf/info.c index 8106114..4ef6484 100644 --- a/src/format/dwarf/info.c +++ b/src/format/dwarf/info.c @@ -24,6 +24,170 @@ #include "info.h" +#include "die.h" +#include "dwarf-int.h" +#include "../debuggable-int.h" + + + + + +static bool extract_dies_from_debug_information(GDwarfFormat *format, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die *parent, dw_die **die); + + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage DWARF à compléter. * +* * +* Description : Charge les informations depuis une section ".debug_info". * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_dwarf_debug_information(GDwarfFormat *format) +{ + bool result; /* Bilan à renvoyer */ + + + + mrange_t range; /* Couverture d'une section */ + vmpa2t end; + vmpa2t iter; /* Tête de lecture mouvante */ + + dw_compil_unit_header header; + dw_die *die; + + + + result = g_exe_format_get_section_range_by_name(G_DBG_FORMAT(format)->executable, ".debug_info", &range); + if (!result) goto lddi_exit; + + copy_vmpa(&iter, get_mrange_addr(&range)); + + + printf("[%d] Passage :: 0x%08llx 0x%08llx\n", + result, + (unsigned long long)range.addr.physical, + (unsigned long long)range.addr.virtual); + + compute_mrange_end_addr(&range, &end); + + while (result) + { + /* Si il n'y a plus rien à lire dans la section... */ + if (cmp_vmpa(&iter, &end) >= 0) break; + + + printf("========================================================================\n"); + printf("========================================================================\n"); + printf("========================================================================\n"); + printf("========================================================================\n"); + printf("\n"); + printf("HEADER START :: 0x%x\n", (unsigned int)iter.physical); + + + result = read_dwarf_compil_unit_header(G_BIN_FORMAT(format)->content, &iter, + SRE_LITTLE /* FIXME */, &header); + if (!result) break; + + printf("[%d] header :: addr size=%hhu\n", result, header.address_size); + + + result = extract_dies_from_debug_information(format, &iter, + SRE_LITTLE /* FIXME */, &header, + NULL, &die); + + + + } + + + format->info_die = die; + + + lddi_exit: + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : format = informations de débogage DWARF à compléter. * +* pos = position de début de lecture. [OUT] * +* endian = boutisme reconnu dans le format. * +* header = en-tête de description de l'unité à traiter. * +* parent = entrée parent de rattachement ou NULL si racine. * +* die = emplacement de stockage de l'entrée. [OUT] * +* * +* Description : Procède à la lecture de l'en-tête d'un contenu binaire DWARF.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool extract_dies_from_debug_information(GDwarfFormat *format, vmpa2t *pos, SourceEndian endian, const dw_compil_unit_header *header, dw_die *parent, dw_die **die) +{ + bool result; /* Bilan à faire remonter */ + dw_die *child; /* Entrée subordonnée à charger*/ + + printf("==================================\n"); + printf("=== version : 0x%hx\n", header->version); + printf("=== offset abbrev : 0x%llx\n", (unsigned long long)header->debug_abbrev_offset); + printf("==================================\n"); + + + phys_t start = 0x1039; + + printf("start :: 0x%x\n", (unsigned int)(pos->physical - start)); + printf("start :: 0x%x\n", (unsigned int)(0x0 + pos->physical)); + + result = build_dwarf_die(format, pos, SRE_LITTLE /* FIXME */, header, die); + if (*die == NULL) return result; + + if (parent != NULL) + dw_die_append_child(parent, *die); + + if (dw_die_has_children(*die)) + { + printf("<<<< children >>>>\n"); + + printf("next :: 0x%x\n", (unsigned int)(pos->physical - start)); + + while (result) + { + result = extract_dies_from_debug_information(format, pos, endian, header, *die, &child); + + if (!result) + delete_dwarf_die(*die); + + /* Entrée avec un code nul -> fin */ + if (child == NULL) break; + + } + + } + + return result; + +} + + + + + + + +#if 0 #include #include @@ -686,3 +850,4 @@ char *resolve_dwarf_function_type(dwarf_format *format, const dw_abbrev *abbrev, return result; } +#endif diff --git a/src/format/dwarf/info.h b/src/format/dwarf/info.h index 0c0f154..805306b 100644 --- a/src/format/dwarf/info.h +++ b/src/format/dwarf/info.h @@ -28,6 +28,25 @@ #include +#include "dwarf.h" + + + +/* Charge les informations depuis une section ".debug_info". */ +bool load_dwarf_debug_information(GDwarfFormat *); + + + + + + + + +#if 0 + +#include + + #include "d_dwarf.h" @@ -37,6 +56,7 @@ bool load_dwarf_information(dwarf_format *); /* Décharge les informations trouvées dans un DWARF. */ void unload_dwarf_information(dwarf_format *); +#endif diff --git a/src/format/dwarf/symbols.c b/src/format/dwarf/symbols.c new file mode 100644 index 0000000..ceaee9e --- /dev/null +++ b/src/format/dwarf/symbols.c @@ -0,0 +1,318 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.c - gestion des symboles d'un DWARF + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "symbols.h" + + +#include "die.h" +#include "dwarf-int.h" +#include "form.h" +#include "../mangling/demangler.h" +#include "../../core/params.h" + + + +/* Charge les informations d'une routine en tant que symbole. */ +static bool load_routine_as_symbol_from_dwarf(GDwarfFormat *, const dw_die *, const dw_abbrev *, bool); + +/* Charge les informations d'un objet en tant que symbole. */ +static bool load_object_as_symbol_from_dwarf(GDwarfFormat *, const dw_die *, const dw_abbrev *, bool); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* die = entrée d'informations de débogage à utiliser. * +* abbrev = abréviation déjà chargée sur laquelle s'appuyer. * +* use_virt = oriente le choix de la distinction ultime. * +* * +* Description : Charge les informations d'une routine en tant que symbole. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool load_routine_as_symbol_from_dwarf(GDwarfFormat *format, const dw_die *die, const dw_abbrev *abbrev, bool use_virt) +{ + DwarfForm form; /* Type d'une valeur d'attribut*/ + const dw_form_value *value; /* Valeur concrète d'attribut */ + virt_t virt; /* Adresse virtuelle de départ */ + bool status; /* Bilan d'une récupération */ + virt_t len; /* Taille de la zone couverte */ + vmpa2t addr; /* Localisation complète */ + mrange_t range; /* Espace de couverture total */ + const char *name; /* Désignation humaine */ + char alt_name[6 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + /* Surface couverte */ + + value = dw_die_peek_extended_value(die, DW_AT_low_pc, &form); + if (value == NULL) goto lrasfd_bad_start; + + status = translate_form_into_address(value, form, &virt); + if (!status) goto lrasfd_bad_start; + + value = dw_die_peek_extended_value(die, DW_AT_high_pc, &form); + if (value == NULL) goto lrasfd_bad_start; + + status &= translate_form_into_address(value, form, &len); + if (!status) goto lrasfd_bad_start; + + if (!g_exe_format_translate_address_into_vmpa(G_DBG_FORMAT(format)->executable, virt, &addr)) + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + init_mrange(&range, &addr, len); + + /* Désignation humaine */ + + value = dw_die_peek_extended_value(die, DW_AT_name, &form); + if (value == NULL) goto lrasfd_bad_name; + + name = translate_form_into_string(value, form); + + if (name == NULL) + { + strcpy(alt_name, "func_"); + + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + + name = alt_name; + + } + + /* Intégration en bonne et due forme */ + + routine = try_to_demangle_routine(name); + + g_binary_routine_set_range(routine, &range); + + symbol = g_binary_symbol_new(STP_ROUTINE); + g_binary_symbol_attach_routine(symbol, routine); + + _g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol, false); + + + + + printf(" --> [valid ?= %d] start @ 0x%08llx\n", status, virt); + printf(" --> [valid ?= %d] len = 0x%08llx\n", status, len); + printf(" --> [valid ?= %d] name = '%s'\n", status, name); + + + return true; + + lrasfd_bad_start: + lrasfd_bad_name: + + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* die = entrée d'informations de débogage à utiliser. * +* abbrev = abréviation déjà chargée sur laquelle s'appuyer. * +* use_virt = oriente le choix de la distinction ultime. * +* * +* Description : Charge les informations d'un objet en tant que symbole. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool load_object_as_symbol_from_dwarf(GDwarfFormat *format, const dw_die *die, const dw_abbrev *abbrev, bool use_virt) +{ + DwarfForm form; /* Type d'une valeur d'attribut*/ + const dw_form_value *value; /* Valeur concrète d'attribut */ + virt_t virt; /* Adresse virtuelle de départ */ + bool status; /* Bilan d'une récupération */ + virt_t len; /* Taille de la zone couverte */ + vmpa2t addr; /* Localisation complète */ + mrange_t range; /* Espace de couverture total */ + const char *name; /* Désignation humaine */ + char alt_name[5 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + /* Surface couverte */ + + + + + + + /* + value = dw_die_peek_extended_value(die, DW_AT_low_pc, &form); + if (value == NULL) goto lrasfd_bad_start; + + status = translate_form_into_address(value, form, &virt); + if (!status) goto lrasfd_bad_start; + + value = dw_die_peek_extended_value(die, DW_AT_high_pc, &form); + if (value == NULL) goto lrasfd_bad_start; + + status &= translate_form_into_address(value, form, &len); + if (!status) goto lrasfd_bad_start; + + if (!g_exe_format_translate_address_into_vmpa(G_DBG_FORMAT(format)->executable, virt, &addr)) + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + init_mrange(&range, &addr, len); + */ + + + + + + /* Désignation humaine */ + + value = dw_die_peek_extended_value(die, DW_AT_name, &form); + if (value == NULL) goto lrasfd_bad_name; + + name = translate_form_into_string(value, form); + + if (name == NULL) + { + strcpy(alt_name, "obj_"); + + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + + name = alt_name; + + } + + /* Intégration en bonne et due forme */ + + /* + routine = try_to_demangle_routine(name); + + g_binary_routine_set_range(routine, &range); + + symbol = g_binary_symbol_new(STP_OBJECT); + g_binary_symbol_attach_routine(symbol, routine); + + _g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol, false); + */ + + + + //printf(" --> [valid ?= %d] start @ 0x%08llx\n", status, virt); + //printf(" --> [valid ?= %d] len = 0x%08llx\n", status, len); + printf(" --> [valid ?= %d] name = '%s'\n", status, name); + + + return true; + + lrasfd_bad_start: + lrasfd_bad_name: + + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* * +* Description : Charge en mémoire la liste humaine des symboles. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_dwarf_symbols(GDwarfFormat *format) +{ + bool result; /* Bilan à retourner */ + bool no_name; /* Choix de construction de nom*/ + + typedef struct _die_visit_info + { + GDwarfFormat *format; + bool use_virt; + + } die_visit_info; + + die_visit_info vinfo; /* Information pour visiteur */ + + + bool catch_dwarf_symbol(const dw_die *die, die_visit_info *info) + { + const dw_abbrev *abbrev; /* Lien vers la représentation */ + DwarfTag tag; /* Etiquette à analyser */ + bool status; /* Bilan d'un chargement */ + + abbrev = dw_die_get_abbrev(die); + tag = dwarf_abbreviation_get_tag(abbrev); + + switch (tag) + { + case DW_TAG_subprogram: + printf(" DIE ==> %p -> %p // tag = %x\n", die, abbrev, tag); + status = load_routine_as_symbol_from_dwarf(info->format, die, abbrev, info->use_virt); + break; + + case DW_TAG_variable: + printf(" DIE ==> %p -> %p // tag = %x\n", die, abbrev, tag); + status = load_object_as_symbol_from_dwarf(info->format, die, abbrev, info->use_virt); + break; + + default: + status = true; + break; + + } + + return status; + + } + + + if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name)) + return false; + + vinfo.format = format; + vinfo.use_virt = no_name; + + result = dw_die_visit(format->info_die, (visit_dies_fc)catch_dwarf_symbol, &vinfo); + + return result; + +} diff --git a/src/format/dwarf/symbols.h b/src/format/dwarf/symbols.h new file mode 100644 index 0000000..cc6085a --- /dev/null +++ b/src/format/dwarf/symbols.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.h - prototypes pour la gestion des symboles d'un DWARF + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _FORMAT_DWARF_SYMBOLS_H +#define _FORMAT_DWARF_SYMBOLS_H + + +#include + + +#include "dwarf.h" + + + +/* Charge en mémoire la liste humaine des symboles. */ +bool load_dwarf_symbols(GDwarfFormat *); + + + +#endif /* _FORMAT_DWARF_SYMBOLS_H */ diff --git a/src/format/dwarf/v2/Makefile.am b/src/format/dwarf/v2/Makefile.am index 54e7719..04dee14 100644 --- a/src/format/dwarf/v2/Makefile.am +++ b/src/format/dwarf/v2/Makefile.am @@ -2,7 +2,8 @@ noinst_LTLIBRARIES = libformatdwarfv2.la libformatdwarfv2_la_SOURCES = \ - dwarf.h dwarf.c + dwarf.h dwarf.c \ + form.h form.c libformatdwarfv2_la_LDFLAGS = $(LIBGTK_LIBS) diff --git a/src/format/dwarf/v2/dwarf.c b/src/format/dwarf/v2/dwarf.c index 73e4e04..ccef01f 100644 --- a/src/format/dwarf/v2/dwarf.c +++ b/src/format/dwarf/v2/dwarf.c @@ -27,6 +27,9 @@ #include "../dwarf-int.h" +#include "form.h" + + /* Format de débogage DWARF v2 (instance) */ struct _GDwarfV2Format @@ -76,12 +79,17 @@ G_DEFINE_TYPE(GDwarfV2Format, g_dwarfv2_format, G_TYPE_DWARF_FORMAT); static void g_dwarfv2_format_class_init(GDwarfV2FormatClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GDwarfFormatClass *dwarf; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_dwarfv2_format_dispose; object->finalize = (GObjectFinalizeFunc)g_dwarfv2_format_finalize; + dwarf = G_DWARF_FORMAT_CLASS(klass); + + dwarf->read_form = (read_form_value_fc)read_dwarf_v2_form_value; + } diff --git a/src/format/dwarf/v2/form.c b/src/format/dwarf/v2/form.c new file mode 100644 index 0000000..8a16887 --- /dev/null +++ b/src/format/dwarf/v2/form.c @@ -0,0 +1,272 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * form.c - chargement en mémoire des valeurs d'attributs + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "form.h" + + +#include "../dwarf-int.h" + + + +/****************************************************************************** +* * +* Paramètres : format = contenu binaire de débogage à parcourir. * +* cu = unité de compilation parente. * +* form = nature de la valeur à lire. * +* pos = tête de lecture au sein des données. [OUT] * +* value = valeur au format donné lue. [OUT] * +* * +* Description : Lit la valeur correspondant à un type donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_v2_form_value(const GDwarfFormat *format, const dw_compil_unit_header *cu, DwarfForm form, vmpa2t *pos, dw_v2_form_value *value) +{ + bool result; /* Bilan de lecture à renvoyer */ + GBinContent *content; /* Contenu binaire à parcourir */ + SourceEndian endian; /* Boutisme des enregistrements*/ + GExeFormat *exe; /* Format d'exécutable rattaché*/ + const bin_t *tmp; /* Données quelconques */ + uint8_t tmp8; /* Données sur 8 bits */ + uint16_t tmp16; /* Données sur 16 bits */ + uint32_t tmp32; /* Données sur 32 bits */ + uint64_t tmp64; /* Données sur 64 bits */ + uleb128_t tmpuleb; /* Données sur xxx bits */ + phys_t offset; /* Décalage à appliquer */ + mrange_t range; /* Couverture d'une section */ + vmpa2t iter; /* Point de lecture parallèle */ + + content = G_BIN_FORMAT(format)->content; + endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); + exe = G_DBG_FORMAT(format)->executable; + + switch (form) + { + case DW_FORM_addr: + + switch (cu->address_size) + { + case 2: + result = g_binary_content_read_u16(content, pos, endian, &tmp16); + if (result) value->address = tmp16; + break; + case 4: + result = g_binary_content_read_u32(content, pos, endian, &tmp32); + if (result) value->address = tmp32; + break; + case 8: + result = g_binary_content_read_u64(content, pos, endian, &tmp64); + if (result) value->address = tmp64; + break; + default: + result = false; + break; + } + break; + + case DW_FORM_block2: + result = g_binary_content_read_u16(content, pos, endian, &tmp16); + if (result) + { + value->block.size = tmp16; + goto block_finish; + } + break; + + case DW_FORM_block4: + result = g_binary_content_read_u32(content, pos, endian, &tmp32); + if (result) + { + value->block.size = tmp32; + goto block_finish; + } + break; + + case DW_FORM_data2: + result = g_binary_content_read_u16(content, pos, endian, &value->data2); + break; + + case DW_FORM_data4: + result = g_binary_content_read_u32(content, pos, endian, &value->data4); + break; + + case DW_FORM_data8: + result = g_binary_content_read_u64(content, pos, endian, &value->data8); + break; + + case DW_FORM_string: + + tmp = g_binary_content_get_raw_access(content, pos, 1); + result = (tmp != NULL); + + if (result) + { + value->string = (const char *)tmp; + + while (result && *tmp != '\0') + { + tmp = g_binary_content_get_raw_access(content, pos, 1); + result = (tmp != NULL); + } + + } + + break; + + case DW_FORM_block: + + tmpuleb = 0; /* Pour GCC */ + + result = g_binary_content_read_uleb128(content, pos, &tmpuleb); + if (!result) break; + + value->block.size = tmpuleb; + + block_finish: + + value->block.start = g_binary_content_get_raw_access(content, pos, value->block.size); + + result = (value->block.start != NULL); + break; + + case DW_FORM_block1: + result = g_binary_content_read_u8(content, pos, &tmp8); + if (result) + { + value->block.size = tmp8; + goto block_finish; + } + break; + + case DW_FORM_data1: + result = g_binary_content_read_u8(content, pos, &value->data1); + break; + + case DW_FORM_flag: + result = g_binary_content_read_u8(content, pos, &value->flag); + break; + + case DW_FORM_sdata: + result = g_binary_content_read_leb128(content, pos, &value->sdata); + break; + + case DW_FORM_strp: + + /* Définition des positions */ + + if (cu->is_32b) + { + result = g_binary_content_read_u32(content, pos, endian, &tmp32); + offset = tmp32; + } + else + { + result = g_binary_content_read_u64(content, pos, endian, &tmp64); + offset = tmp64; + } + + /* Lecture dans la section adaptée */ + + if (result) + result = g_exe_format_get_section_range_by_name(exe, ".debug_str", &range); + + if (result) + { + copy_vmpa(&iter, get_mrange_addr(&range)); + advance_vmpa(&iter, offset); + + tmp = g_binary_content_get_raw_access(content, &iter, 1); + result = (tmp != NULL); + + if (result) + { + value->string = (const char *)tmp; + + while (result && *tmp != '\0') + { + tmp = g_binary_content_get_raw_access(content, &iter, 1); + result = (tmp != NULL); + } + + } + + } + + break; + + case DW_FORM_udata: + result = g_binary_content_read_uleb128(content, pos, &value->udata); + break; + + + + + + + + + + + + case DW_FORM_ref1: + result = g_binary_content_read_u8(content, pos, &value->ref1); + break; + + case DW_FORM_ref2: + result = g_binary_content_read_u16(content, pos, endian, &value->ref2); + break; + + case DW_FORM_ref4: + result = g_binary_content_read_u32(content, pos, endian, &value->ref4); + break; + + case DW_FORM_ref8: + result = g_binary_content_read_u64(content, pos, endian, &value->ref8); + break; + + case DW_FORM_ref_udata: + result = g_binary_content_read_uleb128(content, pos, &value->ref_udata); + break; + + + + + + + + + + + default: + result = false; + break; + + } + + return result; + +} diff --git a/src/format/dwarf/v2/form.h b/src/format/dwarf/v2/form.h new file mode 100644 index 0000000..f88001b --- /dev/null +++ b/src/format/dwarf/v2/form.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * form.h - prototypes pour le chargement en mémoire des valeurs d'attributs + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _FORMAT_DWARF_V2_FORM_H +#define _FORMAT_DWARF_V2_FORM_H + + +#include "../dwarf.h" +#include "../dwarf_def.h" +#include "../../../analysis/content.h" + + + +/* Lit la valeur correspondant à un type donné. */ +bool read_dwarf_v2_form_value(const GDwarfFormat *, const dw_compil_unit_header *, DwarfForm, vmpa2t *, dw_v2_form_value *); + + + +#endif /* _FORMAT_DWARF_V2_FORM_H */ diff --git a/src/format/dwarf/v4/Makefile.am b/src/format/dwarf/v4/Makefile.am index fb3bc43..b0c9719 100644 --- a/src/format/dwarf/v4/Makefile.am +++ b/src/format/dwarf/v4/Makefile.am @@ -2,7 +2,8 @@ noinst_LTLIBRARIES = libformatdwarfv4.la libformatdwarfv4_la_SOURCES = \ - dwarf.h dwarf.c + dwarf.h dwarf.c \ + form.h form.c libformatdwarfv4_la_LDFLAGS = $(LIBGTK_LIBS) diff --git a/src/format/dwarf/v4/dwarf.c b/src/format/dwarf/v4/dwarf.c index 164d321..52345e8 100644 --- a/src/format/dwarf/v4/dwarf.c +++ b/src/format/dwarf/v4/dwarf.c @@ -27,6 +27,9 @@ #include "../dwarf-int.h" +#include "form.h" + + /* Format de débogage DWARF v4 (instance) */ struct _GDwarfV4Format @@ -76,12 +79,17 @@ G_DEFINE_TYPE(GDwarfV4Format, g_dwarfv4_format, G_TYPE_DWARF_FORMAT); static void g_dwarfv4_format_class_init(GDwarfV4FormatClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GDwarfFormatClass *dwarf; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_dwarfv4_format_dispose; object->finalize = (GObjectFinalizeFunc)g_dwarfv4_format_finalize; + dwarf = G_DWARF_FORMAT_CLASS(klass); + + dwarf->read_form = (read_form_value_fc)read_dwarf_v4_form_value; + } @@ -160,11 +168,13 @@ GBinFormat *g_dwarfv4_format_new(GBinContent *content, GExeFormat *parent) result = g_object_new(G_TYPE_DWARFV4_FORMAT, NULL); - - g_binary_format_set_content(G_BIN_FORMAT(result), content); - + if (!g_dwarf_format_load(G_DWARF_FORMAT(result), parent)) + { + g_object_unref(G_OBJECT(result)); + result = NULL; + } return G_BIN_FORMAT(result); diff --git a/src/format/dwarf/v4/form.c b/src/format/dwarf/v4/form.c new file mode 100644 index 0000000..fffc0c3 --- /dev/null +++ b/src/format/dwarf/v4/form.c @@ -0,0 +1,106 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * form.c - chargement en mémoire des valeurs d'attributs + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "form.h" + + +#include "../dwarf-int.h" +#include "../v2/form.h" + + + +/****************************************************************************** +* * +* Paramètres : format = contenu binaire de débogage à parcourir. * +* cu = unité de compilation parente. * +* form = nature de la valeur à lire. * +* pos = tête de lecture au sein des données. [OUT] * +* value = valeur au format donné lue. [OUT] * +* * +* Description : Lit la valeur correspondant à un type donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dwarf_v4_form_value(const GDwarfFormat *format, const dw_compil_unit_header *cu, DwarfForm form, vmpa2t *pos, dw_v4_form_value *value) +{ + bool result; /* Bilan de lecture à renvoyer */ + GBinContent *content; /* Contenu binaire à parcourir */ + SourceEndian endian; /* Boutisme des enregistrements*/ + uint32_t tmp32; /* Données sur 32 bits */ + uint64_t tmp64; /* Données sur 64 bits */ + uleb128_t tmpuleb; /* Données sur xxx bits */ + + content = G_BIN_FORMAT(format)->content; + endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); + + switch (form) + { + case DW_FORM_sec_offset: + + if (cu->is_32b) + { + result = g_binary_content_read_u32(content, pos, endian, &tmp32); + tmp64 = tmp32; + } + else + result = g_binary_content_read_u64(content, pos, endian, &tmp64); + + value->sec_offset = tmp64; + break; + + case DW_FORM_exprloc: + + tmpuleb = 0; /* Pour GCC */ + + result = g_binary_content_read_uleb128(content, pos, &tmpuleb); + if (!result) break; + + value->expr.size = tmpuleb; + + value->expr.start = g_binary_content_get_raw_access(content, pos, value->expr.size); + result = (value->expr.start != NULL); + + break; + + case DW_FORM_flag_present: + result = true; + value->has_flag = true; + break; + + case DW_FORM_ref_sig8: + result = g_binary_content_read_u64(content, pos, endian, &value->signature); + break; + + default: + result = read_dwarf_v2_form_value(format, cu, form, pos, &value->v2); + break; + + } + + return result; + +} diff --git a/src/format/dwarf/v4/form.h b/src/format/dwarf/v4/form.h new file mode 100644 index 0000000..ac36142 --- /dev/null +++ b/src/format/dwarf/v4/form.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * form.h - prototypes pour le chargement en mémoire des valeurs d'attributs + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _FORMAT_DWARF_V4_FORM_H +#define _FORMAT_DWARF_V4_FORM_H + + +#include "../dwarf.h" +#include "../dwarf_def.h" +#include "../../../analysis/content.h" + + + +/* Lit la valeur correspondant à un type donné. */ +bool read_dwarf_v4_form_value(const GDwarfFormat *, const dw_compil_unit_header *, DwarfForm, vmpa2t *, dw_v4_form_value *); + + + +#endif /* _FORMAT_DWARF_V4_FORM_H */ diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 4bc8bbf..0c7760c 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -62,6 +62,9 @@ static void g_elf_format_dispose(GElfFormat *); /* Procède à la libération totale de la mémoire. */ static void g_elf_format_finalize(GElfFormat *); +/* Informe quant au boutisme utilisé. */ +static SourceEndian g_elf_format_get_endianness(const GElfFormat *); + /* Indique le type d'architecture visée par le format. */ static const char *g_elf_format_get_target_machine(const GElfFormat *); @@ -142,6 +145,7 @@ G_DEFINE_TYPE(GElfFormat, g_elf_format, G_TYPE_EXE_FORMAT); static void g_elf_format_class_init(GElfFormatClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GBinFormatClass *fmt; /* Version en format basique */ GExeFormatClass *exe; /* Version en exécutable */ object = G_OBJECT_CLASS(klass); @@ -149,6 +153,10 @@ static void g_elf_format_class_init(GElfFormatClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_elf_format_dispose; object->finalize = (GObjectFinalizeFunc)g_elf_format_finalize; + fmt = G_BIN_FORMAT_CLASS(klass); + + fmt->get_endian = (format_get_endian_fc)g_elf_format_get_endianness; + exe = G_EXE_FORMAT_CLASS(klass); exe->get_machine = (get_target_machine_fc)g_elf_format_get_target_machine; @@ -311,6 +319,25 @@ GBinFormat *g_elf_format_new(GBinContent *content, GExeFormat *parent) * * * Paramètres : format = informations chargées à consulter. * * * +* Description : Informe quant au boutisme utilisé. * +* * +* Retour : Indicateur de boutisme. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static SourceEndian g_elf_format_get_endianness(const GElfFormat *format) +{ + return format->endian; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * * Description : Indique le type d'architecture visée par le format. * * * * Retour : Identifiant de l'architecture ciblée par le format. * @@ -703,22 +730,3 @@ const elf_header *g_elf_format_get_header(const GElfFormat *format) return &format->header; } - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Informe quant au boutisme utilisé. * -* * -* Retour : Indicateur de boutisme. * -* * -* Remarques : - * -* * -******************************************************************************/ - -SourceEndian g_elf_format_get_endianness(const GElfFormat *format) -{ - return format->endian; - -} diff --git a/src/format/elf/elf.h b/src/format/elf/elf.h index a557927..d6f631e 100644 --- a/src/format/elf/elf.h +++ b/src/format/elf/elf.h @@ -61,9 +61,6 @@ GBinFormat *g_elf_format_new(GBinContent *, GExeFormat *); /* Présente l'en-tête ELF du format chargé. */ const elf_header *g_elf_format_get_header(const GElfFormat *); -/* Informe quant au boutisme utilisé. */ -SourceEndian g_elf_format_get_endianness(const GElfFormat *); - #endif /* _FORMAT_ELF_ELF_H */ diff --git a/src/format/format-int.h b/src/format/format-int.h index 84f77c4..90b278e 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -32,6 +32,9 @@ /* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ +/* Indique le boutisme employé par le format binaire analysé. */ +typedef SourceEndian (* format_get_endian_fc) (const GBinFormat *); + /* Procède à la décompilation complète du format. */ typedef void (* format_decompile_fc) (const GBinFormat *, GCodeBuffer *, const char *); @@ -75,6 +78,8 @@ struct _GBinFormatClass { GObjectClass parent; /* A laisser en premier */ + format_get_endian_fc get_endian; /* Boutisme employé */ + }; diff --git a/src/format/format.c b/src/format/format.c index 387894c..88f59b8 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -149,6 +149,10 @@ bool g_binary_format_complete_loading(GBinFormat *format) void g_binary_format_set_content(GBinFormat *format, GBinContent *content) { + assert(format->content == NULL); + + g_object_ref(G_OBJECT(content)); + format->content = content; } @@ -177,6 +181,25 @@ GBinContent *g_binary_format_get_content(const GBinFormat *format) /****************************************************************************** * * +* Paramètres : format = description de l'exécutable à consulter. * +* * +* Description : Indique le boutisme employé par le format binaire analysé. * +* * +* Retour : Boutisme associé au format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +SourceEndian g_binary_format_get_endianness(const GBinFormat *format) +{ + return G_BIN_FORMAT_GET_CLASS(format)->get_endian(format); + +} + + +/****************************************************************************** +* * * Paramètres : format = description de l'exécutable à compléter. * * pt = point de l'espace mémoire à considérer. * * entry = nature du point fourni. * diff --git a/src/format/format.h b/src/format/format.h index b1f0110..4a56d47 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -40,7 +40,8 @@ #define G_TYPE_BIN_FORMAT g_binary_format_get_type() #define G_BIN_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_format_get_type(), GBinFormat)) #define G_IS_BIN_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_format_get_type())) -#define G_BIN_FORMAT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_binary_format_get_type(), GBinFormatIface)) +#define G_BIN_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_FORMAT, GBinFormatClass)) +#define G_IS_BIN_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_FORMAT)) #define G_BIN_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_FORMAT, GBinFormatClass)) @@ -57,6 +58,9 @@ GType g_binary_format_get_type(void); /* Fournit une référence vers le contenu binaire analysé. */ GBinContent *g_binary_format_get_content(const GBinFormat *); +/* Indique le boutisme employé par le format binaire analysé. */ +SourceEndian g_binary_format_get_endianness(const GBinFormat *); + /* Enregistre une adresse comme début d'une zone de code. */ void g_binary_format_register_code_point(GBinFormat *, virt_t, bool); -- cgit v0.11.2-87-g4458