diff options
Diffstat (limited to 'src/analysis/binary.c')
-rw-r--r-- | src/analysis/binary.c | 307 |
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; } |