From 7468875c1022337efbff78069d715672ae083150 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
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 <nocbos@gmail.com>
+
+	* 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 <nocbos@gmail.com>
 
 	* 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 <stdarg.h>
+#include <stdio.h>
 #include <string.h>
 
 
@@ -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, &section);
+
+        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 <malloc.h>
+#include <stdlib.h>
 #include <string.h>
 
 
@@ -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 <sys/types.h>
 
 
+#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