summaryrefslogtreecommitdiff
path: root/src/analysis/binary.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/binary.c')
-rw-r--r--src/analysis/binary.c307
1 files changed, 285 insertions, 22 deletions
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;
}