From 7468875c1022337efbff78069d715672ae083150 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 13 Dec 2009 11:54:32 +0000 Subject: Loaded and saved binary parts. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@140 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 49 ++++++++++++ src/analysis/binary.c | 182 ++++++++++++++++++++++++++++++++++++++++++-- src/analysis/line-int.h | 2 +- src/analysis/line.c | 2 +- src/arch/Makefile.am | 2 +- src/arch/jvm/Makefile.am | 2 +- src/arch/mips/Makefile.am | 2 +- src/arch/x86/Makefile.am | 2 +- src/common/dllist.c | 24 ------ src/common/dllist.h | 29 +++---- src/common/xml.c | 107 +++++++++++++++++++++++++- src/common/xml.h | 12 +++ src/format/Makefile.am | 2 +- src/format/elf/Makefile.am | 2 +- src/format/elf/elf.c | 33 ++++++++ src/format/elf/section.c | 40 ++++++++++ src/format/elf/section.h | 3 + src/format/executable-int.h | 5 ++ src/format/executable.c | 21 +++++ src/format/executable.h | 3 + src/format/java/Makefile.am | 2 +- src/format/part.c | 99 ++++++++++++++++++++++++ src/format/part.h | 10 +++ src/format/pe/Makefile.am | 2 +- 24 files changed, 576 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1deb97d..f5f5ab2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +09-12-13 Cyrille Bagard + + * src/analysis/binary.c: + Load and save binary parts (default, routines and user defined). + + * src/analysis/line.c: + * src/analysis/line-int.h: + Use the new functions to insert lines. + + * src/arch/jvm/Makefile.am: + * src/arch/Makefile.am: + * src/arch/mips/Makefile.am: + * src/arch/x86/Makefile.am: + Add LIBXML_CFLAGS to INCLUDES. + + * src/common/dllist.c: + * src/common/dllist.h: + Remove the buggy *splice* functions and replace them with dl_list_add_before. + + * src/common/xml.c: + * src/common/xml.h: + Create functions to add nodes or attributes to XML nodes. + + * src/format/elf/elf.c: + Provide a way to translate a file offset into a virtual address. + + * src/format/elf/Makefile.am: + Add LIBXML_CFLAGS to INCLUDES. + + * src/format/elf/section.c: + * src/format/elf/section.h: + * src/format/executable.c: + * src/format/executable.h: + * src/format/executable-int.h: + Provide a way to ranslate a file offset into a virtual address. + + * src/format/java/Makefile.am: + Add LIBXML_CFLAGS to INCLUDES. + + * src/format/Makefile.am: + Add LIBXML_CFLAGS to INCLUDES. + + * src/format/part.c: + * src/format/part.h: + Load and save parts unsing XML. + + * src/format/pe/Makefile.am: + Add LIBXML_CFLAGS to INCLUDES. + 09-12-02 Cyrille Bagard * src/format/elf/helper_x86.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index d2c7f3e..56265f2 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -770,15 +770,18 @@ GOpenidaBinary *g_openida_binary_new_from_xml(xmlXPathContextPtr context, const size_t access_len; /* Taille d'un chemin interne */ char *access; /* Chemin pour une sous-config.*/ char *filename; /* Chemin du binaire à charger */ + xmlXPathObjectPtr xobjects; /* Cible d'une recherche */ + int i; /* Boucle de parcours */ + GBinPart *part; /* Partie binaire à traiter */ + off_t offset; /* Position de cette partie */ + vmpa_t addr; /* Adresse correspondante */ result = NULL; /* Chemin du fichier à retrouver */ - access_len = strlen(path) + strlen("/Filename") + 1; - - access = calloc(access_len, sizeof(char)); - snprintf(access, access_len, "%s/Filename", path); + access = strdup(path); + access = stradd(access, "/Filename"); filename = get_node_text_value(context, access); @@ -792,6 +795,129 @@ GOpenidaBinary *g_openida_binary_new_from_xml(xmlXPathContextPtr context, const free(filename); } + /* Parties à désassembler : default */ + + access = strdup(path); + access = stradd(access, "/BinParts/Default/Part"); + + xobjects = get_node_xpath_object(context, access); + + for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobjects); i++) + { + part = g_binary_part_load_from_xml(NODE_FROM_PATH_OBJ(xobjects, i)); + + if (part != NULL) + { + g_binary_part_get_values(part, &offset, NULL, NULL); + + if (!g_exe_format_translate_offset_into_address(G_EXE_FORMAT(result->format), offset, &addr)) + { + g_object_unref(G_OBJECT(part)); + continue; + } + + result->parts_count[BPM_DEFAULT]++; + result->parts[BPM_DEFAULT] = (GBinPart **)realloc(result->parts[BPM_DEFAULT], + result->parts_count[BPM_DEFAULT] * sizeof(GBinPart *)); + + result->parts[BPM_DEFAULT][result->parts_count[BPM_DEFAULT] - 1] = part; + + } + + } + + if(xobjects != NULL) /* FIXME */ + xmlXPathFreeObject(xobjects); + + free(access); + + qsort(result->parts[BPM_DEFAULT], result->parts_count[BPM_DEFAULT], + sizeof(GBinPart *), g_binary_part_compare); + + /* Parties à désassembler : routines */ + + access = strdup(path); + access = stradd(access, "/BinParts/Routines/Part"); + + xobjects = get_node_xpath_object(context, access); + + for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobjects); i++) + { + part = g_binary_part_load_from_xml(NODE_FROM_PATH_OBJ(xobjects, i)); + + if (part != NULL) + { + g_binary_part_get_values(part, &offset, NULL, NULL); + + if (!g_exe_format_translate_offset_into_address(G_EXE_FORMAT(result->format), offset, &addr)) + { + g_object_unref(G_OBJECT(part)); + continue; + } + else g_binary_part_set_address(part, addr); + + result->parts_count[BPM_ROUTINES]++; + result->parts[BPM_ROUTINES] = (GBinPart **)realloc(result->parts[BPM_ROUTINES], + result->parts_count[BPM_ROUTINES] * sizeof(GBinPart *)); + + result->parts[BPM_ROUTINES][result->parts_count[BPM_ROUTINES] - 1] = part; + + } + + } + + if(xobjects != NULL) /* FIXME */ + xmlXPathFreeObject(xobjects); + + free(access); + + qsort(result->parts[BPM_ROUTINES], result->parts_count[BPM_ROUTINES], + sizeof(GBinPart *), g_binary_part_compare); + + /* Parties à désassembler : utilisateur */ + + access = strdup(path); + access = stradd(access, "/BinParts/User/Part"); + + xobjects = get_node_xpath_object(context, access); + + for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobjects); i++) + { + part = g_binary_part_load_from_xml(NODE_FROM_PATH_OBJ(xobjects, i)); + + if (part != NULL) + { + g_binary_part_get_values(part, &offset, NULL, NULL); + + if (!g_exe_format_translate_offset_into_address(G_EXE_FORMAT(result->format), offset, &addr)) + { + g_object_unref(G_OBJECT(part)); + continue; + } + + result->parts_count[BPM_USER]++; + result->parts[BPM_USER] = (GBinPart **)realloc(result->parts[BPM_USER], + result->parts_count[BPM_USER] * sizeof(GBinPart *)); + + result->parts[BPM_USER][result->parts_count[BPM_USER] - 1] = part; + + } + + } + + if(xobjects != NULL) /* FIXME */ + xmlXPathFreeObject(xobjects); + + free(access); + + qsort(result->parts[BPM_USER], result->parts_count[BPM_USER], + sizeof(GBinPart *), g_binary_part_compare); + + + + + + return result; } @@ -816,6 +942,8 @@ bool g_openida_binary_save(const GOpenidaBinary *binary, xmlDocPtr xdoc, xmlXPat { bool result; /* Bilan à faire remonter */ char *access; /* Chemin d'accès à un élément */ + xmlNodePtr node; /* Point d'insertion XML */ + size_t i; /* Boucle de parcours */ result = true; @@ -828,16 +956,49 @@ bool g_openida_binary_save(const GOpenidaBinary *binary, xmlDocPtr xdoc, xmlXPat free(access); + /* Parties à désassembler */ + if (binary->parts_count[BPM_DEFAULT] > 0) + { + access = strdup(path); + access = stradd(access, "/BinParts/Default"); - access = strdup(path); - access = stradd(access, "/Filename2"); + node = ensure_node_exist(xdoc, context, access); - result &= add_content_to_node(xdoc, context, access, binary->filename); + free(access); - free(access); + for (i = 0; i < binary->parts_count[BPM_DEFAULT] && result; i++) + result &= g_binary_part_save_to_xml(binary->parts[BPM_DEFAULT][i], xdoc, node); + } + + if (binary->parts_count[BPM_ROUTINES] > 0) + { + access = strdup(path); + access = stradd(access, "/BinParts/Routines"); + node = ensure_node_exist(xdoc, context, access); + + free(access); + + for (i = 0; i < binary->parts_count[BPM_ROUTINES] && result; i++) + result &= g_binary_part_save_to_xml(binary->parts[BPM_ROUTINES][i], xdoc, node); + + } + + if (binary->parts_count[BPM_USER] > 0) + { + access = strdup(path); + access = stradd(access, "/BinParts/User"); + + node = ensure_node_exist(xdoc, context, access); + + free(access); + + for (i = 0; i < binary->parts_count[BPM_USER] && result; i++) + result &= g_binary_part_save_to_xml(binary->parts[BPM_USER][i], xdoc, node); + + } return result; @@ -914,6 +1075,11 @@ void g_openida_binary_analyse(GOpenidaBinary *binary) queue = get_work_queue(); + + if (binary->parts_count[BPM_ROUTINES] > 0) + binary->model = BPM_ROUTINES; + + if (binary->parts[binary->model] != NULL) { parts = binary->parts[binary->model]; diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h index a78d8b2..9c8e52a 100644 --- a/src/analysis/line-int.h +++ b/src/analysis/line-int.h @@ -57,8 +57,8 @@ struct _GRenderingLine #define lines_list_last(head) dl_list_last(head, GRenderingLine, link) #define lines_list_next_iter(iter, head) dl_list_next_iter(iter, head, GRenderingLine, link) +#define lines_list_add_before(new, head, pos) dl_list_add_before(new, head, pos, link) #define lines_list_add_tail(new, head) dl_list_add_tail(new, head, GRenderingLine, link) -#define lines_list_splice_before(pos, head1, head2) dl_list_splice_before(pos, head1, head2, GRenderingLine, link) #define lines_list_for_each(pos, head) dl_list_for_each(pos, head, GRenderingLine, link) diff --git a/src/analysis/line.c b/src/analysis/line.c index 507597c..24a107b 100644 --- a/src/analysis/line.c +++ b/src/analysis/line.c @@ -424,7 +424,7 @@ void g_rendering_line_insert_into_lines(GRenderingLine **lines, GRenderingLine * else { if (first) - lines_list_splice_before(iter, lines, line); + lines_list_add_before(line, lines, iter); else /* TODO */; } diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index 2aa57b7..ce37874 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -20,7 +20,7 @@ libarch_la_LIBADD = \ libarch_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/arch/jvm/Makefile.am b/src/arch/jvm/Makefile.am index 9b3937a..32c749c 100644 --- a/src/arch/jvm/Makefile.am +++ b/src/arch/jvm/Makefile.am @@ -22,7 +22,7 @@ libarchjvm_la_SOURCES = \ libarchjvm_la_CFLAGS = $(AM_CFLAGS) -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/arch/mips/Makefile.am b/src/arch/mips/Makefile.am index 7b25864..95af97f 100644 --- a/src/arch/mips/Makefile.am +++ b/src/arch/mips/Makefile.am @@ -20,7 +20,7 @@ libarchmips_la_SOURCES = \ libarchmips_la_CFLAGS = $(AM_CFLAGS) -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index 5c684e2..55a88b1 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -51,7 +51,7 @@ libarchx86_la_SOURCES = \ libarchx86_la_CFLAGS = $(AM_CFLAGS) -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/common/dllist.c b/src/common/dllist.c index 5de3cd9..2a75768 100644 --- a/src/common/dllist.c +++ b/src/common/dllist.c @@ -79,27 +79,3 @@ void __dl_list_del(dl_list_item *item, dl_list_head *head) } } - - -/****************************************************************************** -* * -* Paramètres : item = point d'insertion. * -* head = seconde liste à intégrer. * -* * -* Description : Insère une liste au sein d'une autre. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void __dl_list_splice(dl_list_item *pos, dl_list_head head) -{ - pos->next->prev = head; - head->prev->next = pos->next; - - pos->next = head; - head->prev = pos; - -} diff --git a/src/common/dllist.h b/src/common/dllist.h index 3feef5c..499151e 100644 --- a/src/common/dllist.h +++ b/src/common/dllist.h @@ -58,9 +58,6 @@ void __dl_list_add(dl_list_item *, dl_list_head *, dl_list_item *, dl_list_item /* Supprime un élément d'une liste doublement chaînée. */ void __dl_list_del(dl_list_item *, dl_list_head *); -/* Insère une liste au sein d'une autre. */ -void __dl_list_splice(dl_list_item *, dl_list_head); - #define dl_list_empty(head) \ ((head) == NULL) @@ -79,6 +76,17 @@ void __dl_list_splice(dl_list_item *, dl_list_head); } \ while (0) +#define dl_list_add_before(new, head, pos, member) \ + do \ + { \ + pos->member.prev->next = &new->member; \ + new->member.prev = pos->member.prev; \ + pos->member.prev = &new->member; \ + new->member.next = &pos->member; \ + if (pos == *head) *head = new; \ + } \ + while (0) + #define dl_list_add_tail(new, head, type, member) \ do \ { \ @@ -109,21 +117,6 @@ void __dl_list_splice(dl_list_item *, dl_list_head); _result; \ }) -#define dl_list_splice_before(pos, head1, head2, type, member) \ - do \ - { \ - if (pos == *head1) \ - { \ - __dl_list_splice(head2->member.prev, &(*head1)->member); \ - *head1 = head2; \ - } \ - else __dl_list_splice(pos->member.prev, &head2->member); \ - } \ - while(0) - -#define dl_list_splice_after(pos, head2, type, member) \ - __dl_list_splice(&pos->member, &head2->member); - #define dl_list_next_iter(iter, head, type, member) \ (iter->member.next == &head->member ? \ NULL : container_of(iter->member.next, type, member)) diff --git a/src/common/xml.c b/src/common/xml.c index b89b4f9..eb450e0 100644 --- a/src/common/xml.c +++ b/src/common/xml.c @@ -26,6 +26,7 @@ #include +#include #include @@ -694,6 +695,60 @@ xmlNodePtr get_node_from_xpath(xmlXPathContextPtr context, const char *path) * Paramètres : xdoc = structure XML chargée. * * context = contexte à utiliser pour les recherches. * * path = chemin d'accès au noeud visé. * +* name = nom du nouveau noeud à créer. * +* * +* Description : Ajoute un noeud à un autre noeud. * +* * +* Retour : Adresse du noeud mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +xmlNodePtr add_node_to_xpath(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *name) +{ + xmlNodePtr result; /* Noeud créé à retourner */ + xmlNodePtr parent; /* Support du nouveau noeud */ + + parent = get_node_from_xpath(context, path); + if (parent == NULL) return NULL; + + return add_node_to_node(xdoc, parent, name); + +} + + +/****************************************************************************** +* * +* Paramètres : xdoc = structure XML chargée. * +* parent = noeud parent de rattachement. * +* name = nom du nouveau noeud à créer. * +* * +* Description : Ajoute un noeud à un autre noeud. * +* * +* Retour : Adresse du noeud mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +xmlNodePtr add_node_to_node(xmlDocPtr xdoc, xmlNodePtr parent, const char *name) +{ + xmlNodePtr result; /* Noeud créé à retourner */ + + result = xmlNewDocNode(xdoc, NULL, BAD_CAST name, NULL); + result = xmlAddChild(parent, result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : xdoc = structure XML chargée. * +* context = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud visé. * * * * Description : S'assure qu'un noeud donné est bien présent dans le document.* * * @@ -802,8 +857,58 @@ bool add_content_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char node = ensure_node_exist(xdoc, context, path); if (node == NULL) return false; - xmlNodeSetContent(node, content); + xmlNodeSetContent(node, BAD_CAST content); return true; } + + +/****************************************************************************** +* * +* Paramètres : node = noeud dont le contenu est à mettre à jour. * +* name = nom de la propriété à créer. * +* value = chaîne de caractère à placer. * +* * +* Description : Ajoute une propriété à un noeud existant donné. * +* * +* Retour : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_string_attribute_to_node(xmlNodePtr node, const char *name, const char *value) +{ + xmlAttrPtr attrib; /* Attribut créé et en place */ + + attrib = xmlSetProp(node, BAD_CAST name, BAD_CAST value); + + return (attrib != NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud dont le contenu est à mettre à jour. * +* name = nom de la propriété à créer. * +* value = valeur numérique à placer. * +* * +* Description : Ajoute une propriété à un noeud existant donné. * +* * +* Retour : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_long_attribute_to_node(xmlNodePtr node, const char *name, long value) +{ + char tmp[11/*strlen("2147483647")*/]; /* Stockage temporaire */ + + snprintf(tmp, 11, "%ld", value); + + return add_string_attribute_to_node(node, name, tmp); + +} diff --git a/src/common/xml.h b/src/common/xml.h index 82e2578..a555f56 100644 --- a/src/common/xml.h +++ b/src/common/xml.h @@ -111,12 +111,24 @@ bool write_xml_content(xmlTextWriterPtr, const char *, ...); /* Fournit le premier noeud correspondant à un chemin XPath. */ xmlNodePtr get_node_from_xpath(xmlXPathContextPtr, const char *); +/* Ajoute un noeud à un autre noeud. */ +xmlNodePtr add_node_to_path(xmlDocPtr, xmlXPathContextPtr, const char *, const char *); + +/* Ajoute un noeud à un autre noeud. */ +xmlNodePtr add_node_to_node(xmlDocPtr, xmlNodePtr, const char *); + /* S'assure qu'un noeud donné est bien présent dans le document. */ xmlNodePtr ensure_node_exist(xmlDocPtr, xmlXPathContextPtr, const char *); /* S'assure qu'un noeud donné est bien présent dans le document. */ bool add_content_to_node(xmlDocPtr, xmlXPathContextPtr, const char *, const char *); +/* Ajoute une propriété à un noeud existant donné. */ +bool add_string_attribute_to_node(xmlNodePtr, const char *, const char *); + +/* Ajoute une propriété à un noeud existant donné. */ +bool add_long_attribute_to_node(xmlNodePtr, const char *, long); + #endif /* _XML_H */ diff --git a/src/format/Makefile.am b/src/format/Makefile.am index 9bfdd92..838cb99 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -35,7 +35,7 @@ libformat_la_LIBADD = \ libformat_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am index 1e18356..f524bdf 100644 --- a/src/format/elf/Makefile.am +++ b/src/format/elf/Makefile.am @@ -15,7 +15,7 @@ libformatelf_la_SOURCES = \ libformatelf_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index f32bce7..878bf51 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -62,6 +62,9 @@ static vmpa_t g_elf_format_get_entry_point(const GElfFormat *); /* Fournit les références aux zones binaires à analyser. */ static GBinPart **g_elf_format_get_parts(const GElfFormat *, size_t *); +/* Fournit l'adresse virtuelle correspondant à une position. */ +static bool g_elf_format_translate_offset_into_address(const GElfFormat *, off_t, vmpa_t *); + /****************************************************************************** @@ -136,6 +139,8 @@ static void g_elf_format_init(GElfFormat *format) exe_format->get_entry_point = (get_entry_point_fc)g_elf_format_get_entry_point; exe_format->get_parts = (get_parts_fc)g_elf_format_get_parts; + exe_format->translate = (translate_off_fc)g_elf_format_translate_offset_into_address; + } @@ -486,3 +491,31 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count return result; } + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* pos = position dans le flux binaire à retrouver. * +* addr = adresse virtuelle correspondante. [OUT] * +* * +* Description : Fournit l'adresse virtuelle correspondant à une position. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_elf_format_translate_offset_into_address(const GElfFormat *format, off_t pos, vmpa_t *addr) +{ + bool result; /* Bilan à retourner */ + + result = translate_offset_into_address_using_elf_sections(format, pos, addr); + + if (!result) + /* TODO : prgm... */; + + return result; + +} diff --git a/src/format/elf/section.c b/src/format/elf/section.c index f837dbf..b8d6a50 100644 --- a/src/format/elf/section.c +++ b/src/format/elf/section.c @@ -275,3 +275,43 @@ const char *extract_name_from_elf_string_section(const GElfFormat *format, const return result; } + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* pos = position dans le flux binaire à retrouver. * +* addr = adresse virtuelle correspondante. [OUT] * +* * +* Description : Fournit l'adresse virtuelle correspondant à une position. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_offset_into_address_using_elf_sections(const GElfFormat *format, off_t pos, vmpa_t *addr) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + elf_shdr section; /* Section à analyser */ + + result = false; + + for (i = 0; i < format->header.e_shnum && !result; i++) + { + find_elf_section_by_index(format, i, §ion); + + if (ELF_SHDR(format, section, sh_offset) <= pos + && pos < (ELF_SHDR(format, section, sh_offset) + ELF_SHDR(format, section, sh_size))) + { + *addr = ELF_SHDR(format, section, sh_addr) + pos - ELF_SHDR(format, section, sh_offset); + result = true; + } + + } + + return result; + +} diff --git a/src/format/elf/section.h b/src/format/elf/section.h index bc952a4..ca91097 100644 --- a/src/format/elf/section.h +++ b/src/format/elf/section.h @@ -51,6 +51,9 @@ bool find_elf_section_content_by_name(const GElfFormat *, const char *, off_t *, /* Identifie une chaîne de caractères dans une section adéquate. */ const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, off_t); +/* Fournit l'adresse virtuelle correspondant à une position. */ +bool translate_offset_into_address_using_elf_sections(const GElfFormat *, off_t, vmpa_t *); + #endif /* _FORMAT_ELF_SECTION_H */ diff --git a/src/format/executable-int.h b/src/format/executable-int.h index ca8b7d5..e4b18a4 100644 --- a/src/format/executable-int.h +++ b/src/format/executable-int.h @@ -41,6 +41,9 @@ typedef vmpa_t (* get_entry_point_fc) (const GExeFormat *); /* Fournit les références aux zones de code à analyser. */ typedef GBinPart ** (* get_parts_fc) (const GExeFormat *, size_t *); +/* Fournit l'adresse virtuelle correspondant à une position. */ +typedef bool (* translate_off_fc) (const GExeFormat *, off_t, vmpa_t *); + @@ -53,6 +56,8 @@ struct _GExeFormat get_entry_point_fc get_entry_point; /* Obtention du point d'entrée */ get_parts_fc get_parts; /* Liste des parties binaires */ + translate_off_fc translate; /* Correspondance pos -> addr */ + }; /* Format d'exécutable générique (classe) */ diff --git a/src/format/executable.c b/src/format/executable.c index 4fb6b41..4af587f 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -142,3 +142,24 @@ GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count) return format->get_parts(format, count); } + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* pos = position dans le flux binaire à retrouver. * +* addr = adresse virtuelle correspondante. [OUT] * +* * +* Description : Fournit l'adresse virtuelle correspondant à une position. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_exe_format_translate_offset_into_address(const GExeFormat *format, off_t pos, vmpa_t *addr) +{ + return format->translate(format, pos, addr); + +} diff --git a/src/format/executable.h b/src/format/executable.h index bf3269d..4d3f759 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -75,6 +75,9 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *); /* Fournit les références aux zones binaires à analyser. */ GBinPart **g_exe_format_get_parts(const GExeFormat *, size_t *); +/* Fournit l'adresse virtuelle correspondant à une position. */ +bool g_exe_format_translate_offset_into_address(const GExeFormat *, off_t, vmpa_t *); + #endif /* _FORMAT_EXECUTABLE_H */ diff --git a/src/format/java/Makefile.am b/src/format/java/Makefile.am index 46bee9e..1ad2c67 100755 --- a/src/format/java/Makefile.am +++ b/src/format/java/Makefile.am @@ -12,7 +12,7 @@ libformatjava_la_SOURCES = \ libformatjava_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/format/part.c b/src/format/part.c index d21cd87..63747d9 100644 --- a/src/format/part.c +++ b/src/format/part.c @@ -25,6 +25,7 @@ #include +#include #include @@ -123,6 +124,84 @@ GBinPart *g_binary_part_new(void) /****************************************************************************** * * +* Paramètres : node = noeud XML contenant les données à charger. * +* * +* Description : Crée une description de partie de code vierge à partir d'XML.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPart *g_binary_part_load_from_xml(xmlNodePtr node) +{ + GBinPart *result; /* Structure à retourner */ + char *value; /* Propriété lue depuis le XML */ + + result = g_binary_part_new(); + + result->name = qck_get_node_prop_value(node, "name"); + if (result->name == NULL) goto gbplfx_error; + + value = qck_get_node_prop_value(node, "offset"); + if (value == NULL) goto gbplfx_error; + + result->offset = atoi(value); + free(value); + + value = qck_get_node_prop_value(node, "size"); + if (value == NULL) goto gbplfx_error; + + result->size = atoi(value); + free(value); + + return result; + + gbplfx_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : part = description de partie à sauvegarder. * +* xdoc = structure XML chargée. * +* parent = noeud XML où rattacher le futur nouveau noeud. * +* * +* Description : Enregistre les informations d'une partie de code dans du XML.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_part_save_to_xml(const GBinPart *part, xmlDocPtr xdoc, xmlNodePtr parent) +{ + bool result; /* Bilan à retourner */ + xmlNodePtr node; /* Nouveau noeud créé */ + + result = true; + + node = add_node_to_node(xdoc, parent, "Part"); + if (node == NULL) return false; + + result = add_string_attribute_to_node(node, "name", part->name); + result &= add_long_attribute_to_node(node, "offset", part->offset); + result &= add_long_attribute_to_node(node, "size", part->size); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : part = description de partie à mettre à jour. * * name = nom à donner à la partie. * * * @@ -188,6 +267,26 @@ void g_binary_part_set_values(GBinPart *part, off_t offset, off_t size, vmpa_t a /****************************************************************************** * * +* Paramètres : part = description de partie à mettre à jour. * +* addr = adresse de la section à conserver. * +* * +* Description : Définit l'adresse virtuelle d'une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_part_set_address(GBinPart *part, vmpa_t addr) +{ + part->addr = addr; + +} + + +/****************************************************************************** +* * * Paramètres : part = description de partie à consulter. * * offset = position de la section à donner ou NULL. [OUT] * * size = taille de la section à donner ou NULL. [OUT] * diff --git a/src/format/part.h b/src/format/part.h index ff18fc9..5c1c904 100644 --- a/src/format/part.h +++ b/src/format/part.h @@ -29,6 +29,7 @@ #include +#include "../common/xml.h" #include "../arch/archbase.h" @@ -54,6 +55,12 @@ GType g_binary_part_get_type(void); /* Crée une description de partie de code vierge. */ GBinPart *g_binary_part_new(void); +/* Crée une description de partie de code vierge à partir d'XML. */ +GBinPart *g_binary_part_load_from_xml(xmlNodePtr); + +/* Enregistre les informations d'une partie de code dans du XML. */ +bool g_binary_part_save_to_xml(const GBinPart *, xmlDocPtr, xmlNodePtr); + /* Attribue une description humaine à une partie de code. */ void g_binary_part_set_name(GBinPart *, const char *); @@ -63,6 +70,9 @@ const char *g_binary_part_get_name(const GBinPart *); /* Définit les valeurs utiles d'une partie de code. */ void g_binary_part_set_values(GBinPart *, off_t, off_t, vmpa_t); +/* Définit l'adresse virtuelle d'une partie de code. */ +void g_binary_part_set_address(GBinPart *, vmpa_t); + /* Fournit les valeurs utiles d'une partie de code. */ void g_binary_part_get_values(const GBinPart *, off_t *, off_t *, vmpa_t *); diff --git a/src/format/pe/Makefile.am b/src/format/pe/Makefile.am index a11d912..45f2f6b 100755 --- a/src/format/pe/Makefile.am +++ b/src/format/pe/Makefile.am @@ -8,7 +8,7 @@ libformatpe_la_SOURCES = \ libformatpe_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = -- cgit v0.11.2-87-g4458