summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-09-19 22:28:42 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-09-19 22:28:42 (GMT)
commit0e3059731d9687027c913135b3b856596c49a689 (patch)
treed3c3754f95c90ae50168817e6248afee6873fbf3 /src/analysis
parent18648e4e8763a3bc005d6fae51eae3d1528d7d29 (diff)
Extended the prototype for matching formats in order to get it suitable for plugins.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@577 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/binaries/file.c8
-rw-r--r--src/analysis/binary-int.h12
-rw-r--r--src/analysis/binary.c307
-rw-r--r--src/analysis/binary.h32
-rw-r--r--src/analysis/content-int.h10
-rw-r--r--src/analysis/content.c86
-rw-r--r--src/analysis/content.h10
-rw-r--r--src/analysis/contents/file.c128
-rw-r--r--src/analysis/contents/file.h3
-rw-r--r--src/analysis/disass/disassembler.c2
-rw-r--r--src/analysis/project.c530
-rw-r--r--src/analysis/project.h52
12 files changed, 1126 insertions, 54 deletions
diff --git a/src/analysis/binaries/file.c b/src/analysis/binaries/file.c
index 32cd41f..c31828c 100644
--- a/src/analysis/binaries/file.c
+++ b/src/analysis/binaries/file.c
@@ -116,8 +116,8 @@ static void g_file_binary_init(GFileBinary *binary)
loaded = G_LOADED_BINARY(binary);
- loaded->save = (save_binary_fc)g_file_binary_save;
- loaded->get_name = (get_binary_name_fc)g_file_binary_get_name;
+ //loaded->save = (save_binary_fc)g_file_binary_save;
+ //loaded->get_name = (get_binary_name_fc)g_file_binary_get_name;
}
@@ -173,7 +173,7 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename)
content = g_file_content_new(filename);
if (content == NULL) goto lbf_error;
- target = find_matching_format(content, NULL);
+ target = "";//find_matching_format(content, NULL);
desc = get_binary_format_name(target);
if (desc == NULL)
@@ -194,7 +194,7 @@ GLoadedBinary *g_file_binary_new_from_file(const char *filename)
goto lbf_error;
}
- target = find_matching_format(content, loaded->format);
+ target = "";//find_matching_format(content, loaded->format);
desc = get_binary_format_name(target);
if (desc != NULL)
diff --git a/src/analysis/binary-int.h b/src/analysis/binary-int.h
index 4bfb14e..60b9662 100644
--- a/src/analysis/binary-int.h
+++ b/src/analysis/binary-int.h
@@ -33,11 +33,8 @@
-/* Ecrit une sauvegarde du binaire dans un fichier XML. */
-typedef bool (* save_binary_fc) (const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
-
/* Fournit le fichier correspondant à l'élément binaire. */
-typedef const char * (* get_binary_name_fc) (const GLoadedBinary *, bool);
+typedef const char * (* get_binary_name_fc) (const GLoadedBinary *, bool); //// REMME
/* Description de fichier binaire (instance) */
@@ -57,11 +54,12 @@ struct _GLoadedBinary
DBStorage storages[DBF_COUNT]; /* Lieux d'enregistrement */
GList *collections; /* Ensemble de modifications */
- save_binary_fc save; /* Sauvegarde au format XML */
- get_binary_name_fc get_name; /* Obtention d'une description */
+ get_binary_name_fc get_name; /* Obtention d'une description */ //// REMME
+
+ GBinContent *content; /* Contenu binaire chargé */ //// REMME
GExeFormat *format; /* Format du binaire */
- GDbgFormat *debug; /* Informations de débogage */
+ GDbgFormat *debug; /* Informations de débogage */ //// REMME
GArchProcessor *proc; /* Architecture du binaire */
GArchInstruction *instrs; /* Instructions d'assemblage */
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 615e72e..c94f4f6 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -24,12 +24,14 @@
#include "binary.h"
+#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+
#include <i18n.h>
@@ -41,8 +43,11 @@
#include "../common/extstr.h"
#include "../common/cpp.h"
#include "../core/collections.h"
+#include "../core/formats.h"
#include "../core/params.h"
+#include "../core/processors.h"
#include "../glibext/chrysamarshal.h"
+#include "../gui/panels/log.h"
@@ -185,8 +190,11 @@ static void g_loaded_binary_init(GLoadedBinary *binary)
static void g_loaded_binary_dispose(GLoadedBinary *binary)
{
+ g_object_unref(G_OBJECT(binary->content));
+
if (binary->format != NULL)
g_object_unref(G_OBJECT(binary->format));
+
if (binary->proc != NULL)
g_object_unref(G_OBJECT(binary->proc));
@@ -222,10 +230,103 @@ static void g_loaded_binary_finalize(GLoadedBinary *binary)
/******************************************************************************
* *
-* Paramètres : context = contexte pour les recherches XPath. *
+* Paramètres : content = contenu binaire chargé en mémoire. *
+* *
+* Description : Interprète un contenu binaire chargé. *
+* *
+* Retour : Adresse de la représentation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GLoadedBinary *g_loaded_binary_new(GBinContent *content)
+{
+ GLoadedBinary *result; /* Adresse à retourner */
+ FormatMatchStatus status; /* Statut d'une reconnaissance */
+ char *target; /* Sous-traitance requise */
+ const char *desc; /* Description humaine associée*/
+ const char *arch; /* Architecture d'exécution */
+
+ result = g_object_new(G_TYPE_LOADED_BINARY, NULL);
+
+ 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 */
+
+ status = find_matching_format(content, NULL, &target);
+ assert(status == FMS_MATCHED);
+
+ desc = get_binary_format_name(target);
+
+ if (desc == NULL)
+ {
+ free(target);
+ log_simple_message(LMT_INFO, _("Unknown binary format"));
+ goto lbf_error;
+ }
+ else
+ log_variadic_message(LMT_INFO, _("Detected format: %s"), desc);
+
+ result->format = G_EXE_FORMAT(load_new_named_format(target, content, NULL));
+
+ free(target);
+
+ if (result->format == NULL)
+ {
+ log_simple_message(LMT_ERROR, _("Error while loading the binary"));
+ goto lbf_error;
+ }
+
+ /* Informations de débogage associées */
+
+ if (!g_loaded_binary_attach_debug_info(result, content))
+ goto lbf_error;
+
+ /* Architecture visée */
+
+ arch = g_exe_format_get_target_machine(result->format);
+ desc = get_arch_processor_name(arch);
+
+ if (desc == NULL)
+ {
+ log_simple_message(LMT_INFO, _("Unknown architecture"));
+ goto lbf_error;
+ }
+ else
+ log_variadic_message(LMT_INFO, _("Detected architecture: %s"), desc);
+
+ result->proc = get_arch_processor_for_type(arch);
+
+ if (result->proc == NULL)
+ {
+ log_simple_message(LMT_ERROR, _("Unable to load the required processor"));
+ goto lbf_error;
+ }
+
+ return G_LOADED_BINARY(result);
+
+ lbf_error:
+
+ g_object_unref(G_OBJECT(result));
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire chargé en mémoire. *
+* context = contexte pour les recherches XPath. *
* path = chemin d'accès au noeud XML à lire. *
+* project = projet dans lequel venir rechercher les contenus. *
* *
-* Description : Charge en mémoire le contenu d'un fichier à partir d'XML. *
+* Description : Interprète un contenu binaire chargé avec un appui XML. *
* *
* Retour : Adresse de la représentation ou NULL en cas d'échec. *
* *
@@ -233,39 +334,94 @@ static void g_loaded_binary_finalize(GLoadedBinary *binary)
* *
******************************************************************************/
-GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path)
+GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path, GStudyProject *project)
{
GLoadedBinary *result; /* Adresse à retourner */
- char *type; /* Type de binaire à charger */
+ char *content_path; /* Partie "Contenus" */
+ char *access; /* Chemin d'accès à un élément */
+ char *hash; /* Empreinte à retrouver */
+ GBinContent *content; /* Contenu à référencer */
+
+ xmlXPathObjectPtr xobject; /* Cible d'une recherche */
+ unsigned int i; /* Boucle de parcours */
+
+ /* Contenus binaires associés */
+
+ content_path = strdup(path);
+ content_path = stradd(content_path, "/Contents");
+
+ access = strdup(content_path);
+ access = stradd(access, "/Main");
+ hash = get_node_text_value(context, access);
+ free(access);
- result = NULL;
+ if (hash == NULL)
+ {
+ free(content_path);
+ return NULL;
+ }
- type = get_node_prop_value(context, path, "type");
+ content = g_study_project_find_binary_content_by_hash(project, hash);
+ free(hash);
- if (strcmp(type, "file") == 0)
- result = g_file_binary_new_from_xml(context, path);
+ if (content == NULL)
+ {
+ free(content_path);
+ return NULL;
+ }
- free(type);
+ result = g_loaded_binary_new(content);
if (result == NULL)
+ {
+ free(content_path);
return NULL;
+ }
- /* --------- %< --------- TODO : à bouger pour + de générique --------- %< --------- */
+ xobject = get_node_xpath_object(context, "/ChrysalideProject/Contents/Content");
+ for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
+ {
+ asprintf(&access, "%s/DebugInfo[position()=%u]", content_path, i + 1);
- // -> init()
- //result->collections = create_collections_list();
+ hash = get_node_text_value(context, access);
+ free(access);
- if (!g_loaded_binary_load_storage(result, context, path))
- goto glbnfx_error;
+ if (hash == NULL)
+ {
+ free(content_path);
+ goto glbnfx_error;
+ }
+
+ content = g_study_project_find_binary_content_by_hash(project, hash);
+ free(hash);
+
+ if (content == NULL)
+ {
+ free(content_path);
+ goto glbnfx_error;
+ }
+ if (!g_loaded_binary_attach_debug_info(result, content))
+ {
+ free(content_path);
+ goto glbnfx_error;
+ }
+
+ }
+
+ if(xobject != NULL)
+ xmlXPathFreeObject(xobject);
- /* --------- %< --------- TODO : à bouger pur + de générique --------- %< --------- */
+ free(content_path);
+ /* Elément divers associés au binaire */
+ if (!g_loaded_binary_load_storage(result, context, path))
+ goto glbnfx_error;
return result;
@@ -296,15 +452,88 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch
bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
{
bool result; /* Bilan à faire remonter */
+ char *content_path; /* Partie "Contenus" */
+ char *access; /* Chemin d'accès à un élément */
+ GBinContent *content; /* Contenu à référencer */
+ const gchar *hash; /* Empreinte à mémoriser */
+ size_t debugs_count; /* Quantité de formats liés */
+ size_t i; /* Boucle de parcours */
+ GDbgFormat *debug; /* Informations de débogage */
+
+ /* Contenus binaires associés */
- result = binary->save(binary, xdoc, context, path);
+ content_path = strdup(path);
+ content_path = stradd(content_path, "/Contents");
+
+ access = strdup(content_path);
+ access = stradd(access, "/Main");
+
+ content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
+ hash = g_binary_content_get_cheksum(content);
+ g_object_unref(G_OBJECT(content));
+
+ result = add_content_to_node(xdoc, context, access, hash);
+
+ free(access);
+
+ debugs_count = g_exe_format_count_debug_info(binary->format);
+
+ for (i = 0; i < debugs_count; i++)
+ {
+ asprintf(&access, "%s/DebugInfo[position()=%zu]", content_path, i);
+
+ debug = g_exe_format_get_debug_info(binary->format, i);
+
+ content = g_binary_format_get_content(G_BIN_FORMAT(debug));
+ hash = g_binary_content_get_cheksum(content);
+ g_object_unref(G_OBJECT(content));
+
+ g_object_unref(G_OBJECT(debug));
+
+ result &= add_content_to_node(xdoc, context, access, hash);
+
+ free(access);
+
+ }
+
+ free(content_path);
+
+ /* Elément divers associés au binaire */
result = g_loaded_binary_save_storage(binary, xdoc, context, path);
+ /* Sauvegarde côté serveur */
- ////
g_db_client_save(binary->local);
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = élément binaire à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le nom associé à l'élément binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_loaded_binary_get_name(const GLoadedBinary *binary, bool full)
+{
+ const char *result; /* Description à retourner */
+ GBinContent *content; /* Contenu binaire mannipulé */
+
+ content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
+
+ result = g_binary_content_describe(content, full);
+
+ g_object_unref(G_OBJECT(content));
return result;
@@ -961,19 +1190,53 @@ void g_loaded_binary_analyse(GLoadedBinary *binary)
/******************************************************************************
* *
* Paramètres : binary = élément binaire à consulter. *
-* full = précise s'il s'agit d'une version longue ou non. *
* *
-* Description : Fournit le nom associé à l'élément binaire. *
+* Description : Fournit le format de fichier reconnu dans le contenu binaire.*
* *
-* Retour : Nom de fichier avec chemin absolu. *
+* Retour : Instance du format reconnu. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *g_loaded_binary_get_name(const GLoadedBinary *binary, bool full)
+bool g_loaded_binary_attach_debug_info(GLoadedBinary *binary, GBinContent *content)
{
- return binary->get_name(binary, full);
+ bool result; /* Bilan à retourner pour info */
+ FormatMatchStatus status; /* Statut d'une reconnaissance */
+ char *target; /* Sous-traitance requise */
+ const char *desc; /* Description humaine associée*/
+ GDbgFormat *debug; /* Format de débogage trouvé */
+
+ result = false;
+
+ status = find_matching_format(content, binary->format, &target);
+
+ if (status == FMS_MATCHED)
+ {
+ desc = get_binary_format_name(target);
+
+ if (desc != NULL)
+ {
+ log_variadic_message(LMT_INFO, _("Detected debug format: %s"), desc);
+
+ debug = G_DBG_FORMAT(load_new_named_format(target, content, binary->format));
+
+ if (debug == NULL)
+ log_simple_message(LMT_ERROR, _("Error while loading the debug information for binary"));
+
+ else
+ {
+ result = true;
+ g_exe_format_add_debug_info(binary->format, debug);
+ }
+
+ }
+
+ free(target);
+
+ }
+
+ return result;
}
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 6b7d338..4ef3a0d 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -28,6 +28,7 @@
#include <glib-object.h>
#include <stdbool.h>
+#include "content.h"
#include "db/collection.h"
#include "db/client.h"
#include "db/protocol.h"
@@ -39,6 +40,23 @@
+/* Redéfinition depuis project.c : projet d'étude regroupant les binaires analysés (instance) */
+typedef struct _GStudyProject GStudyProject;
+
+
+
+#define G_TYPE_LOADED_BINARY g_loaded_binary_get_type()
+#define G_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_loaded_binary_get_type(), GLoadedBinary))
+#define G_IS_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_loaded_binary_get_type()))
+#define G_LOADED_BINARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LOADED_BINARY, GLoadedBinaryClass))
+#define G_IS_LOADED_BINARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LOADED_BINARY))
+#define G_LOADED_BINARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LOADED_BINARY, GLoadedBinaryClass))
+
+
+
+
+
+
#define G_TYPE_LOADED_BINARY g_loaded_binary_get_type()
#define G_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_loaded_binary_get_type(), GLoadedBinary))
#define G_IS_LOADED_BINARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_loaded_binary_get_type()))
@@ -79,12 +97,18 @@ typedef enum _BinaryView
/* Indique le type défini pour une description de fichier binaire. */
GType g_loaded_binary_get_type(void);
-/* Charge en mémoire le contenu d'un fichier à partir d'XML. */
-GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr, const char *);
+/* Interprète un contenu binaire chargé. */
+GLoadedBinary *g_loaded_binary_new(GBinContent *);
+
+/* Interprète un contenu binaire chargé avec un appui XML. */
+GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr, const char *, GStudyProject *);
/* Ecrit une sauvegarde du binaire dans un fichier XML. */
bool g_loaded_binary_save(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
+/* Fournit le nom associé à l'élément binaire. */
+const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
+
/* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */
@@ -155,8 +179,8 @@ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *, DBFeatures, GDbIte
/* Lance l'analyse d'un élément binaire chargé. */
void g_loaded_binary_analyse(GLoadedBinary *);
-/* Fournit le nom associé à l'élément binaire. */
-const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
+/* Fournit le format de fichier reconnu dans le contenu binaire. */
+bool g_loaded_binary_attach_debug_info(GLoadedBinary *, GBinContent *);
/* Fournit le format de fichier reconnu dans le contenu binaire. */
GExeFormat *g_loaded_binary_get_format(const GLoadedBinary *);
diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h
index 7734916..c5b1659 100644
--- a/src/analysis/content-int.h
+++ b/src/analysis/content-int.h
@@ -29,6 +29,12 @@
+/* Fournit le nom associé au contenu binaire. */
+typedef const char * (* describe_content_fc) (const GBinContent *, bool);
+
+/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
+typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *);
+
/* Fournit une empreinte unique (SHA256) pour les données. */
typedef const gchar * (* get_checksum_fc) (GBinContent *);
@@ -62,6 +68,10 @@ struct _GBinContentIface
{
GTypeInterface base_iface; /* A laisser en premier */
+ describe_content_fc describe; /* Fournit une description */
+
+ save_content_fc save; /* Sauvegarde du contenu */
+
get_checksum_fc get_checksum; /* Calcul de l'empreinte */
compute_size_fc compute_size; /* Calcul de la taille totale */
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 5a4c899..d314d0c 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -24,7 +24,11 @@
#include "content.h"
+#include <string.h>
+
+
#include "content-int.h"
+#include "contents/file.h"
@@ -57,6 +61,88 @@ static void g_binary_content_default_init(GBinContentInterface *iface)
/******************************************************************************
* *
+* Paramètres : context = contexte pour les recherches XPath. *
+* path = chemin d'accès au noeud XML à lire. *
+* *
+* Description : Charge en mémoire un contenu binaire à partir d'XML. *
+* *
+* Retour : Adresse de la représentation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr context, const char *path)
+{
+ GBinContent *result; /* Contenu en place à renvoyer */
+ char *type; /* Type de binaire à charger */
+
+ result = NULL;
+
+ type = get_node_prop_value(context, path, "type");
+
+ if (strcmp(type, "file") == 0)
+ result = g_file_content_new_from_xml(context, path);
+
+ free(type);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le nom associé au contenu binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu au besoin. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_binary_content_describe(const GBinContent *content, bool full)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->describe(content, full);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à traiter. *
+* xdoc = structure XML en cours d'édition. *
+* context = contexte à utiliser pour les recherches. *
+* path = chemin d'accès réservé au binaire. *
+* *
+* Description : Ecrit une sauvegarde de contenu binaire dans un fichier XML. *
+* *
+* Retour : true si l'opération a bien tourné, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_save(const GBinContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+{
+ GBinContentIface *iface; /* Interface utilisée */
+
+ iface = G_BIN_CONTENT_GET_IFACE(content);
+
+ return iface->save(content, xdoc, context, path);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : content = contenu binaire à venir lire. *
* *
* Description : Fournit une empreinte unique (SHA256) pour les données. *
diff --git a/src/analysis/content.h b/src/analysis/content.h
index d422dc6..0d991b9 100644
--- a/src/analysis/content.h
+++ b/src/analysis/content.h
@@ -31,6 +31,7 @@
#include "../arch/vmpa.h"
#include "../common/endianness.h"
+#include "../common/xml.h"
@@ -52,6 +53,15 @@ typedef struct _GBinContentIface GBinContentIface;
/* Détermine le type d'une interface pour la lecture de binaire. */
GType g_binary_content_get_type(void) G_GNUC_CONST;
+/* Charge en mémoire un contenu binaire à partir d'XML. */
+GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr, const char *);
+
+/* Fournit le nom associé au contenu binaire. */
+const char *g_binary_content_describe(const GBinContent *, bool);
+
+/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
+bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *);
+
/* Fournit une empreinte unique (SHA256) pour les données. */
const gchar *g_binary_content_get_cheksum(GBinContent *);
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index eb0d488..9f1c10c 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -27,12 +27,14 @@
#include <assert.h>
#include <fcntl.h>
#include <malloc.h>
+#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "../content-int.h"
+#include "../../common/extstr.h"
@@ -41,6 +43,8 @@ struct _GFileContent
{
GObject parent; /* A laisser en premier */
+ char *filename; /* Fichier chargé en mémoire */
+
bin_t *data; /* Contenu binaire représenté */
mrange_t range; /* Couverture du binaire */
@@ -72,6 +76,12 @@ static void g_file_content_dispose(GFileContent *);
/* Procède à la libération totale de la mémoire. */
static void g_file_content_finalize(GFileContent *);
+/* Fournit le nom associé au contenu binaire. */
+static const char *g_file_content_describe(const GFileContent *, bool);
+
+/* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */
+static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *);
+
/* Fournit une empreinte unique (SHA256) pour les données. */
static const gchar *g_file_content_get_checksum(GFileContent *);
@@ -166,6 +176,10 @@ static void g_file_content_init(GFileContent *content)
static void g_file_content_interface_init(GBinContentInterface *iface)
{
+ iface->describe = (describe_content_fc)g_file_content_describe;
+
+ iface->save = (save_content_fc)g_file_content_save;
+
iface->get_checksum = (get_checksum_fc)g_file_content_get_checksum;
iface->compute_size = (compute_size_fc)g_file_content_compute_size;
@@ -217,6 +231,8 @@ static void g_file_content_dispose(GFileContent *content)
static void g_file_content_finalize(GFileContent *content)
{
+ free(content->filename);
+
if (content->data != NULL)
free(content->data);
@@ -275,6 +291,8 @@ GBinContent *g_file_content_new(const char *filename)
result = g_object_new(G_TYPE_FILE_CONTENT, NULL);
+ result->filename = strdup(filename);
+
result->data = (bin_t *)malloc(info.st_size);
memcpy(result->data, content, info.st_size);
@@ -295,6 +313,116 @@ GBinContent *g_file_content_new(const char *filename)
/******************************************************************************
* *
+* Paramètres : context = contexte pour les recherches XPath. *
+* path = chemin d'accès au noeud XML à lire. *
+* *
+* Description : Charge en mémoire le contenu d'un fichier à partir d'XML. *
+* *
+* Retour : Adresse de la représentation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr context, const char *path)
+{
+ GBinContent *result; /* Adresse à retourner */
+ char *access; /* Chemin pour une sous-config.*/
+ char *filename; /* Chemin du binaire à charger */
+
+ result = NULL;
+
+ /* Chemin du fichier à retrouver */
+
+ access = strdup(path);
+ access = stradd(access, "/Filename");
+
+ filename = get_node_text_value(context, access);
+
+ free(access);
+
+ /* Chargement */
+
+ if (filename != NULL)
+ {
+ result = g_file_content_new(filename);
+ free(filename);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à consulter. *
+* full = précise s'il s'agit d'une version longue ou non. *
+* *
+* Description : Fournit le nom associé au contenu binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu au besoin. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_file_content_describe(const GFileContent *content, bool full)
+{
+ const char *result; /* Description à retourner */
+
+ if (full)
+ result = content->filename;
+ else
+ result = strrchr(content->filename, G_DIR_SEPARATOR) + 1;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à traiter. *
+* xdoc = structure XML en cours d'édition. *
+* context = contexte à utiliser pour les recherches. *
+* path = chemin d'accès réservé au binaire. *
+* *
+* Description : Ecrit une sauvegarde de contenu binaire dans un fichier XML. *
+* *
+* Retour : true si l'opération a bien tourné, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+{
+ bool result; /* Bilan à faire remonter */
+ char *access; /* Chemin d'accès à un élément */
+
+ result = true;
+
+ /* Type */
+
+ result &= add_string_attribute_to_node(xdoc, context, path, "type", "file");
+
+ /* Nom du fichier associé */
+
+ access = strdup(path);
+ access = stradd(access, "/Filename");
+
+ result &= add_content_to_node(xdoc, context, access, content->filename);
+
+ free(access);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : content = contenu binaire à venir lire. *
* *
* Description : Fournit une empreinte unique (SHA256) pour les données. *
diff --git a/src/analysis/contents/file.h b/src/analysis/contents/file.h
index 2e3cfef..0985f6b 100644
--- a/src/analysis/contents/file.h
+++ b/src/analysis/contents/file.h
@@ -53,6 +53,9 @@ GType g_file_content_get_type(void);
/* Charge en mémoire le contenu d'un fichier donné. */
GBinContent *g_file_content_new(const char *);
+/* Charge en mémoire le contenu d'un fichier à partir d'XML. */
+GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr, const char *);
+
#endif /* _ANALYSIS_CONTENTS_FILE_H */
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index cd16429..990ab0f 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -705,7 +705,7 @@ void disassemble_binary(GLoadedBinary *binary, GArchInstruction **instrs, GCodeB
checksum = g_binary_content_get_cheksum(content);
g_object_unref(G_OBJECT(content));
- build_disass_prologue(*buffer, g_loaded_binary_get_name(binary, true), checksum);
+ build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum);
disass = g_delayed_disassembly_new(binary, instrs, *buffer);
g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary);
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 5bb028f..db00f09 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -29,14 +29,20 @@
#include <string.h>
+#include <i18n.h>
+
+
#include "binaries/file.h"
#include "../common/xml.h"
+#include "../core/formats.h"
#include "../core/params.h"
#include "../glibext/signal.h"
#include "../gtkext/easygtk.h"
+#include "../glibext/delayed-int.h"
#include "../gtkext/gtkblockview.h"
#include "../gtkext/gtkgraphview.h"
#include "../gtkext/gtksourceview.h"
+#include "../gui/panels/log.h"
#include "../gui/panels/panel.h"
@@ -44,6 +50,14 @@
/* ------------------------- DEFINITION D'UN PROJET INTERNE ------------------------- */
+/* Conservation d'un contenu chargé */
+typedef struct _loaded_content
+{
+ GBinContent *content; /* Contenu binaire en place */
+ ProjectContentState state; /* Renseigne le type de contenu*/
+
+} loaded_content;
+
/* Conservation d'un binaire chargé */
typedef struct _loaded_binary
{
@@ -65,9 +79,13 @@ struct _GStudyProject
char *filename; /* Lieu d'enregistrement */
+ loaded_content *contents; /* Contenus binaires chargés */
+ size_t contents_count; /* Nombre de ces contenus */
+ GMutex cnt_mutex; /* Modification de la liste */
+
loaded_binary **binaries; /* Fichiers binaires associés */
size_t binaries_count; /* Nombre de ces fichiers */
- GMutex mutex; /* Modification de la liste */
+ GMutex bin_mutex; /* Modification de la liste */
};
@@ -91,6 +109,49 @@ static void g_study_project_hide(const GStudyProject *);
+
+
+/* ----------------------- AMORCE POUR CHARGEMENT DE CONTENUS ----------------------- */
+
+
+/* Ensembles binaires à désassembler (instance) */
+struct _GDelayedStudy
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ GStudyProject *project; /* Projet de rattachement */
+ GBinContent *content; /* Contenu binaire à traiter */
+ ProjectContentState state; /* Renseigne le type de contenu*/
+
+ bool only_preload; /* Enregistrement seulement ? */
+
+};
+
+/* Ensembles binaires à désassembler (classe) */
+struct _GDelayedStudyClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des intégrations de binaires à étudier. */
+static void g_delayed_study_class_init(GDelayedStudyClass *);
+
+/* Initialise une intégration de binaire à étudier. */
+static void g_delayed_study_init(GDelayedStudy *);
+
+/* Supprime toutes les références externes. */
+static void g_delayed_study_dispose(GDelayedStudy *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_delayed_study_finalize(GDelayedStudy *);
+
+/* Prépare une intégration de binaire au projet courant. */
+static void g_delayed_study_process(GDelayedStudy *, GtkExtStatusBar *);
+
+
+
/* ---------------------------------------------------------------------------------- */
/* DEFINITION D'UN PROJET INTERNE */
/* ---------------------------------------------------------------------------------- */
@@ -132,7 +193,9 @@ static void g_study_project_class_init(GStudyProjectClass *klass)
static void g_study_project_init(GStudyProject *project)
{
- g_mutex_init(&project->mutex);
+ g_mutex_init(&project->cnt_mutex);
+
+ g_mutex_init(&project->bin_mutex);
}
@@ -180,11 +243,17 @@ GStudyProject *g_study_project_open(GObject *ref, const char *filename)
GStudyProject *result; /* Adresse à retourner */
xmlDocPtr xdoc; /* Structure XML chargée */
xmlXPathContextPtr context; /* Contexte pour les XPath */
+ unsigned int root_contents; /* Quantité de contenus majeurs*/
+ GAsyncQueue *sema; /* Sémaphore taisant son nom */
xmlXPathObjectPtr xobject; /* Cible d'une recherche */
unsigned int i; /* Boucle de parcours */
size_t access_len; /* Taille d'un chemin interne */
char *access; /* Chemin pour une sous-config.*/
- GLoadedBinary *binary; /* Représentation à intégrer */
+ GBinContent *content; /* Contenu binaire retrouvé */
+ long state; /* Etat de ce contenu binaire */
+ bool status; /* Bilan d'une lecture */
+ GDelayedStudy *dstudy; /* Etude complémentaire à mener*/
+ GLoadedBinary *binary; /* Représentation à intégrer */
if (!open_xml_file(filename, &xdoc, &context)) return NULL;
@@ -192,19 +261,78 @@ GStudyProject *g_study_project_open(GObject *ref, const char *filename)
result->filename = strdup(filename);
- /* Chargement des éléments binaires attachés */
+ /* Préparations aux traitements parallèles */
+
+ root_contents = 0;
+
+ sema = g_async_queue_new();
+
+ void ack_content_processing(GDelayedStudy *dstudy, GAsyncQueue *aqueue)
+ {
+ g_async_queue_push(aqueue, GINT_TO_POINTER(1));
+ }
+
+ /* Chargement des contenus binaires attachés */
+
+ xobject = get_node_xpath_object(context, "/ChrysalideProject/Contents/Content");
+
+ for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
+ {
+ access_len = strlen("/ChrysalideProject/Contents/Content[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
+
+ access = calloc(access_len, sizeof(char));
+ snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%u]", i + 1);
+
+ content = g_binary_content_new_from_xml(context, access);
+ status = get_node_prop_long_value(context, access, "state", &state);
+
+ free(access);
+
+ if (!status)
+ {
+ log_variadic_message(LMT_PROCESS, _("bad state for content '%s' ; skipping..."),
+ g_binary_content_describe(content, true));
+ continue;
+ }
+
+ /* Le contenu peut être un conteneur ? */
+ if (state == PCS_ROOT)
+ {
+ dstudy = g_delayed_study_new(result, content, state);
+ g_signal_connect(dstudy, "work-completed", G_CALLBACK(ack_content_processing), sema);
+
+ g_delayed_study_preload_only(dstudy);
+
+ root_contents++;
+
+ study_new_content(dstudy);
+
+ }
+
+ }
+
+ if(xobject != NULL)
+ xmlXPathFreeObject(xobject);
+
+ /* Attente pour la réception de contenus supplémentaires éventuels */
+
+ for (i = 0; i < root_contents; i++)
+ g_async_queue_pop(sema);
+
+ g_async_queue_unref(sema);
- xobject = get_node_xpath_object(context, "/OpenIDAProject/Binaries/Binary");
+ /* Chargement des binaires analysés */
+
+ xobject = get_node_xpath_object(context, "/ChrysalideProject/Binaries/Binary");
for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
{
- access_len = strlen("/OpenIDAProject/Binaries/Binary[position()=")
- + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1;
+ access_len = strlen("/ChrysalideProject/Binaries/Binary[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
access = calloc(access_len, sizeof(char));
- snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%u]", i + 1);
+ snprintf(access, access_len, "/ChrysalideProject/Binaries/Binary[position()=%u]", i + 1);
- binary = g_loaded_binary_new_from_xml(context, access);
+ binary = g_loaded_binary_new_from_xml(context, access, result);
free(access);
@@ -254,17 +382,36 @@ bool g_study_project_save(GStudyProject *project, const char *filename)
result = create_new_xml_file(&xdoc, &context);
- result &= (ensure_node_exist(xdoc, context, "/OpenIDAProject") != NULL);
+ result &= (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL);
+
+ /* Enregistrement des contenus binaires attachés */
- /* Enregistrement des éléments binaires attachés */
+ for (i = 0; i < project->contents_count && result; i++)
+ {
+ if (!project->contents[i].state == PCS_INTERNAL) continue;
+
+ access_len = strlen("/ChrysalideProject/Contents/Content[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
+
+ access = calloc(access_len, sizeof(char));
+ snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%zu]", i + 1);
+
+ result = g_binary_content_save(project->contents[i].content, xdoc, context, access);
+
+ if (result)
+ result = add_long_attribute_to_node(xdoc, context, access, "state", project->contents[i].state);
+
+ free(access);
+
+ }
+
+ /* Enregistrement des binaires analysés */
for (i = 0; i < project->binaries_count && result; i++)
{
- access_len = strlen("/OpenIDAProject/Binaries/Binary[position()=")
- + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1;
+ access_len = strlen("/ChrysalideProject/Binaries/Binary[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
access = calloc(access_len, sizeof(char));
- snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%zu]", i + 1);
+ snprintf(access, access_len, "/ChrysalideProject/Binaries/Binary[position()=%zu]", i + 1);
result = g_loaded_binary_save(project->binaries[i]->binary, xdoc, context, access);
@@ -311,6 +458,88 @@ const char *g_study_project_get_filename(const GStudyProject *project)
/******************************************************************************
* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* content = contenu binaire à mémoriser pour le projet. *
+* state = état du contenu à conserver. *
+* *
+* Description : Assure l'intégration d'un contenu binaire dans un projet. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_add_binary_content(GStudyProject *project, GBinContent *content, ProjectContentState state)
+{
+ loaded_content *new; /* Nouveau contenu à définir */
+
+ g_mutex_lock(&project->cnt_mutex);
+
+ project->contents = (loaded_content *)realloc(project->contents,
+ ++project->contents_count * sizeof(loaded_content));
+
+ new = &project->contents[project->contents_count - 1];
+
+ g_object_ref(G_OBJECT(content));
+
+ new->content = content;
+ new->state = state;
+
+ g_mutex_unlock(&project->cnt_mutex);
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* hash = empreinte du contenu à retrouver. *
+* *
+* Description : Recherche un contenu binaire du projet selon son empreinte. *
+* *
+* Retour : Contenu avec propriété transférée ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project, const char *hash)
+{
+ GBinContent *result; /* Trouvaille à retourner */
+ size_t i; /* Boucle de parcours */
+ GBinContent *iter; /* Contenu binaire analysé */
+ const gchar *other; /* Autre empreinte à comparer */
+
+ result = NULL;
+
+ g_mutex_lock(&project->cnt_mutex);
+
+ for (i = 0; i < project->contents_count && result == NULL; i++)
+ {
+ iter = project->contents[i].content;
+ other = g_binary_content_get_cheksum(iter);
+
+ if (strcmp(hash, other) == 0)
+ {
+ g_object_ref(G_OBJECT(iter));
+ result = iter;
+ }
+
+ }
+
+ g_mutex_unlock(&project->cnt_mutex);
+
+ return result;
+
+}
+
+
+
+
+/******************************************************************************
+* *
* Paramètres : binary = élément binaire tout juste désassemblé. *
* project = projet dont le contenu est à compléter. *
* *
@@ -431,7 +660,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
/* Enregistrement dans le projet */
- g_mutex_lock(&project->mutex);
+ g_mutex_lock(&project->bin_mutex);
project->binaries = (loaded_binary **)realloc(project->binaries,
++project->binaries_count * sizeof(loaded_binary *));
@@ -440,7 +669,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
project->binaries[result] = loaded;
- g_mutex_unlock(&project->mutex);
+ g_mutex_unlock(&project->bin_mutex);
update_project_area(project);
@@ -714,3 +943,272 @@ void push_project_into_recent_list(const GStudyProject *project)
g_generic_config_set_value(get_main_configuration(), MPK_LAST_PROJECT, project->filename);
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* AMORCE POUR CHARGEMENT DE CONTENUS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de préparations d'étude. */
+G_DEFINE_TYPE(GDelayedStudy, g_delayed_study, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des intégrations de binaires à étudier. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_class_init(GDelayedStudyClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_delayed_study_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_delayed_study_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dstudy = instance à initialiser. *
+* *
+* Description : Initialise une intégration de binaire à étudier. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_init(GDelayedStudy *dstudy)
+{
+ G_DELAYED_WORK(dstudy)->run = (run_task_fc)g_delayed_study_process;
+
+ dstudy->only_preload = false;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_dispose(GDelayedStudy *dstudy)
+{
+ g_object_unref(G_OBJECT(dstudy->project));
+ g_object_unref(G_OBJECT(dstudy->content));
+
+ G_OBJECT_CLASS(g_delayed_study_parent_class)->dispose(G_OBJECT(dstudy));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_finalize(GDelayedStudy *dstudy)
+{
+ G_OBJECT_CLASS(g_delayed_study_parent_class)->finalize(G_OBJECT(dstudy));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* content = contenu binaire chargé à analyser. *
+* state = état du contenu à conserver. *
+* *
+* Description : Crée une tâche d'intégration de contenu binaire. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : L'appelant perd la propriété du contenu. *
+* *
+******************************************************************************/
+
+GDelayedStudy *g_delayed_study_new(GStudyProject *project, GBinContent *content, ProjectContentState state)
+{
+ GDelayedStudy *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_DELAYED_STUDY, NULL);
+
+ g_object_ref(G_OBJECT(project));
+ result->project = project;
+
+ g_object_ref(G_OBJECT(content));
+ result->content = content;
+
+ result->state = state;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dstudy = intégration à mener. *
+* statusbar = barre de statut à tenir informée. *
+* *
+* Description : Prépare une intégration de binaire au projet courant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_delayed_study_process(GDelayedStudy *dstudy, GtkExtStatusBar *statusbar)
+{
+ FormatMatchStatus status; /* Statut d'une reconnaissance */
+ char *target; /* Sous-traitance requise */
+ GLoadedBinary *binary; /* Représentation chargée */
+
+ status = find_matching_format(dstudy->content, NULL, &target);
+
+ switch (status)
+ {
+ case FMS_MATCHED:
+
+ if (dstudy->only_preload)
+ g_study_project_add_binary_content(dstudy->project, dstudy->content, dstudy->state);
+
+ else
+ {
+ binary = g_loaded_binary_new(dstudy->content);
+
+ if (binary != NULL)
+ {
+ g_study_project_add_binary_content(dstudy->project, dstudy->content, dstudy->state);
+
+ g_signal_connect_to_main(binary, "disassembly-done",
+ G_CALLBACK(g_study_project_add_loaded_binary),
+ dstudy->project, g_cclosure_marshal_VOID__VOID);
+
+ g_loaded_binary_analyse(binary);
+
+ }
+
+ }
+
+ break;
+
+ case FMS_FORWARDED:
+ /**
+ * L'émetteur de ce type de réponse a pour charge de
+ * reprogrammer lui même l'analyse de nouveaux contenus.
+ */
+ log_variadic_message(LMT_PROCESS, _("binary '%s' contains other binaries..."),
+ g_binary_content_describe(dstudy->content, true));
+
+ if (dstudy->state == PCS_ROOT)
+ g_study_project_add_binary_content(dstudy->project, dstudy->content, PCS_ROOT);
+
+ break;
+
+ default:
+ /**
+ * Les jeux sont faits pour le contenu binaire courant.
+ */
+ log_variadic_message(LMT_PROCESS, _("Unknown binary format for '%s'..."),
+ g_binary_content_describe(dstudy->content, true));
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dstudy = tâche d'analyse de contenu pour projet à mener. *
+* *
+* Description : Limite l'étude et l'intégration d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_delayed_study_preload_only(GDelayedStudy *dstudy)
+{
+ dstudy->only_preload = true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire chargé à analyser. *
+* state = état du contenu à conserver. *
+* *
+* Description : Programme l'étude et l'intégration d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void qck_study_new_content(GBinContent *content, ProjectContentState state)
+{
+ GDelayedStudy *dstudy; /* Etude à conduire */
+
+ dstudy = g_delayed_study_new(get_current_project(), content, state);
+
+ study_new_content(dstudy);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire chargé à analyser. *
+* state = état du contenu à conserver. *
+* *
+* Description : Programme l'étude et l'intégration d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void study_new_content(GDelayedStudy *dstudy)
+{
+ GWorkQueue *queue; /* Gestionnaire de différés */
+
+ queue = get_work_queue();
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(dstudy));
+
+}
diff --git a/src/analysis/project.h b/src/analysis/project.h
index 05e7f12..5f5b38c 100644
--- a/src/analysis/project.h
+++ b/src/analysis/project.h
@@ -66,6 +66,23 @@ bool g_study_project_save(GStudyProject *, const char *);
/* Indique le chemin du fichier destiné à la sauvegarde. */
const char *g_study_project_get_filename(const GStudyProject *);
+/* Etat d'un contenu binaire du projet */
+typedef enum _ProjectContentState
+{
+ PCS_ROOT, /* Contenu principal */
+ PCS_INTERNAL, /* Contenu dérivé */
+ PCS_ATTACHED, /* Contenu complémentaire */
+
+ PCS_COUNT
+
+} ProjectContentState;
+
+/* Assure l'intégration d'un contenu binaire dans un projet. */
+void g_study_project_add_binary_content(GStudyProject *, GBinContent *, ProjectContentState);
+
+/* Recherche un contenu binaire du projet selon son empreinte. */
+GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *, const char *);
+
/* Assure l'intégration d'un élément binaire dans un projet. */
void g_study_project_add_loaded_binary(GLoadedBinary *, GStudyProject *);
@@ -103,4 +120,39 @@ void push_project_into_recent_list(const GStudyProject *);
+/* ----------------------- AMORCE POUR CHARGEMENT DE CONTENUS ----------------------- */
+
+
+#define G_TYPE_DELAYED_STUDY g_delayed_study_get_type()
+#define G_DELAYED_STUDY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_study_get_type(), GDelayedStudy))
+#define G_IS_DELAYED_STUDY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_study_get_type()))
+#define G_DELAYED_STUDY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_STUDY, GDelayedStudyClass))
+#define G_IS_DELAYED_STUDY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_STUDY))
+#define G_DELAYED_STUDY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_STUDY, GDelayedStudyClass))
+
+
+/* Ensembles binaires à désassembler (instance) */
+typedef struct _GDelayedStudy GDelayedStudy;
+
+/* Ensembles binaires à désassembler (classe) */
+typedef struct _GDelayedStudyClass GDelayedStudyClass;
+
+
+/* Indique le type défini pour les tâches de préparations d'étude. */
+GType g_delayed_study_get_type(void);
+
+/* Crée une tâche d'intégration de contenu binaire. */
+GDelayedStudy *g_delayed_study_new(GStudyProject *, GBinContent *, ProjectContentState);
+
+/* Limite l'étude et l'intégration d'un contenu binaire. */
+void g_delayed_study_preload_only(GDelayedStudy *);
+
+/* Programme l'étude et l'intégration d'un contenu binaire. */
+void qck_study_new_content(GBinContent *, ProjectContentState);
+
+/* Programme l'étude et l'intégration d'un contenu binaire. */
+void study_new_content(GDelayedStudy *);
+
+
+
#endif /* _PROJECT_H */